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

Александр Мальцев
Александр Мальцев
69K
14
Содержание:
  1. jQuery – Получения данных формы с помощью метода each
  2. jQuery - Сериализация формы
  3. Комментарии

Статья, в которой рассмотрим различные способы простого извлечения данных из HTML формы. А именно познакомимся с тем, как это сделать с помощью метода each, а также методов jQuery специально предназначенных для этого. Объект FormData в данной статье рассматривать не будем.

jQuery – Получения данных формы с помощью метода each

Работу по извлечению данных c элементов формы посредством метода each рассмотрим на примере.

// создадим пустой объект
var $data = {};
// переберём все элементы input, textarea и select формы с id="myForm "
$('#myForm').find ('input, textearea, select').each(function() {
  // добавим новое свойство к объекту $data
  // имя свойства – значение атрибута name элемента
  // значение свойства – значение свойство value элемента
  $data[this.name] = $(this).val();
});

В минимальном варианте данная последовательность действий состоит из создания пустого объекта JavaScript, перебора элементов формы с помощью метода each и добавления в созданный объект данных соответствующих значениям определённых атрибутов (name и value) элементов.

При необходимости, после получения данных формы можно добавить различные проверки. Это предотвратит отправку не валидных данных на сервер.

Для отправки данных на сервер (например, по технологии AJAX) можно использовать метод jQuery ajax.

// AJAX-запрос, который будет отправлен на сервер:
//   по адресу: process.php
//   методом POST
//   содержащий данные $data 
// success - это функция, которая будет вызвана после получения ответа от сервера
//   (сам ответ доступен посредством аргумента result)
$.ajax({
  url: 'process.php',
  type: 'post',
  data: $data,
  success: function(result) {
    // действия при получения ответа (result) от сервера
  }
});

jQuery - Сериализация формы

В jQuery для получения всех полей формы input, textarea и select можно использовать следующие методы:

  • serialize() - предназначен для сериализации данных формы в строку запроса.
    имяПоля1=значение1&имяПоля2=значение2...
  • serializeArray() - выполняет кодирование элементов формы в массив, состоящий из имен и значений.
    [
      { name : "имяПоля1",
        value : "значение1" },
      { name : "имяПоля2",
        value : "значение2" },
      ...
    ]

Методы jQuery serialize и serializeArray оличаются друг от друга только форматом вывода данных. Метод serialize обычно применяется в том случае, когда результат (данные формы) необходимо положить в строку HTTP запроса. Метод serializeArray наоборот, используется тогда, когда результат, который он предоставил, как правило, ещё необходимо обработать.

Например, рассмотрим, как можно перебрать массив, который вернул метод serializeArray, с помощью функции each:

// создание массива объектов из данных формы
var data = $('#myForm').serializeArray();
// переберём каждое значение массива и выведем его в формате имяЭлемента=значение в консоль
$.each(data,function(){
  console.log(this.name+'='+this.value);
});

Если же вы собираете данные для того чтобы их передать в метод библиотеки jQuery ajax, то в этом случае неважно, какой из этих методов использовать. Т.к. данный метод может принимать данные, закодированные как с помощью метода serialize, так и посредством serializeArray.

Для того чтобы элемент был сериализован методом serialize или serializeArray, он должен отвечать критериям "successful controls", указанным в спецификации HTML. Первое условие "successful controls" – это наличие у элемента атрибута name. Второе, если форма отправлена не с помощью кнопки submit, то она (имя и значение кнопки) не будет добавлена в возвращаемую методом строку или массив. Третье, значения из элементов checkboxes и radio кнопок (input с type "radio" или "checkbox") будут включены в набор только в том случае, если они установлены (отмечены). Четвёртое, элементы, которые отключены, обработаны не будут. Т.е. для того чтобы элемент был сериализован, он должен иметь false в качестве значение свойства disabled (другими словами, у элемента обязан отсутствовать атрибут disabled).

Внимание: Методы serialize и serializeArray не сериализуют данные из элементов, которые используются для выбора файлов.

Разберём пример, в котором в зависимости от нажатай кнопки в форме соберём данные с помощью метода serialize или serializeArray. Для отправки данных на сервер и получения от него ответа будем использовать функцию jQuery ajax. Ответ, который прийдёт с сервера вставим в элемент с идентиикатором form_result.

<!-- Элемент для вывода результата -->
<div id="form_result"></div>
<hr>
<!-- HTML-форма -->
<form id="orderCallBack" action="process.php">
  Ваше имя: <input type="text" name="name" value=""><br>
  Ваш телефон: <input type="text" name="phone" value=""><br>
  Ваше сообщение:<br> <textarea name="message"></textarea><br>
  <input type="submit" name="submit1" value="Заказать звонок" data-method="serialize"><br>
  <input type="submit" name="submit2" value="Заказать звонок" data-method="serializeArray">
