Получить поля ввода формы с помощью jQuery?

У меня есть форма с множеством полей ввода.

Когда я улавливаю событие формы отправки с помощью jQuery, возможно ли получить все поля ввода этой формы в ассоциативный массив?

Хороший вопрос; на самом деле, мне кажется очень странным, что jQuery не имеет функции, которая делает именно это. Существуют функции для получения данных формы в двух разных форматах, но не самый удобный, знаете ли, для сценарии… (Может быть .val () должен возвращать такой массив, если вызывается в элементе формы?)

Luke Maurer 18.03.2011 03:19
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
431
1
664 021
26
Перейти к ответу Данный вопрос помечен как решенный

Ответы 26

Ассоциативный? Не обошлось и без некоторой работы, но вы можете использовать универсальные селекторы:

var items = new Array();

$('#form_id:input').each(function (el) {
    items[el.name] = el;
});

на самом деле, в ответе Лэнса ассоциативный массив остается неизменным для значений POST и занимает целую строку кода.

msumme 27.01.2010 06:35

почему элементы являются массивом? вы используете его как простой объект. Здесь нет необходимости в массиве

Jonathan Morales Vélez 13.03.2015 13:18

Оли из @ JonathanMoralesVélez (2008) больше не существует для комментариев. 2015 согласен с вами.

Oli 13.03.2015 13:39
Ответ принят как подходящий

$('#myForm').submit(function() {
    // get all the inputs into an array.
    var $inputs = $('#myForm :input');

    // not sure if you wanted this, but I thought I'd add it.
    // get an associative array of just the values.
    var values = {};
    $inputs.each(function() {
        values[this.name] = $(this).val();
    });

});

Благодаря совету Simon_Weaver вот еще один способ сделать это, используя serializeArray:

var values = {};
$.each($('#myForm').serializeArray(), function(i, field) {
    values[field.name] = field.value;
});

Обратите внимание, что этот фрагмент не будет работать с элементами <select multiple>.

Похоже, что новые поля формы HTML 5 не работает с serializeArray в jQuery версии 1.3. Это работает в версии 1.4+.

В более новых версиях jQuery ответ Simon_Weaver более надежен и проще.

MightyE 04.05.2010 01:27

@MightyE & @Simon_Weaver - вы правы, это более надежный метод, но он не делает именно то, что искал OP. serializeArray возвращает массив объектов со свойствами name и value. Лучшим решением может быть обработка вывода из serializeArray в любой требуемый формат.

nickf 04.05.2010 04:14

Ты прав, никф, формат данных теперь другой, когда я смотрю на него более внимательно. На самом деле, я удивлен, что для этого нет встроенной поддержки.

MightyE 05.05.2010 22:18

Я думаю, что serializeArray () делает именно то, что вы хотите, и это намного меньше кода.

slacy 19.03.2011 01:05

@slacy, как во втором примере в моем ответе?

nickf 19.03.2011 17:06

Способ Саймона не работает (с jquery.1.3.2), если тип ввода - «электронная почта». Я предполагаю, что другие новые типы html5 тоже не появляются. Я не тестировал новый jquery

John La Rooy 06.04.2011 07:25

@gnibbler - я только что тестировал это на jQuery 1.4.4 и 1.5.1, и он работает с обеими этими версиями.

nickf 06.04.2011 13:05

@nickf, полезно знать. Я подумал, что они будут включены на каком-то этапе

John La Rooy 06.04.2011 14:22

Что касается первого варианта, как насчет элементов <select>? Я попробовал var $inputs = $('#new-ticket :input, :select');, но это не сработало. Кто-нибудь знает, как это сделать, потому что я не думаю, что делаю это правильно.

Nathan 27.02.2012 07:03

@Nathan, вам следует использовать $("#new-ticket :input, #new-ticket :select") или даже лучше $(":input, :select", "#new-ticket")

nickf 27.02.2012 20:44

@nickf, могу я попросить вас взглянуть на вопрос jquery по другой теме здесь: stackoverflow.com/questions/13137404/…?

Istiaque Ahmed 31.10.2012 16:07

Ссылка HTML5 - это 403.

gsamaras 23.09.2015 21:09

почему вы используете $ input? Что это за синтаксис?

Kyborek 29.07.2016 12:22

@Kyborek: это не синтаксис, это соглашение, элементы dom помечены символом $, не знаю, откуда он взялся, но я делаю ставку на сообщество PHP, в них отсутствовал символ $ в переменных.

