Сейчас люди частенько юзают сервис google forms для любых форм на сайте. Поэтому часто возникает вопрос о встраивании Google формы на сайт, её стилизации и обработки ошибок в стиле сайта, поэтому мы разберем все это дело в текущей статье.
Зачем вообще использовать сервис гугл форм:
- Формы создавать просто и быстро;
- Результаты форм сразу сохраняются в таблице на облачном гугл диске;
- Уведомление на email о заполнении вам так же приходит;
- Это бесплатно.
Теперь к делу:
Создание формы:
Итак едем вот сюда жмем на всякие кнопки — создаем форму с нужными полями, там поддерживаются всякие разные типы полей. Я взял несколько стандартных типов полей и получилась вот такая форма.
Теперь будем втыкать форму на сайт.
Способ 1: iframe
Гугл предложит нам самый простой и быстрый способ встраивания — через iframe. Так что просто втыкаем айфрейм на страницу.
1 |
<iframe src="https://docs.google.com/forms/d/1xwGBCGQyvim9DY0Teuwlq5AtE7DJUCSogSwgGC-dwFA/viewform?embedded=true" width="760" height="500" frameborder="0" marginheight="0" marginwidth="0">Загрузка...</iframe> |
Конечно, он самый бичевский и отстилить его можно будет только хитрым способ через ж и вообще это айфрейм, но зато будет сразу встроенная валидация и вроде как защита от спама. xD
Способ 2: собственный html + jQuery + ajax
Инспектируем форму и достаем значения атрибутов name у полей и атрибут action у формы:
Создаем собственную форму и вставляем полям такие же атрибуты name как и у формы в айфрейме:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<form action="" id="gform-jquery"> <label>Поле 1 обычный инпут <input type="text" name="entry.1708534700" class="req"> </label> <label>Поле 2 текстарея <textarea name="entry.1715525179" class="req"></textarea> </label> <p>Поле 3 радиобаттон</p> <label><input type="radio" name="entry.750520923" value="Вариант 1">Вариант 1</label> <label><input type="radio" name="entry.750520923" value="Вариант 2">Вариант 2</label> <label><input type="radio" name="entry.750520923" value="Вариант 3">Вариант 3</label> <p>Поле 4 чекбоксы</p> <label><input type="checkbox" name="entry.1217837295" value="Вариант 1">Вариант 1</label> <label><input type="checkbox" name="entry.1217837295" value="Вариант 2">Вариант 2</label> <label><input type="checkbox" name="entry.1217837295" value="Вариант 3">Вариант 3</label> <label><input type="checkbox" name="entry.1217837295" value="Вариант 4">Вариант 4</label> <label>Поле 5 селектлист <select name="entry.1912015558"> <option value="Вариант 1">Вариант 1</option> <option value="Вариант 2">Вариант 2</option> <option value="Вариант 3">Вариант 3</option> </select> </label> <input type="hidden" name="entry.635644082" value="Собственный HTML+jQuery"> <button type="submit">Отправить</button> </form> |
Теперь отправим форму аяксом с помощью jQuery:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
$(document).ready(function(){ // после загрузки DOM $('#gform-jquery').submit(function(e){ // вешаем событие на отправку формы e.preventDefault(); // выключаем стандартное действие отправки var form = $(this); // запомним форму в переменной // добавим небольшую секцию проверки на заполненность var errors = false; // сначала ошибок нет form.find('.req').each(function(){ // пройдем по каждому полю с классом .req в форме $(this).removeClass('error'); // сначала уберем у него класс с ошибкой, на случай если он там есть if ($(this).val() == '') { // если оно пустое $(this).addClass('error'); // добавим к нему класс с ошибкой errors = true; // найдена ошибка } }); if (errors) return false; // если есть ошибка то больше ничего не делаем var data = form.serialize(); // сериализуем данные формы в строку для отправки, обратите внимание что атрибуты name у полей полностью сопдают с нэймами у полей самой гугл формы $.ajax({ // инициализируем аякс url: "https://docs.google.com/forms/d/1xwGBCGQyvim9DY0Teuwlq5AtE7DJUCSogSwgGC-dwFA/formResponse", // слать надо сюда, строку с буковками надо заменить на вашу, это атрибут action формы data: data, // данные которые мы сериализовали type: "POST", // постом dataType: "xml", // ответ ждем в формате xml beforeSend: function(){ // перед отправкой form.find('button').attr('disabled'); // отключим кнопку }, statusCode: { // после того как пришел ответ от сервера 0: function (){ // это успешный случай form.html('<h4>Спасибо!</h4><p>Форма отправлена блаблабла</p>'); // сунем в форму сообщение что все ок }, 200: function (){ // это тоже успешный случай form.html('<h4>Спасибо!</h4><p>Форма отправлена блаблабла</p>'); // сунем в форму сообщение что все ок } } }); }); }); |
Этот способ подойдет, если ничего важного в форме нет, и нет опасности что вас заспамят.
Способ 3: собственный html + jQuery + ajax + php
Теперь сделаем собственную форму, отправим её аяксом к нам на сервер, там все проверим и обработаем, и отправим в гугл уже на стороне сервера.
Делаем форму, нэймы полей уже не важны, присвоим нужные нэймы потом в php обработчике.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<form action="" id="gform-jquery-php"> <label>Поле 1 обычный инпут <input type="text" name="field1"> </label> <label>Поле 2 текстарея <textarea name="field2"></textarea> </label> <p>Поле 3 радиобаттон</p> <label><input type="radio" name="field3" value="Вариант 1">Вариант 1</label> <label><input type="radio" name="field3" value="Вариант 2">Вариант 2</label> <label><input type="radio" name="field3" value="Вариант 3">Вариант 3</label> <p>Поле 4 чекбоксы</p> <label><input type="checkbox" name="field4[]" value="Вариант 1">Вариант 1</label> <!-- если используем чекбоксы или другие элементы с несколькими вариантами надо подставить [] к нэйму чтобы пришел массив --> <label><input type="checkbox" name="field4[]" value="Вариант 2">Вариант 2</label> <label><input type="checkbox" name="field4[]" value="Вариант 3">Вариант 3</label> <label><input type="checkbox" name="field4[]" value="Вариант 4">Вариант 4</label> <label>Поле 5 селектлист <select name="field5"> <option value="Вариант 1">Вариант 1</option> <option value="Вариант 2">Вариант 2</option> <option value="Вариант 3">Вариант 3</option> </select> </label> <button type="submit">Отправить</button> </form> |
Вешаем на неё событие:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$(document).ready(function(){ // после загрузки DOM $('#gform-jquery-php').submit(function(e){ // вешаем событие на отправку формы e.preventDefault(); // выключаем стандартное действие отправки var form = $(this); // запомним форму в переменной var data = form.serialize(); // сериализуем данные формы в строку для отправки $.ajax({ // инициализируем аякс url: "send-g-form.php", // путь до нашего php обработчика, в моем случае он лежит в той же папке что и форма data: data, // данные которые мы сериализовали type: "POST", // постом dataType: "json", // ответ ждем в формате json beforeSend: function(){ // перед отправкой form.find('button').attr('disabled', true); // отключим кнопку }, success: function(data) { // соединение прошло и получен ответ от обработчика // внутри data будет объект, все его ключи и значения повторяют массив который мы вернули php обработчиком в json строке, помимо ok и message можно сувать туда всякие другие вещи if (data.ok) { // если ok != 0 то значит ошибок нет form.remove(); // выпилим форму } $('#response').html(data.message); // и покажем сообщение от сервера }, error: function(xhr, ajaxOptions, thrownError) { // если ошибка console.log(arguments); // убрать после дебага }, complete: function() { // в конце любого исхода form.find('button').prop('disabled', false); // снова включим кнопку } }); }); }); |
И пишем php-обработку под это дело:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<?php if (!$_POST) die('приветик'); // если глобальный массив POST не передан значит приветик // иначе продолжаем $response = array(); // сюда будем писать то что будем возвращать скрипту $field1 = isset($_POST['field1']) ? $_POST['field1'] : false; // сунем каждое поле в отдельную переменную $field2 = isset($_POST['field2']) ? $_POST['field2'] : false; $field3 = isset($_POST['field3']) ? $_POST['field3'] : false; $field4 = isset($_POST['field4']) ? $_POST['field4'] : false; $field5 = isset($_POST['field5']) ? $_POST['field5'] : false; $field6 = isset($_POST['field6']) ? $_POST['field6'] : false; // сюда можно положить всякие проверки полей и капчу например if (!$field1 || !$field2) { // в моем случае надо чтобы первые 2 поля не были пустыми $response['ok'] = 0; // пишем что все плохо $response['message'] = '<p class="error">Не заполнены первые два поля. Их всего два, ну ты чо? =)</p>'; // пишем ответ die(json_encode($response)); //выводим массив в json формате и умираем } // теперь подготовим данные для отправки в гугл форму $url = 'https://docs.google.com/forms/d/1xwGBCGQyvim9DY0Teuwlq5AtE7DJUCSogSwgGC-dwFA/formResponse'; // куда слать, это атрибут action у гугл формы $data = array(); // массив для отправки в гугл форм $data['entry.1708534700'] = $field1; // указываем соответствия полей, ключи массива это нэймы оригинальных полей гуглформы $data['entry.1715525179'] = $field2; $data['entry.750520923'] = $field3; $data['entry.1217837295'] = $field4; $data['entry.1912015558'] = $field5; $data['entry.635644082'] = 'Собственный HTML+jQuery+PHP'; // это наше скрытое поле $data = http_build_query($data); // теперь сериализуем массив данных в строку для отправки foreach ($field4 as $key => $value) { // если у нас есть элементы с нескольки значениями (например чекбоксы), надо пройтись по каждому и заменить кое что в отправляемой строке $data = str_replace('entry.1217837295%5B'.$key.'%5D', 'entry.1217837295', $data); // а именно выпилить [0], [1], [2].. из ключей, иначе в гугл форму это поле с несколькими значениями не запишется } $options = array( // задаем параметры запроса 'http' => array( 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => $data, ), ); $context = stream_context_create($options); // создаем контекст отправки $result = file_get_contents($url, false, $context); // отправляем if (!$result) { // если что-то не так $response['ok'] = 0; // пишем что все плохо $response['message'] = '<p class="error">Что-то пошло не так, попробуйте отправить позже.</p>'; // пишем ответ die(json_encode($response)); //выводим массив в json формате и умираем } $response['ok'] = 1; // если дошло до сюда, значит все ок $response['message'] = '<p class="">Все ок, отправилось.</p>'; // пишем ответ die(json_encode($response)); //выводим массив в json формате и умираем ?> |
Этот способ хорош тем, что мы можем делать с данными все что угодно перед отправкой, проверить их защищено на стороне сервера, поставить всякие капчи и пользователь не узнает про существование гугл формы.