Ajax на практике.

Получение данных из формы.

В прошлой статье, мы разобрали основной механизм работы метода jQuery $.ajax(). Теперь не плохо бы рассмотреть случаи из реальной практики: каким способом и откуда можно получать данные для передачи ajax-запросом.

Получение данных из формы.

Есть несколько способов получить данные из полей формы:

  1. Выбирать каждое поле отдельно, получая его значение. Однако, это не очень удобно, когда полей много.
  2. Использовать метод serialize()
  3. Использовать метод serializeArray()

Остановимся на двух последних и не столько на том, как получать данные (тут всё просто), а на том, как их обрабатывать на стороне сервера. Возьмем, к примеру, такую форму:

HTML (файл index.html)

<form action="handler.php" method="post" id="my_form">
  <label for="fio">Ф.И.О:</label>
    <input type="text" name="fio" id="fio"><br>
  <label for="mail">Email:</label>
    <input type="text" name="mail" id="mail"><br>
  <label for="select">Пол:</label>
    <select name="gender" id="gender">
      <option value="1">Мужской</option>
      <option value="2">Женский</option>
    </select><br>
  <label>Получать письма:<br>
    <input type="radio" name="get_mail" value="1" id="get_mail_0" checked>Да</label><br>
  <label>
    <input type="radio" name="get_mail" value="0" id="get_mail_1">Нет</label><br>
  <input type="submit" id="submit" value="Отправить">
</form>

И напишем такой JS-код

jQuery (файл script.js)

$(function(){
  $('#my_form').on('submit', function(e){
    e.preventDefault();
    var $that = $(this),
        fData = $that.serialize(); // сериализируем данные
        // ИЛИ
        // fData = $that.serializeArray();
    $.ajax({
      url: $that.attr('action'), // путь к обработчику берем из атрибута action
      type: $that.attr('method'), // метод передачи - берем из атрибута method
      data: {form_data: fData},
      dataType: 'json',
      success: function(json){
        // В случае успешного завершения запроса...
        if(json){
          $that.replaceWith(json); // заменим форму данными, полученными в ответе.
        }
      }
    });
  });
});

Теперь напишем обработчик таким образом, чтоб наглядно увидеть разницу между методами serialize() и serializeArray()

PHP-обработчик (файл handler.php)

<?php
if(isset($_POST['form_data'])){
  $req = false; // изначально переменная для "ответа" - false
  parse_str($_POST['form_data'], $form_data); // разбираем строку запроса
  // Приведём полученную информацию в удобочитаемый вид
  ob_start();
  echo 'До обработки: ' . $_POST['form_data'];
  echo 'После обработки:';
  echo '<pre>';
  print_r($form_data);
  echo '</pre>';
  $req = ob_get_contents();
  ob_end_clean();
  echo json_encode($req); // вернем полученное в ответе
  exit;
}

Итак, если мы отправим данные с использованием метода serialize(), то после завершения запроса, вместо формы, мы увидит примерно такую картину:

До обработки: fio=%D0%9F%D1%83%D0%BF%D0%BA%D0%B8%D0%BD+%D0%92.%D0%92.&mail=mail%40piva.net&select=1&get_mail=1
После обработки:
Array (
  [fio] => Пупкин В.В.
  [mail] => mail@piva.net
  [gender] => 1
  [get_mail] => 1
)

Теперь мы видим в каком виде передаются данные (по сути, строкой) и как выглядят они же, после обработки функцией parse_str(): мы получили ассоциативный массив, где ключами являются имена полей (атрибут name), а значениями - соответствующие данные этих полей.

Проделаем то же самое, но уже с использованием метода serializeArray(), только слегка изменим обработчик. Теперь он должен выглядеть таким образом:

<?php
if(isset($_POST['form_data'])){
  $req = false; // изначально переменная для "ответа" - false
  // Приведём полученную информацию в удобочитаемый вид
  ob_start();
  echo '<pre>';
  print_r($_POST['form_data']);
  echo '</pre>';
  $req = ob_get_contents();
  ob_end_clean();
  echo json_encode($req); // вернем полученное в ответе
  exit;
}