Drachenfels 07.10.2016 19:30

убедитесь, что у всех ваших входов есть имена, иначе это не сработает :)

bottlenecked 19.10.2016 19:32

$('#myform').serializeArray() - это все, что вам нужно, $.each... просто создает тот же объект JavaScript, который уже был создан serializeArray. (+1 @slacy)

ryanm 14.08.2017 20:59

Это решение работает только с тегами «input» html; не будет повторять, например, в текстовом поле или выбирать.

Steve Horvath 05.03.2020 06:17

$('#myForm').bind('submit', function () {
  var elements = this.elements;
});

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

Поздно к вечеринке по этому вопросу, но это еще проще:

$('#myForm').submit(function() {
    // Get all the forms elements and their values in one step
    var values = $(this).serialize();

});

Это действительно лучший ответ. Он даже сохраняет любое форматирование массива, которое может быть у вас для полей ввода. Я не думаю, что ответ nickf действительно сохранил бы ваши структуры данных в неприкосновенности, если бы он был сформирован, например, с помощью Zend_Form, где у вас были бы field [something] и field [something_else] в качестве имен входов ... по крайней мере семантически я не понимаю, как бы это было ...

msumme 27.01.2010 06:34

Согласно документации API jQuery, .serialize() (api.jquery.com/serialize) помещает все элементы формы в одну строку, готовую для добавления к URL-адресу в строке запроса, по сути имитируя запрос формы GET. Это не приведет к тому, что выполняет ответ nickf.

Christopher Parker 02.03.2010 21:22

Стоит знать: .serialize() также работает только с элементами формы. Таким образом, $('form select').serialize() будет сериализовать данные только для выборок.

antitoxic 01.06.2012 14:31

Вместо того, чтобы повторять $('#myForm'), используйте $ (this).

Jimothy 25.07.2014 23:21

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

Sam 29.04.2016 11:14

Плагин jquery.form может помочь с тем, что ищут другие, которые в конечном итоге ответят на этот вопрос. Я не уверен, делает ли он то, что вы хотите, или нет.

Также есть функция serializeArray.

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

$.extend($.expr[':'],{
    submitable: function(a){
        if ($(a).is(':checkbox:not(:checked)'))
        {
            return false;
        }
        else if ($(a).is(':input'))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
});

использование:

$('#form_id :submitable');

Я еще не тестировал его с несколькими полями выбора, но он работает для получения всех полей формы так, как это делает стандартная отправка.

Я использовал это при настройке параметров продукта на сайте OpenCart, чтобы включить флажки и текстовые поля, а также стандартный тип поля выбора.

Не забудьте о флажках и переключателях -

var inputs = $("#myForm :input");
var obj = $.map(inputs, function(n, i) {
  var o = {};
  if (n.type == "radio" || n.type == "checkbox")
    o[n.id] = $(n).attr("checked");
  else
    o[n.id] = $(n).val();
  return o;
});
return obj

У меня была такая же проблема, но я решил ее по-другому.

var arr = new Array();
$(':input').each(function() {
 arr.push($(this).val());
});
arr;

Он возвращает значение всех полей ввода. Вы можете изменить $(':input'), чтобы быть более конкретным.

То же решение, что и Nickf, но с учетом имен входных массивов например

<input type = "text" name = "array[]" />

values = {};
$("#something :input").each(function() {
  if (this.name.search(/\[\]/) > 0) //search for [] in name
  {
    if (typeof values[this.name] != "undefined") {
      values[this.name] = values[this.name].concat([$(this).val()])
    } else {
      values[this.name] = [$(this).val()];
    }
  } else {
    values[this.name] = $(this).val();
  }
});

Была аналогичная проблема с небольшим поворотом, и я подумал, что выкину это. У меня есть функция обратного вызова, которая получает форму, поэтому у меня уже был объект формы, и я не мог простых вариантов на $('form:input'). Вместо этого я придумал:

    var dataValues = {};
    form.find('input').each(
        function(unusedIndex, child) {
            dataValues[child.name] = child.value;
        });

Это похожая, но не идентичная ситуация, но я нашел эту ветку очень полезной и подумал, что добавлю ее в конец и надеюсь, что кто-то еще сочтет ее полезной.

serializeArray jQuery не включает отключенные поля, поэтому, если они вам тоже нужны, попробуйте:

var data = {};
$('form.my-form').find('input, textarea, select').each(function(i, field) {
    data[field.name] = field.value;
});

serialize () - лучший метод. @ Christopher Parker говорит, что anwser Никфа выполняет больше, однако он не принимает во внимание, что форма может содержать текстовое поле и выбирать меню. Гораздо лучше использовать serialize (), а затем манипулировать им по мере необходимости. Данные из serialize () можно использовать либо в сообщениях Ajax, либо в get, поэтому здесь нет никаких проблем.

Иногда я считаю, что получать по одному более полезно. Для этого есть следующее:

var input_name = "firstname";
var input = $("#form_id :input[name='"+input_name+"']"); 

Добавление [0].value к этому, то есть $(...)[0].value; дало мне значение ввода напрямую, спасибо!

Pau Coma Ramirez 13.09.2016 18:01

Если вам нужно получить несколько значений из входов, и вы используете [] для определения входов с несколькими значениями, вы можете использовать следующее:

$('#contentform').find('input, textarea, select').each(function(x, field) {
    if (field.name) {
        if (field.name.indexOf('[]')>0) {
            if (!$.isArray(data[field.name])) {
               data[field.name]=new Array();
            }
            data[field.name].push(field.value);
        } else {
            data[field.name]=field.value;
        }
    }                   
});

Надеюсь, это кому-то поможет. :)

