Opencart - Контактная Форма Без Перезагрузки Страницы

Тема в разделе "Модули и дополнения", создана пользователем admin, 21 окт 2016.

  1. TopicStarter Overlay
    Offline

    admin Команда форума Администратор

    Сообщения:
    2.327
    Симпатии:
    77.048
    Репутация:
    170
    Всем - привет. Сегодня решил взяться за переработку статьи об ajax форме, которая открывалась в модальном окне. Статья достаточно популярна, но имела некоторые проблемы. Дело в том, что после отправки данных, выводилось сообщение об успешной отправке и не позволяло больше отправлять письма до перезагрузки страницы. Многие из вас спрашивали, как сделать так, чтобы сообщение не заменяло форму и позволяло повторно отправлять письма. В этой статье мы это исправим и не только.

    Еще, у прошлой статьи был, наверное, недостаток в том, что сложно было подключить несколько форм, а именно, нужно было дублировать скрипт, обрабатывающий форму, что не очень красиво. В этой статье поправим и этот момент. Кроме того, форма будет работать и без модального окна.

    Ах да, приведу в порядок айдишники и классы, чтобы легче понималось что и зачем. Изменю дизайн формы, так интереснее. В одной из следующих статей, возможно, подключим к этой форме reCapthсa от Google, и настроем цель "Событие", при успешной отправке, так что готовится целый цикл статей.

    Как сделать форму обратной связи в модальном окне
    Давайте приступим. Так как модальное окно будет вызываться при помощи jQuery плагина Remodal, то перед закрывающимся тегом </body> подключим сам jQuery и плагин Remodal. Ниже добавим скрипт, который будет отвечать за отправку формы без перезагрузки страницы. Выглядит это следующим образом:

    Код:
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
    <script src="modalform/libs/remodal/remodal.min.js"></script>
    <script src="modalform/js/form.js"></script>
    Обратите внимание на путь к файлам. Я решил поместить практически все файлы в папку modalform, чтобы легче было подключать к проекту.

    Прежде чем перейти к разметке формы, подключим css файлы модального окна. Я делаю это между тегами head:

    Код:
    <link rel="stylesheet" href="modalform/libs/remodal/remodal.css">
    <link rel="stylesheet" href="modalform/libs/remodal/remodal-default-theme.css">
    <link rel="stylesheet" href="modalform/css/formstyle.css">
    Чтобы было интереснее:
    2016-10-21_120816.png 2016-10-21_120832.png 2016-10-21_120911.png

    Итак, теперь перейдем к разметке самой формы и кнопки вызывающей ее. Начнем с кнопки.

    Код:
    <a class="linkButton" data-remodal-target="firstModal">Оставить заявку</a>
    Тут - все просто. Обычная ссылка с произвольным классом. Data-remodal-target используется для того, чтобы вызвать модальное окно, аналогично, если бы использовался href со ссылкой на id. Но зачем нам этот мусор в адресной строке. В свою очередь модальное окно с формой выглядит следующим образом:

    Код:
    <div class="remodal" data-remodal-id="firstModal" data-remodal-options="hashTracking: false,closeOnConfirm: false">
    <button data-remodal-action="close" class="remodal-close"></button>
    <div class="formArea">
    <form id="firstForm" class="form" autocomplete="off">
    <p class="formTitle">Оставьте ваши контактные данные и наш консультант свяжется с вами</p>
    <p class="msgs"></p>
    <fieldset class="form-fieldset ui-input __first">
    <input name="uname" type="text" id="username" tabindex="0" />
    <label for="username">
    <span data-text="Введите ваше имя">Введите ваше имя</span>
    </label>
    </fieldset>
    
    <fieldset class="form-fieldset ui-input __second">
    <input name="uemail" type="email" id="email" tabindex="0" />
    <label for="email">
    <span data-text="Введите ваш e-mail">Введите ваш e-mail</span>
    </label>
    </fieldset>
    
    <input name="formInfo" class="formInfo" type="hidden" value="" />
    
    <div class="form-footer">
    <input type="submit" class="formBtn" value="Отправить заявку" />
    </div>
    <p class="formCreator"><a href="http://lowenet.biz">lowenet.biz</a></p>
    </form>
    </div>
    </div>
    Хоть кода, на первый взгляд, достаточно много, на самом деле все не так сложно. Вся форма обернута в div c классом remodal. У него есть data-remodal-id с таким же параметром как у кнопки. То есть firstForm. Именно благодаря им, при клике на кнопку открывается нужное окно, в случае, если на странице их несколько.

    Data-remodal-options - один из способов задать или отключить некоторые возможности скрипта для модального окна. Подробнее можно почитать на официальном из сайте. Ссылку уже давал выше. В моем случае. Я отключил появление якоря в адресной строке и запретил закрытие окно после нажатия кнопки "отправить".

    Внутри сама форма с fieldset(ами). Здесь важно обратить внимание, на параграф с классом "msgs". Именно сюда будет выводиться сообщение об успешной отправке или ошибке. Раньше сообщение выводилось прямо внутри формы, заменяя весь контент внутри.

    Еще один момент. Скрытое поле c классом formInfo. Оно нужно для того, чтобы отличать заявки и понимать какую именно форму заполнил пользователь, в случае, если их несколько разных. Просто заполняем нужным текстом значение value.

    В конце статьи, я покажу как сделать так, чтобы вызывать окно из разных мест на сайте и понимать, на какую именно кнопку нажал пользователь.

    Теперь давайте посмотрим на скрипт, который поможет нам отправить форму без перезагрузки страницы. Я назвал его form.js:

    Код:
    $(document).ready(function () {
    $("form").submit(function () {
    // Получение ID формы
    var formID = $(this).attr('id');
    
    // Добавление решётки к имени ID
    var formNm = $('#' + formID);
    $.ajax({
    type: "POST",
    url: '/modalform/mail.php',
    data: formNm.serialize(),
    success: function (data) {
    // Вывод сообщения об успешной отправке
    $('.msgs').html(data);
    $('.formTitle').css("display","none");
    setTimeout(function(){
    $('.formTitle').css("display","block");
    $('.msgs').html('');
    $('input').not(':input[type=submit], :input[type=hidden]').val('');
    }, 3000);
    },
    error: function (jqXHR, text, error) {
    // Вывод сообщения об ошибке отправки
    $('.msgs').html(error);
    $('.formTitle').css("display","none");
    setTimeout(function(){
    $('.formTitle').css("display","block");
    $('.msgs').html('');
    $('input').not(':input[type=submit], :input[type=hidden]').val('');
    }, 3000);
    }
    });
    return false;
    });
    //для стилей формы
    var $input = $('.form-fieldset > input');
    $input.blur(function (e) {
    $(this).toggleClass('filled', !!$(this).val());
    });
    });
    Давайте немного поясню, что тут происходит. Мы вызываем функцию, когда произошло событие submit у формы (нажали на отправку). Затем получаем id формы и сохраняем в переменную formNm. Теперь, id нашей формы в ней. В прошлой статье именно сюда выводилось сообщение. И именно об этом моменте я так часто писал в комментариях. Нужно просто указать другое место для вывода. В нашем случае мы все сообщения будем выводить в заранее подготовленное место. Это тег "p" с классом "msgs".

    В скрипте, говорим, что на время показа сообщения об успешной или не успешной отправке, скроем заголовок. А через 3 секунды вернем все на место и отчистим поля формы вместе с сообщением.

    Файл, который отправит полученные данные - mail.php. Вот его код:

    Код:
    <?php
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (!empty($_POST['uname']) && (!empty($_POST['uemail']) || !empty($_POST['uphone']))){
    if (isset($_POST['uname'])) {
    $uname = strip_tags($_POST['uname']);
    $unameFieldset = "<b>Имя пославшего:</b>";
    }
    if (isset($_POST['uemail'])) {
    $uemail = strip_tags($_POST['uemail']);
    $uemailFieldset = "<b>Почта:</b>";
    }
    if (isset($_POST['uphone'])) {
    $uphone = strip_tags($_POST['uphone']);
    $uphoneFieldset = "<b>Телефон:</b>";
    }
    if (isset($_POST['formInfo'])) {
    $formInfo = strip_tags($_POST['formInfo']);
    $formInfoFieldset = "<b>Тема:</b>";
    }
    
    $to = "admin@lowenet.biz"; /*Укажите адрес, на который должно приходить письмо*/
    $sendfrom = "admin@lowenet.biz"; /*Укажите адрес, с которого будет приходить письмо */
    $headers  = "From: " . strip_tags($sendfrom) . "\r\n";
    $headers .= "Reply-To: ". strip_tags($sendfrom) . "\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html;charset=utf-8 \r\n";
    $headers .= "Content-Transfer-Encoding: 8bit \r\n";
    $subject = "$formInfo";
    $message = "$unameFieldset $uname<br>
    $uemailFieldset $uemail<br>
    $uphoneFieldset $uphone<br>
    $formInfoFieldset $formInfo";
    
    $send = mail ($to, $subject, $message, $headers);
    if ($send == 'true') {
    echo '<p class="success">Спасибо за отправку вашего сообщения!</p>';
    } else {
    echo '<p class="fail"><b>Ошибка. Сообщение не отправлено!</b></p>';
    }
    } else {
    echo '<p class="fail">Ошибка. Вы заполнили не все обязательные поля!</p>';
    }
    } else {
    header ("Location: http://lowenet.biz"); // главная страница вашего лендинга
    }
    В нем несколько проверок:
    • Пришли ли данные методом POST, если да, то проверяем не пустые ли основные поля, если нет, то записываем в переменные и отправляем.
    • Если данные не пришли методом POST, то выкидываем на главную (то есть пользователь, каким-то образом попал сразу на страницу mail.php), а нам это не нужно, так как может отправиться пустое письмо.
    На этом первая часть закончена.

    Не забывайте указывать свои почтовые ящики. Кстати, на mail.ru письма могут не приходить с вашего ip. Ну и правильно, пользователи mail.ru и IE должны страдать.

    Теперь, давайте сделаем так, чтобы не приходилось заполнять параметр value у скрытого поля вручную, а он заполнялся автоматически. Это может понадобиться, когда у вас одна форма, но много кнопок на landing page, которые вызывают ее. Например, один раз вы берете контакты для бесплатной консультации, а где-нибудь ниже предлагаете услугу со скидкой. Чтобы понимать по какой именно кнопке нажали и чего ждет от вас пользователь, логично было бы в письме передавать информацию об этом. Я предлагаю кнопкам (ссылкам), по которым будет вызываться модальное окно дать title. Например, так:

    Код:
    <a class="linkButton" data-remodal-target="firstModal" title="Консультация">Получить консультацию</a>
    <a class="linkButton" data-remodal-target="secondModal" title="Обратный звонок">Обратный звонок</a>
    И написать небольшой скрипт, который при клике на на нашу кнопку(ссылку) будет подставлять в скрытое поле информацию из title:

    Код:
    $(".linkButton").click(function() {
    $( "input[name*='formInfo']" ).val($(this).attr( "title" ));
    });
    То есть мы говорим, что при клике на элемент с классом linkButton, возьми текст из его title и помести в input с name параметром formInfo, где:
    • linkButton - класс нашей кнопки;
    • formInfo - значение name скрытого поля;
    Это очень удобно, когда лендинг сделан по типу интернет магазина и на нем несколько товаров. Чтобы не делать несколько форм, просто задаем title кнопке и легко узнаем, какой именно товар, тариф или услугу заказал пользователь.

    Если будет вылазить ошибка "not found", первым делом проверьте путь к mail.php в файле form.js
     

    Вложения:

    • contForm.zip
      Размер файла:
      525,7 КБ
      Просмотров:
      46
    Fitcher, Motik, dmitriy1986 и 26 другим нравится это.
  2. Offline

    alex124 Пользователь

    Сообщения:
    9
    Симпатии:
    2
    Репутация:
    0
    Спасибо!
     
  3. Offline

    ms-mike Пользователь

    Сообщения:
    5
    Симпатии:
    0
    Репутация:
    0
    Спасибо!
     
  4. Offline

    neos Пользователь

    Сообщения:
    2
    Симпатии:
    0
    Репутация:
    0
    Спасибо!
     
  5. Offline

    konkord1259 Пользователь

    Сообщения:
    13
    Симпатии:
    1
    Репутация:
    0
    Спасибо!
     
  6. Offline

    djnick Пользователь

    Сообщения:
    6
    Симпатии:
    0
    Репутация:
    0
    Спасибо
     
  7. Offline

    Dior Пользователь

    Сообщения:
    4
    Симпатии:
    0
    Репутация:
    0
    спасибо
     
  8. Offline

    darquan0 Пользователь

    Сообщения:
    1
    Симпатии:
    0
    Репутация:
    0
    Спасибо!
     
  9. Offline

    Григорий Пользователь

    Сообщения:
    15
    Симпатии:
    1
    Репутация:
    0
    Спасибо!
     
  10. Offline

    di-mas82 Пользователь

    Сообщения:
    3
    Симпатии:
    0
    Репутация:
    0
    Спасибо
     
  11. Offline

    Alex777888 Пользователь

    Сообщения:
    3
    Симпатии:
    0
    Репутация:
    0
    спасибо
     
  12. Offline

    Levon1 Пользователь

    Сообщения:
    16
    Симпатии:
    3
    Репутация:
    0
    Спасибо
     
  13. Offline

    lasker Пользователь

    Сообщения:
    5
    Симпатии:
    0
    Репутация:
    0
    спасибо
     
  14. Offline

    ukraintsef Пользователь

    Сообщения:
    14
    Симпатии:
    3
    Репутация:
    0
    Спасибо
     
  15. Offline

    ser-go Пользователь

    Сообщения:
    6
    Симпатии:
    1
    Репутация:
    0
    спасибо!
     
  16. Offline

    valex Пользователь

    Сообщения:
    18
    Симпатии:
    142
    Репутация:
    0
    Спасибо
     
  17. Offline

    Alexandr1995 Пользователь

    Сообщения:
    3
    Симпатии:
    0
    Репутация:
    0
    Спасибо!
     
  18. Offline

    9263438205 Пользователь

    Сообщения:
    3
    Симпатии:
    0
    Репутация:
    0
    Спасибо
     
  19. Offline

    seodimka Пользователь

    Сообщения:
    12
    Симпатии:
    0
    Репутация:
    0
    спасибо
     
  20. Offline

    serzh3005 Пользователь

    Сообщения:
    5
    Симпатии:
    0
    Репутация:
    0
    спасибо