В этом случае, мы уже увидим на экране следующее:

Array
(
  [0] => Array 
    (
      [name] => fio
      [value] => Пупкин В.В.
    )
  [1] => Array 
    (
      [name] => mail
      [value] => mail@piva.net
    )
  [2] => Array 
    (
      [name] => gender
      [value] => 1
    )
  [3] => Array 
    (
      [name] => get_mail
      [value] => 1
    )
)

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

Получение данных из атрибута data-*.

Итак, это был один из наиболее часто используемых способов получения и передачи данных методом AJAX-запроса. Но рассмотрим другой случай, когда формы нет, но нам нужно откуда-то брать данные для дальнейшей их обработки. К примеру, на странице товара, есть кнопка "Добавить в корзину", по нажатию на которую, мы должны получить какую-то минимальную информацию о продукте. Конечно же, можно сделать скрытые поля формы, где эту информацию и складировать, но есть и другой подход, а именно использование собственных настраиваемых атрибутов. Имя этого атрибута, начинается с префикса data- и должен имеет как минимум один прописной символ после дефиса. Например, data-id, data-mydata, data-ajax и т.д. Вот его-то и возьмем на вооружение, тем более, что в jQuery предусмотрен метод для работы с этим атрибутом - .data().
Сделаем кнопку "Добавить в корзину", содержащюю в атрибуте data-* такие данные, как ID товара, его название и цену. Разделим эти данные запятой (можно использовать другой подходящий разделитель):

<button class="add_to_cart" data-product="22,Процессор,300$">Добавить в корзину</button>

И напишем следующий JS-код:

$('.add_to_cart').on('click', function(){ // по клику на кнопку,
  // получаем данные её атрибута data-product
  var prodData = $(this).data('product'); // "22,Процессор,300$"
  // если нужно, то можно эти данные разобрать на клиенте, поместив их в массив
  var prodDataArray = prodData.split(','); // ["22","Процессор","300$"]
  // или сразу одной строкой кода:
  var prodDataArray = $(this).data('product').split(','); // ["22","Процессор","300$"]
});

Таким не сложным способом, без лишних "телодвижений", мы получили о товаре данные, которые можем использовать дальше: передать AJAX-запросом на сервер, записать в cookie или Local Storage и т.д. Конечно же мы не сбрасываем со счетов и обычные методы для получения данных: текстовое содержание элементов, их другие атрибуты и прочее, но с этим, я надеюсь, что сложностей возникнуть не должно ;)


В следующей части, коснёмся одной из наиболее животрепещущей темы среди новичков: загрузка файлов с помощью AJAX.

Incode Pro logo

33 комментария

Страница 1 из 2  
Incode 03.11.2015 07:24
форма и обработчик на одном файле
@client500, Это же очевидно - на этот же файл указать url. Только обработка данных должна быть в начале файла.
itsivanov 29.01.2016 13:15
Как передачу данных средствами Ajax реализовать в одном файле? п.с. нужно)
itsivanov 29.01.2016 13:46
Это же очевидно - на этот же файл указать url. Только обработка данных должна быть в начале файла.

Не отрабатывает


<?php
if(isset($_POST['b1'])) {
  echo $_POST['b1'];
}
?>
<script>
src="http://code.jquery.com/jquery-latest.js";
function getdetails(){
	
	var box = $('#box').val();
	
	$.ajax({
		type: "POST",
		url: "index.php",
		data: {b1:box}
	}).done(function( result )
		{
			$("#result").html(result);
		});
} 
</script>
	
	<form method="post" enctype="multipart/form-data">
	<p>
	<textarea type="text "name="box" maxlength="140" id="box" style="width:100%;" ></textarea>
		<input type="submit" class="submit" value="SAVE THIS MESSAGE" onClick="getdetails()">
	</form>
<div  id="result"></div>
itsivanov 29.01.2016 13:59
P.S.
<script src="http://code.jquery.com/jquery-latest.js"></script>