</form>
<!-- Сценарий для обработки формы -->
<script>
$(function() {
  // при нажатию на кнопку с типом submit
  $('#orderCallBack input[type="submit"]').click(function(e) {
    // отменяем стандартное поведение браузера
    e.preventDefault();
    // переменная, которая будет содержать данные серилизации
    var $data;
    // в зависимости от того какую нажали кнопку, выполняем
    // серилизацию тем или иным способом
    if ($(this).attr('data-method') == 'serialize') {
      $data = $(this).parent('form').serialize();
    } else {
      $data = $(this).parent('form').serializeArray();
    }
    // для отправки данных будем использовать технологию ajax
    //   url - адрес скрипта, с помощью которого будем обрабатывать форму на сервере
    //   type - метод отправки запроса (POST)
    //   data - данные, которые необходимо передать серверу
    //   success - функция, которая будет вызвана, когда ответ прийдёт с сервера
    $.ajax({
      url: $(this).parent('form').attr('action'),
      type: 'post',
      data: $data,
      success: function(result) {
        $('#form_result').html(result);
      }
    })
  });
});
</script>

PHP код, обрабатывающий ajax запрос на сервере:

<?php
// переменная для сохранения результата
$data='';
// переберём массив $_POST
foreach ($_POST as $key => $value) {
  // добавим в переменную $data имя и значение ключа
  $data .= $key . ' = ' . $value . '
'; } // выведим результат echo $data; ?>

Вышеприведёный код просто формирует строку из данных формы на сервере, которая затем будет отправлена клиенту (браузеру).

Сериализация формы с помощью методов jQuery serialize и serializeArray
Сериализация формы с помощью методов jQuery serialize и serializeArray

Комментарии:

  1. Raimonds Ozolins
    01 июня 2021, 17:13
    Здравствуйте, Александр! Спасибо за вашу статью. Я новичок в программировании.
    Пожалуйста, укажите, что я делаю неверно? Необходимо получить данные из формы и отправить запрос в php.
    С сервера получаю ответ пустой массив. Есть понимание, что параметры из формы не передаются в php файл.
    Как разрешить не знаю.
    ссылка не .html и .js:


    php файл содержит следующий код:

    <?php

    ini_set('display_errors', 'On');
    error_reporting(E_ALL);

    $executionStartTime = microtime(true);

    $url='http://api.geonames.org/earthquakesJSON?formatted=true&north'. $_REQUEST['north']. '&south='. $_REQUEST['south']. '&east='. $_REQUEST['east']. '&west='. $_REQUEST['west']. '&username=raimondozolins';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_URL,$url);

    $result=curl_exec($ch);

    curl_close($ch);

    $decode = json_decode($result,true);

    $output['status']['code'] = «200»;
    $output['status']['name'] = «ok»;
    $output['status']['description'] = «success»;
    $output['status']['returnedIn'] = intval((microtime(true) — $executionStartTime) * 1000). " ms";
    $output['data'] = $decode['geonames'];

    header('Content-Type: application/json; charset=UTF-8');

    echo json_encode($output);

    ?>
    Спасибо.
    1. Raimonds Ozolins
      01 июня 2021, 18:42
      ссылка нa html и js по каким-то причинам не скопировалась.
      jsfiddle.net/RaimOzo/ad85yktn/10/
    2. daniilko0
      07 сентября 2018, 22:56
      Здравствуйте Александр. Пишу тестовую систему (викторину). Хочу понять как с помощью jquery получать данные чекбоксов и радиобаттонов и их уже обрабатывать. Помогите пожалуйста.
      1. Максим Хализов
        13 августа 2017, 00:32
        Шеф — спаси, надежда только на тебя!)
        Мне очень нужно выполнить такую задачу: человек видит поле ввода, вводит туда 8 цифр(не больше, не меньше) после чего жмет кнопку ОК, появляется счетчик, которые идет от 0 до 500 и добавляет по 25 единиц каждые 3 секунды. Интервалы, шаг, потолок нужно иметь возможность изменять в коде.
        На данный момент я смог сделать почти всё, но не могу остановить счетчик на 500!( и счетчик запускается даже если поле пустое, а должен запускаться только если в поле введено именно 8 и именно цифр.

        <form>
        <input type="text" minlength="8" maxlength="8"  required onkeyup="check();" id="onkeypress">
        <input type="submit" id="send" value="Отправить">
        <script>
        document.getElementsByTagName('input')[0].onkeypress = function(e) {
        e = e || event;
        if (e.ctrlKey || e.altKey || e.metaKey) return;
        var chr = getChar(e);
        if (chr == null) return;
        if (chr < '0' || chr > '9') {
        return false;
        }
        }
        function getChar(event) {
        if (event.which == null) {
        if (event.keyCode < 32) return null;
        return String.fromCharCode(event.keyCode)
        }
        if (event.which != 0 && event.charCode != 0) {
        if (event.which < 32) return null;
        return String.fromCharCode(event.which)
        }
        return null;
        }
        </script>
        <span class="textClient2" id="moneyClient5">0</span><span class="counter"> рублей</span>
        <script>
        $(document).ready(function() {
        $("#send").click(function(){
                
        var updateTimer = function() {
        var moneyClient5 = document.getElementById('moneyClient5');
        var count3 = Number(moneyClient5.innerHTML);
        moneyClient5.innerHTML = count3 += 24;
        };
        setInterval(updateTimer, 1000);
        })
        })
        </script>
        </form>
        
        1. Александр Мальцев
          13 августа 2017, 12:42
          Можно сделать так:
          <form id="myform">
              <input type="text" minlength="8" maxlength="8" id="onkeypress" required="required"/>
              <input type="submit" value="Отправить" disabled="disabled"/>
              <span class="textClient2" id="moneyClient5">0</span><span class="counter"> рублей</span>
          </form>
          
          <script>
              $(function () {
                  $('#onkeypress').on('input', function (e) {
                      $(this).val($(this).val().replace(/[^0-9]/g, ''));
                      console.log($(this).val().length);
                      if ($(this).val().length === 8) {
                          $(this).closest('form').find('[type="submit"]').prop('disabled', false);
                      } else {
                          $(this).closest('form').find('[type="submit"]').prop('disabled', true);
                      }
                  });
                  $('#myform').submit(function (e) {
                      e.preventDefault();
                      $('form').find('[type="submit"]').prop('disabled', true);
                      var start = 0;
                      var end = 500;
                      var step = 25;
                      var time = 3000;
                      var interval = window.setInterval(function () {
                          start += step;
                          $('#moneyClient5').text(start);
                          console.log(start + step > end);
                          if (start + step > end) {
                              clearInterval(interval);
                              $('#onkeypress').val('');
                              $('#moneyClient5').text('0');
                              $('#onkeypress').trigger('input');
                          }
                      }, time)
                  })
              });
          </script>
          
        2. Леонид
          09 апреля 2017, 17:42
          Здравствуйте Александр!
          Имеется список из чекбоксов:
          <input type="checkbox" value=".<?= $color_value_id; ?>" name="COLOR_CHANGER[]" data-color="<?= $color_value; ?>" id="<?= $color_value_id; ?>" class="check"/>
          <label for="<?= $color_value_id; ?>"><?= $color_value; ?><span></span></label>
          
          Как передать в запрос одновременно значения атрибутов name, value и data-color?
          var $data_color = $(document).find('#color_form').serializeArray();
          Так передает только name и value. Подскажите, как правильно сделать?
          З.Ы.
          data-* атрибут можно называть, как вздумается?
          1. Александр Мальцев
            10 апреля 2017, 14:41
            Здравствуйте, Леонид.
            Наиболее просто это выполнить с помощью формата JSON.
            Например (javascript):
            // получаем данные формы с id=color_form
            var data = $('#color_form').serializeArray();
            // перебираем все элементы формы, имеющие состояние checked и атрибут data-color  
            $('#color_form input:checked[data-color]').each(function(){
              /* сохраняем ключ и значение */
              var key = $(this).attr('name');
              var value = $(this).attr('value');  
              // составляем объект из свойств value и data-color элемента
              var valueObj = {
                'value': $(this).attr('value'),
                'data-color': $(this).attr('data-color')
              }
              // преобразуем объект в JSON
              var valueStr = JSON.stringify(valueObj);
              // заменяем в массиве data значение данного элемента на JSON
              $.each(data,function(){
                if (this.name == key && this.value == value ) {
                  this.value = valueStr;
                }
              });
            
            На сервере (php):
            // получаем значение color и декодируем её
            $color = json_decode($_POST['color']);
            // получаем значение value
            $value = $color->{'value'};
            // получаем значение data-color
            $dataColor = $color->{'data-color'};
            
            1. Леонид
              10 апреля 2017, 15:17
              Александр, вы очень умный программист! Спасибо вам огромное за вашу помощь! Вам необходимо добавить на сайт кнопочку для благодарности, для поддержания проекта так сказать! Вы очень мне помогли. Но в последнем случае я сделал немного иначе и все нужные мне поля передал через атрибут value. Предварительно собрав все нужное в строку, а на выводе все обратно разбил. Работает вроде)
              1. Леонид
                10 апреля 2017, 15:20
                Нашел кнопочку) Поблагодарил!
                1. Александр Мальцев
                  10 апреля 2017, 15:41
                  Спасибо!
          2. Леонид
            30 марта 2017, 16:05
            Решил сам таким способом
            $(this).find('#post_form').serialize();
            возможно не правильно, но буду рад вашей критике.
            1. Александр Мальцев
              30 марта 2017, 17:50
              Это оптимальный вариант. Только как вы их получает без атрибута name у элементов input?
              1. Леонид
                31 марта 2017, 07:28
                добавил name=«factory_name[]», все чудесно работает.
            2. Леонид
              30 марта 2017, 15:58
              Здравствуйте Александр! Подскажите пожалуйста, как передать данные из такой структуры. Как передать множественные свойства в запрос ajax с дальнейшей обработкой?
              <?
                              $arFilter = array('ACTIVE' => 'Y', 'ID' => $factory_res, 'GLOBAL_ACTIVE' => 'Y');
                              $arSelect = array('ID', 'NAME', 'DEPTH_LEVEL', 'SECTION_PAGE_URL', 'IBLOCK_SECTION_ID');
                              $arOrder = array('DEPTH_LEVEL' => 'ASC', 'SORT' => 'ASC');
              
                              $rsFactoryList = CIBlockSection::GetList($arOrder, $arFilter, false, $arSelect);
                              $sectionLinc = array();
                              $result['ROOT'] = array();
                              $sectionLinc[0] = &$result['ROOT'];
                              ?>
                              <?
                              while ($arSection = $rsFactoryList->GetNext(true, false)) {
                                  $sectionLinc[intval($arSection['IBLOCK_SECTION_ID'])]['CHILD'][$arSection['ID']] = $arSection;
                                  $sectionLinc[$arSection['ID']] = &$sectionLinc[intval($arSection['IBLOCK_SECTION_ID'])]['CHILD'][$arSection['ID']];
                                  ?>
                                  <input type="hidden" value="<?= $sectionLinc[$arSection['ID']]['NAME']; ?>" 
                                         id="data_factory_name_<?= $sectionLinc[$arSection['ID']]['ID']; ?>"/>
                                  <input type="hidden" value="<?= $sectionLinc[$arSection['ID']]['SECTION_PAGE_URL']; ?>" 
                                         id="data_factory_url_<?= $sectionLinc[$arSection['ID']]['ID']; ?>"/>
                                  <input type="hidden" value="<?= $sectionLinc[$arSection['ID']]['DEPTH_LEVEL']; ?>" 
                                         id="data_factory_level_<?= $sectionLinc[$arSection['ID']]['ID']; ?>"/>
                                  <?
                                     }
                                     unset($sectionLinc);
                                     ?>
              
              Из привязки к разделам забираю информацию «ИМЯ, ССЫЛКУ НА РАЗДЕЛ и УРОВЕНЬ ВЛОЖЕННОСТИ». Для каждого инпута присвоил id:
              id="data_factory_name_<?= $sectionLinc[$arSection['ID']]['ID']; ?>"
              Для того чтоб у каждого элемента была информация о том какие разделы привязаны. После загрузки страницы видим следующее.

              делаю запрос:
              $(document).ready(function () {
                          $(".grid-item").click(function () {
              
                              var data_id = $(this).find('#data_id').attr('value');
                              var data_name = $(this).find('#data_name').attr('value');
                              var data_picture = $(this).find('#data_picture').attr('value');
                              var data_color = $(this).find('#data_color').attr('value');
                              var data_structure = $(this).find('#data_structure').attr('value');
                              var data_factory_name = $(this).find('#data_factory_name_<?= $itemid; ?>').attr('value');
                              var data_factory_url = $(this).find('#data_factory_url_<?= $itemid; ?>').attr('value');
                              var data_factory_level = $(this).find('#data_factory_level_<?= $itemid; ?>').attr('value');
                  
                          $.ajax({
                                  type: 'get',
                                  url: 'ajax.php',
                                  data: {
                                      'data_id': data_id,
                                      'data_name': data_name,
                                      'data_picture': data_picture,
                                      'data_color': data_color,
                                      'data_structure': data_structure,
                                      'data_factory_name': data_factory_name,
                                      'data_factory_url': data_factory_url,
                                      'data_factory_dl': data_factory_level
                                  },
                                  response: 'text',
                                  success: function (data) {
                                      $('.modal-box').html(data);
                                  }
                              });
                          });
                      });
              
              Как передать данные которые обведены на картинке? Не могу разобраться. Буду очень благодарен вашей помощи, советам и критике!
              Войдите, пожалуйста, в аккаунт, чтобы оставить комментарий.