// This html:
// <form id = "someCoolForm">
// <input type = "text" class = "form-control" name = "username" value = "...." />
// 
// <input type = "text" class = "form-control" name = "profile.first_name" value = "...." />
// <input type = "text" class = "form-control" name = "profile.last_name" value = "...." />
// 
// <input type = "text" class = "form-control" name = "emails[]" value = "..." />
// <input type = "text" class = "form-control" name = "emails[]" value = ".." />
// <input type = "text" class = "form-control" name = "emails[]" value = "." />
// </form>
// 
// With this js:
// 
// var form1 = parseForm($('#someCoolForm'));
// console.info(form1);
// 
// Will output something like:
// {
// username: "test2"
// emails:
//   0: "[email protected]"
//   1: "[email protected]"
// profile: Object
//   first_name: "..."
//   last_name: "..."
// }
// 
// So, function below:

var parseForm = function (form) {

    var formdata = form.serializeArray();

    var data = {};

    _.each(formdata, function (element) {

        var value = _.values(element);

        // Parsing field arrays.
        if (value[0].indexOf('[]') > 0) {
            var key = value[0].replace('[]', '');

            if (!data[key])
                data[key] = [];

            data[value[0].replace('[]', '')].push(value[1]);
        } else

        // Parsing nested objects.
        if (value[0].indexOf('.') > 0) {

            var parent = value[0].substring(0, value[0].indexOf("."));
            var child = value[0].substring(value[0].lastIndexOf(".") + 1);

            if (!data[parent])
                data[parent] = {};

            data[parent][child] = value[1];
        } else {
            data[value[0]] = value[1];
        }
    });

    return data;
};

http://api.jquery.com/serializearray/

$('#form').on('submit', function() {
    var data = $(this).serializeArray();
});

Это также можно сделать без jQuery, используя объект XMLHttpRequest Level 2 FormData.

http://www.w3.org/TR/2010/WD-XMLHttpRequest2-20100907/#the-formdata-interface

var data = new FormData([form])

Вот еще одно решение, таким образом вы можете получить все данные о форме и использовать их в вызове на стороне сервера или в чем-то еще.

$('.form').on('submit', function( e )){ 
   var form = $( this ), // this will resolve to the form submitted
       action = form.attr( 'action' ),
         type = form.attr( 'method' ),
         data = {};

     // Make sure you use the 'name' field on the inputs you want to grab. 
   form.find( '[name]' ).each( function( i , v ){
      var input = $( this ), // resolves to current input element.
          name = input.attr( 'name' ),
          value = input.val();
      data[name] = value;
   });

  // Code which makes use of 'data'.

 e.preventDefault();
}

Затем вы можете использовать это с вызовами ajax:

function sendRequest(action, type, data) {
       $.ajax({
            url: action,
           type: type,
           data: data
       })
       .done(function( returnedHtml ) {
           $( "#responseDiv" ).append( returnedHtml );
       })
       .fail(function() {
           $( "#responseDiv" ).append( "This failed" );
       });
}

Надеюсь, это будет полезно для любого из вас :)

Все ответы хороши, но если есть поле, которое вы хотели бы игнорировать в этой функции? Просто дайте полю свойство, например ignore_this:

<input type = "text" name = "some_name" ignore_this>