и так тоже не отрабатывает.
Incode 29.01.2016 14:22
@itsivanov, У вас какая-то каша в коде. Смотрите полный код страницы:
Показать код

P.S. Страница должна быть в кодировке UTF-8 без BOM!
itsivanov 29.01.2016 14:27
@Incode, максимально сократил для показа. За ф-ю спасибо большое,не знал) Выручили!Буду чаще заходить к вам. классный блог!)
itsivanov 29.01.2016 14:31
@Incode, отрабатывает и просто с UTF-8
Гость 05.06.2016 14:42
Спасибо! Очень просто и ничего лишнего.
Гость 13.04.2017 22:44
Здравствуйте! Очень полезная и интересная статья!
Но я, кажется, нашла в Вашем html-файле ошибочку. Случайно проверила валидатором, и он сказал, что в строке label for="select" должно быть не select. Вероятно, там должно быть gender, так?
Гость 18.08.2017 23:09
5+ Спасибо!
spoon 14.06.2018 14:27
Второй день бьюсь не понимаю как сохранить данные из формы без перезагрузки, т.е. на странице index.php форма, с помощью ajax отправляем её данные на страницу form.php где они хранятся.
Что то типа корзины заказа.
Incode 14.06.2018 18:08
@spoon, Передать данные на сервер - это еще не значит, что они где-то сохраняются. Сохранять можно в обычных файлах, в базе данных, в cookie, сессии и т.д. В примере показано как передать, а где хранить - это уже дело каждого. К тому же, серверные языки тоже разные бывают. Если бы вы отправляли данные обычным способом (с перезагрузкой), вы бы удивлялись тому, что данные нигде не сохраняются, если вы это сами не предусмотрели? То же самое и с Ajax-запросом, т.к. принципиальной разницы между ними нет.
spoon 14.06.2018 18:31
Разве json_encode не должна вернуть в таком виде?
{"a":1,"b":2,"c":3,"d":4,"e":5}
spoon 14.06.2018 18:31
А в примере так
Array (
  [fio] => Пупкин В.В.
  [mail] => mail@piva.net
  [gender] => 1
  [get_mail] => 1
)
spoon 14.06.2018 18:39
Можно простенький пример с сохранением данных?
Задача такая: есть форма на странице form.php, где клиент выбирает чекбоксы и радио, потом нажимает на кнопку "Сохранить" но не переходит, а если нажмет на кнопку "Посмотреть заказ" то переходит на страницу zakaz.php где сохранились данные выбора формы.
spoon 14.06.2018 18:58
Ещё такой вопрос, в вашем коде
<?php
if(isset($_POST['form_data'])){
  $req = false;
  parse_str($_POST['form_data'], $form_data);
  ob_start();
  print_r($form_data);
  $req = ob_get_contents();
  ob_end_clean();
  echo json_encode($req); 
  exit;
}


$reg хранит массив json, как присвоить сессии эти данные? Типа этого

$_SESSION['a'] = Пупкин В.В.;
$_SESSION['b'] = mail@piva.net;
$_SESSION['c'] =1;
spoon 14.06.2018 18:59
Hf @Incode, рассмотрите функцию редактирования сообщения), а то бывает надо, а ни как).
Incode 14.06.2018 21:25
@spoon, рассмотреть я могу, а выделить на это время - нет.
Типа этого
Типа да. Как один из вариантов... Только перед выбором способа хранения, нужно четко знать особенности этого хранилища и понимать, в каких случаях и какое будет оптимальным.
spoon 15.06.2018 09:50
Как разобрать полученный массив по переменным?
т.е. из этого
Array (
  [fio] => Пупкин В.В.
  [mail] => mail@piva.net
  [gender] => 1
  [get_mail] => 1
)


получить это например

$car = 'Пупкин В.В.';
$dar = ' mail@piva.net';
и т.д.
spoon 15.06.2018 09:52
@Incode, при добавлении статьи ваш сайт периодически запрашивает регистрацию.
Incode 15.06.2018 14:00
@spoon, тяжело вам будет без базовых знаний PHP...
Как разобрать полученный массив по переменным?

