Показать сообщение отдельно
  #12 (permalink)  
Старый 10.11.2020, 08:00
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,990

На клиенте:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
.container {
    width: 30%;
    margin: 0 auto;
}

.container h3:before {
    content: attr(data-quest);
}

.container.send h3:before {
    content: attr(data-send);
}

.container.done h3:before {
    content: attr(data-done);
}

.container.error h3:before {
    content: attr(data-error);
    color: #f00;
}

.container .next {
    visibility: hidden;
}

.container:not(.send) .next {
    visibility: visible;
}

form {
    position: relative;
}

form * {
    box-sizing: border-box;
}

input, select, textarea {
    width: 100%;
}

textarea {
    resize: vertical; 
    height: 130px; 
}

/*цвет списка не выбранного*/
select:invalid {
    color: #767676; 
}
/*но только не его доступных опций*/
select:invalid option:not(:disabled) {
    color: #000;
}

.overlap {
    display: none;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding: 30px;
    background-color: rgba(1, 34, 77, 0.93);
    z-index: 5;
}

.container.send .overlap,
.container.done .overlap,
.container.error .overlap {
    display: block;
}

.overlap ul {
    padding: 0;
    margin-top: 20px;
}

.overlap li {
    list-style: none;
    font-size: 18px;
    color: #fff;
}

.progress {
  display: none;
  justify-content: center;
  align-items: center;
  height: 100%;
  overflow: hidden;
}

.container.send .progress {
  display: flex;  
}

.circle {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  margin: 7px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.circle:before {
  content: "";
  width: 20px;
  height: 20px;
  border-radius: 50%;
  opacity: 0.7;
  animation: scale 2s infinite cubic-bezier(0, 0, 0.49, 1.02);
}

.circle-1 {
  background-color: #49b8e5;
}
.circle-1:before {
  background-color: #49b8e5;
  animation-delay: 200ms;
}

.circle-2 {
  background-color: #1e98d4;
}
.circle-2:before {
  background-color: #1e98d4;
  animation-delay: 400ms;
}

.circle-3 {
  background-color: #2a92d0;
}
.circle-3:before {
  background-color: #2a92d0;
  animation-delay: 600ms;
}

.circle-4 {
  background-color: #3a88c8;
}
.circle-4:before {
  background-color: #3a88c8;
  animation-delay: 800ms;
}

.circle-5 {
  background-color: #507cbe;
}
.circle-5:before {
  background-color: #507cbe;
  animation-delay: 1000ms;
}

@keyframes scale {
  0% {
    transform: scale(1);
  }
  50%, 75% {
    transform: scale(2.5);
  }
  78%, 100% {
    opacity: 0;
  }
}
</style>
</head>
<body>

<div class="container">
<h3 data-quest="Задать вопрос" data-send="Отправление формы" data-done="Форма отправлена" data-error="Ошибки приема данных"></h3>

<form id="feedback" method="post" action="/feedback/mails_sender.php" enctype="multipart/form-data" autocomplete="off">
    <div class="comment">
                <fieldset>
                        <select name="sex" required="">
                            <option value="" selected="" disabled="">Выберите Ваш пол *</option>
                            <option value="1">Мужчина</option>
                            <option value="3">Женщина</option>
                        </select>
                </fieldset>
                <fieldset>
                        <input name="email" type="email" placeholder="Эл. @ почта *"  required="" />
                </fieldset>
                <fieldset>
                        <select name="worker" required="">
                            <option value="" selected="" disabled="">Выберите сотрудника *</option>
                            <option value="1">Сергей</option>
                            <option value="2">Иван</option>
                            <option value="a">Николай</option>
                            <option value="4">Антон</option>
                            <option value="5">Виктор</option>
                        </select>
                </fieldset>
                <fieldset>
                        <input name="subject" type="text" placeholder="Тема *"  required="" />
                </fieldset>
                <fieldset>
                        <textarea name="message" placeholder="Текст сообщения *" required=""></textarea>
                </fieldset>
                <fieldset>
                        <input type="file" name="file" />
                </fieldset>
    </div>
    
    <div class="buttons">
        <button type="submit" class="sub">Отправить</button>
        <button type="reset" class="sub">Очистить</button> 
    </div>
    
    <div class="overlap">
        <div class="progress">
            <div class="circle circle-1"></div>
            <div class="circle circle-2"></div>
            <div class="circle circle-3"></div>
            <div class="circle circle-4"></div>
            <div class="circle circle-5"></div>
        </div>
        <ul class="response"></ul>
        <button class="next" type="button">Продолжить</button>
    </div>    
</form>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> 
<script>
var frm = $("#feedback").submit(function(e) {
    e.preventDefault(); //отменяем действие по умолчанию
    
    var container = $('.container'), //контейнер
        data = new FormData; //данные для отправления
    
    //помещаем поля формы в data
    $.each(frm.serializeArray(), function() {
        data.append(this.name, this.value)
    });
    //если есть выбор файла, добавляем его в data
    if(this.file.value) data.append('file', this.file.files[0]);
    
    $.ajax({
            url: this.action,
            type: 'post',
            dataType: 'json',
            data: data,
            cache: false,
            contentType: false,
            processData: false,
            beforeSend: function() {
                container.addClass('send') //показываем прогресс
            },
            complete: function() {
                container.removeClass('send') //удаляем прогресс
            },
            success: function(resp) {
                //определяем вывод сообщения в заголовке
                container.addClass(resp.result); 
                //выводим результат отправления
                frm.find('ul.response').html('<li>' + resp.data.join('</li><li>') + '</li>')
            },
            error: function(xhr, opt, error) {
	           alert(error + "\n" + xhr.statusText + "\n" + xhr.responseText);
            }
    })
}).find('button.next').click(function() {
    //сбросить форму если нет ошибок
    if(!frm.parent().hasClass('error')) frm.find('[type="reset"]').click(); 
    //убираем перекрытие формы
    frm.parent().removeClass('done error').find('ul.response').empty() 
}).end();
</script>
</body>
</html>

На просторах интернета "крутилок" как собак ... здесь одна из них, если есть беспокойство о древних браузерах, тогда гифки.
Вывод действа в заголовок формы, который определяется его data атрибутами и текущим именем родительского контейнера. Остальное не требует пояснения, надеюсь, это простой минимум, которого вполне хватает для отправления, "жир наращивать", это уже по вкусу и потребностям.

Полям добавлен атрибут required поэтому будет нативная проверка браузером и пустая форма отправляется не будет.
Значения списков не могут быть Сергей, Петя ... это должны быть идентификаторы, которые сервер проверяет. Собственно и в список Пол вставлять в значения мужчина/женщина, это от лени.

Последний раз редактировалось laimas, 10.11.2020 в 15:15.
Ответить с цитированием