И в вашей функции сериализации:

if (!$(name).prop('ignorar')){
   do_your_thing;
}

Таким образом вы игнорируете некоторые поля.

Это больше комментарий, чем ответ, поскольку он не отвечает на исходный вопрос.

Wai Ha Lee 16.04.2016 22:39

Может потому, что у него уже есть масса ответов? Это дополнение к полученным им ответам.

Marcelo Rocha 25.04.2016 14:01

Я бы реализовал это с именем класса, например обязательным, если ввод должен быть заполнен. Тогда я могу проверить $('.mandatory'); и !$('.mandatory');

lharby 23.05.2017 12:47

Измените ignore_this на data-ignore-this = "true" вместо создания собственных атрибутов, которые не проверяют w3c

zanderwar 27.05.2019 05:24

Я использую этот код без каждого цикла:

$('.subscribe-form').submit(function(e){
    var arr=$(this).serializeArray();
    var values = {};
    for(i in arr){values[arr[i]['name']]=arr[i]['value']}
    console.info(values);
    return false;
});

Кажется странным, что никто не проголосовал за и не предложил краткого решения для получения данных списка. Вряд ли какие-либо формы будут одномерными объектами.

Обратной стороной этого решения, конечно же, является то, что к вашим одноэлементным объектам нужно будет обращаться по индексу [0]. Но, IMO, это намного лучше, чем использование одного из дюжин-линейных картографических решений.

var formData = $('#formId').serializeArray().reduce(function (obj, item) {
    if (obj[item.name] == null) {
        obj[item.name] = [];
    } 
    obj[item.name].push(item.value);
    return obj;
}, {});

Этот фрагмент кода будет работать вместо имени, электронная почта введите имя полей формы

$(document).ready(function(){
  $("#form_id").submit(function(event){
    event.preventDefault();
    var name = $("input[name='name']",this).val();
    var email = $("input[name='email']",this).val();
  });
});

Это мое любимое решение, вдохновленное ответами Лэнс Рашинг и Simon_Weaver.

$('#myForm').submit( function( event ) {
    var values = $(this).serializeArray();
    // In my case, I need to fetch these data before custom actions
    event.preventDefault();
});

Результатом является массив объектов, например.

[{name: "start-time", value: "11:01"}, {name: "end-time", value: "11:11"}]

Используя приведенный ниже код,

var inputs = {};
$.each(values, function(k, v){
    inputs[v.name]= v.value;
});

его окончательный результат будет

{"start-time":"11:01", "end-time":"11:01"}

Я надеюсь, что это будет полезным, а также самым простым.

 $("#form").submit(function (e) { 
    e.preventDefault();
    input_values =  $(this).serializeArray();
  });

Как ни странно, это не сработало в последней версии jquery 3.4.1.

relipse 14.02.2020 22:06

Попробуйте следующий код:

jQuery("#form").serializeArray().filter(obje => 
obje.value!='').map(aobj=>aobj.name+" = "+aobj.value).join("&")

Пожалуйста, объясните свой ответ

Ling Vu 17.02.2020 13:05

Для нескольких элементов выбора (<select multiple = "multiple">) я изменил решение от @Jason Norwood-Young, чтобы оно работало.

Ответ (как опубликовано) принимает только значение из первого выбранного элемента, а не все они. Он также не инициализировал и не возвращал data, первый из которых вызывал ошибку JavaScript.

Вот новая версия:

function _get_values(form) {
  let data = {};
  $(form).find('input, textarea, select').each(function(x, field) {
    if (field.name) {
      if (field.name.indexOf('[]') > 0) {
        if (!$.isArray(data[field.name])) {
          data[field.name] = new Array();
        }
        for (let i = 0; i < field.selectedOptions.length; i++) {
          data[field.name].push(field.selectedOptions[i].value);
        }

      } else {
        data[field.name] = field.value;
      }
    }

  });
  return data
}

Использование:

_get_values($('#form'))

Примечание. Вам просто нужно убедиться, что выбранный вами name имеет добавленный в конец [], например:

<select name = "favorite_colors[]" multiple = "multiple">
  <option value = "red">Red</option>
  <option value = "green">Green</option>
  <option value = "blue">Blue</option>
</select>

$("#form-id").submit(function (e) { 
  e.preventDefault();
  inputs = {};
  input_serialized =  $(this).serializeArray();
  input_serialized.forEach(field => {
    inputs[field.name] = field.value;
  })
  console.info(inputs)
});

Другие вопросы по теме