$car = $_POST['form_data']['fio'];
$dar = $_POST['form_data']['mail'];
// и т.д.
Только полученные данные от клиента, нужно обязательно обрабатывать, фильтруя их и обезвреживая от потенциально вредоносных "вливаний".
spoon 15.06.2018 15:20
Этот код
$car = $_POST['form_data']['fio'];
$dar = $_POST['form_data']['mail'];

где прописывать? У меня не работает.

Сделал так index.php
<?php
$car = $_POST['form_data']['a'];
$dar = $_POST['form_data']['pro'];
echo $car, $dar;
?>  
<html lang="ru">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Тест</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
	<script type="text/javascript">
$(document).ready(function(){
    $('form').on('submit', function(e){
    e.preventDefault();
    var $that = $(this),
	fData = $that.serialize(); 
    $.ajax({
      url: 'a.php', 
      type: 'POST',
      data: {form_data: fData},
      dataType: 'json',
      success: function(json){  
          $('#f').html(json);
      }
    });
  });
});    
</script>
</head>
<body>
<div>
<form>
<input type="radio" id="radio1"   name="pro" value="да"/> &nbsp;<label for="vide_a" name="vide_a"> Radio 1</label><br>
<input type="radio" id="radio2"   name="pro" value="нет" /> &nbsp;<label  for="vide_b" name="vide_b"> Radio 2</label><br>
<input type="radio" id="radio3"   name="pro" value="тот"/> &nbsp;<label  for="vide_c" name="vide_c"> Radio 3</label><br>
<input id="svet_a" name="a" type="checkbox" value="но">
<input id="svet_b" name="b" type="checkbox" value="на">
<button type="submit">Отправить заявку</button>
</form>
<p id="f"></P>
</div>
</body>
</html>


и обработчик a.php
if(isset($_POST['form_data'])){
  $req = false; 
  parse_str($_POST['form_data'], $form_data); 
  ob_start();
  print_r($form_data);
  $req = ob_get_contents();
  ob_end_clean();
  echo json_encode($req); 
  exit;
}
Incode 15.06.2018 15:53
@spoon
и обработчик a.php
Именно тут
spoon 16.06.2018 10:03
сделал по другому
a.php-обработчик
<?php
if(isset($_POST['form_data'])){
	$req = $_POST['form_data'];
	parse_str($req);
	echo $pro.'<br>';
        echo $a.'<br>';
        echo $b.'<br>';
}
?>


index.php
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Тест</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
	<script type="text/javascript">
$(document).ready(function(){
    $('form').on('submit', function(e){
    e.preventDefault();
    var $that = $(this),
	fData = $that.serialize();
    $.ajax({
      url: 'a.php', 
      type: 'POST', 
      data: {form_data: fData},
      success: function(json){   
      $('#f').html(json); 
      }
    });
  });
});    
</script>
</head>
<body>
<div>
<form>
<input type="radio" id="radio1"   name="pro" value="да"/> &nbsp;<label for="vide_a" name="vide_a"> Radio 1</label><br>
<input type="radio" id="radio2"   name="pro" value="нет" /> &nbsp;<label  for="vide_b" name="vide_b"> Radio 2</label><br>
<input type="radio" id="radio3"   name="pro" value="тот"/> &nbsp;<label  for="vide_c" name="vide_c"> Radio 3</label><br>
<input id="svet_a" name="a" type="checkbox" value="но">
<input id="svet_b" name="b" type="checkbox" value="на">
<button type="submit">Отправить заявку</button>
</form>
<p id="f"></P>
</div>
</body>
</html>

Чисто для понимания процесса)), всё работает. Понятное дело что защиты ни какой, но повторюсь для понимания что к чему.
Гость 16.09.2022 17:29
А как в качестве базы подключить гугле таблицы?
Спасибо!
Страница 1 из 2  
Ваш комментарий:
X