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

412

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

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

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

Ответы:

524
$('#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+

nickf
источник
1
В более новых версиях jQuery ответ Simon_Weaver является более надежным и простым.
MightyE
1
@MightyE & @Simon_Weaver - вы правы, это более надежный метод, но он не выполняет в точности то, что искал ОП. serializeArray возвращает массив объектов со свойствами nameи value. Лучшим решением может быть обработка вывода из serializeArray в любой требуемый формат.
Nickf
1
Я думаю, что serializeArray () делает именно то, что вы хотите, и гораздо меньше кода.
рабство
1
Для первого варианта, как насчет <select>элементов? Я пытался, var $inputs = $('#new-ticket :input, :select');но это не работает. Кто-нибудь знает правильный способ сделать это, потому что я не думаю, что я делаю это правильно.
Натан
2
@ Натан, ты должен использовать $("#new-ticket :input, #new-ticket :select"), или даже лучше,$(":input, :select", "#new-ticket")
nickf
252

Опоздал на вечеринку по этому вопросу, но это еще проще

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

});
Ланс Рашинг
источник
8
Это действительно лучший ответ. Он даже сохраняет любое форматирование массива для ваших полей ввода. Я не думаю, что ответ от nickf на самом деле сохранит ваши структуры данных нетронутыми, если он будет сформирован, например, с использованием Zend_Form, где у вас будет поле [нечто] и поле [нечто_ельсе] в качестве имен входных данных ... по крайней мере семантически, я не могу видеть, как это было бы ...
msumme
43
Согласно документации jQuery API, .serialize()( api.jquery.com/serialize ) помещает все элементы формы в одну строку, готовую для добавления к URL-адресу в строке запроса, по существу имитируя запрос формы GET. Это не будет достигать того, что дает ответ Никфа.
Кристофер Паркер
Это лучший ответ!
Даниэль Хантер
5
Стоит знать: .serialize()также работает только с элементами формы. Так $('form select').serialize()будет сериализовать данные только для избранных.
антитоксический
3
Вместо повторения $('#myForm')используйте $ (это).
Джимоти
23

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

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

Simon_Weaver
источник
15

Иногда я нахожу получение по одному более полезным. Для этого есть вот что:

var input_name = "firstname";
var input = $("#form_id :input[name='"+input_name+"']"); 
Малахия
источник
Присоединяясь [0].valueк этому, т.е. $(...)[0].value;дал мне значение ввода напрямую, спасибо!
Пау Кома Рамирес
12
$('#myForm').bind('submit', function () {
  var elements = this.elements;
});

Переменная elements будет содержать все входные данные, select, textareas и fieldsets внутри формы.

Quentin
источник
9

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

$('.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" );
       });
}

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

Оле олдрик
источник
5

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

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

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

Крис
источник
4

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

var items = new Array();

$('#form_id:input').each(function (el) {
    items[el.name] = el;
});
Oli
источник
на самом деле, ответ Ланса сохраняет ассоциативный массив неизменным для значений POST и занимает колоссальную строку кода.
26
почему элементы являются массивом? вы используете его как обычный объект. Там нет необходимости для массива здесь
Джонатан Моралес Велес
3
Oli @ JonathanMoralesVélez 2008 больше не собирается комментировать. 2015 с вами согласен.
Оли
4

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

var data = {};
$('form.my-form').find('input, textarea, select').each(function(i, field) {
    data[field.name] = field.value;
});
Сара Весселс
источник
4

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

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
Человек по имени Хейни
источник
3

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

$(document).ready(function(){
  $("#form_id").submit(function(event){
    event.preventDefault();
    var name = $("input[name='name']",this).val();
    var email = $("input[name='email']",this).val();
  });
});
редкий туркан
источник
3

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

Недостатком этого решения, конечно, является то, что ваши одноэлементные объекты должны быть доступны по индексу [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;
}, {});
Ryanman
источник
2

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

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

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

Suizo
источник
2

То же решение, что и для 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();
  }
});
Itako
источник
1

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

$('#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;
        }
    }                   
});
Джейсон Норвуд-Янг
источник
1

Это мое любимое решение, вдохновленное ответами Лэнса Рашинга и 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"}
T.Liu
источник
1

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

$('.subscribe-form').submit(function(e){
    var arr=$(this).serializeArray();
    var values={};
    for(i in arr){values[arr[i]['name']]=arr[i]['value']}
    console.log(values);
    return false;
});
Роман Гринев
источник
1

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

 $("#form").submit(function (e) { 
    e.preventDefault();
    input_values =  $(this).serializeArray();
  });
dipenparmar12
источник
Как ни странно, это не сработало в последней версии jquery 3.4.1
relipse
0

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

$.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, чтобы включить флажки и текстовые поля, а также стандартный тип блока выбора.

slarti42uk
источник
0

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

Билли
источник
0

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

// 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.log(form1);
// 
// Will output something like:
// {
// username: "test2"
// emails:
//   0: ".@....com"
//   1: "...@........com"
// 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;
};
юлианский
источник
0

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

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

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

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

Вот так вы игнорируете некоторые поля.

Марсело Роша
источник
1
Это скорее комментарий, чем ответ, так как он не отвечает на первоначальный вопрос.
Вай Ха Ли
Может быть, потому что у него уже есть тонны ответов? Это дополнение к ответам, которые он получил.
Марсело Роча,
Я бы реализовал это с помощью имени класса, такого как обязательное, если ввод должен быть заполнен. Тогда я могу проверить $('.mandatory');и!$('.mandatory');
lharby
Изменить , ignore_thisчтобы data-ignore-this="true"вместо того , чтобы создавать свои собственные атрибуты , которые не проверяют w
zanderwar
0

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

jQuery("#form").serializeArray().filter(obje => 
obje.value!='').map(aobj=>aobj.name+"="+aobj.value).join("&")
Теодор Рауту
источник
2
Пожалуйста, объясните свой ответ
Лин Ву
0

Для нескольких элементов select ( <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>
Тзасо
источник
-1
$("#form-id").submit(function (e) { 
  e.preventDefault();
  inputs={};
  input_serialized =  $(this).serializeArray();
  input_serialized.forEach(field => {
    inputs[field.name] = field.value;
  })
  console.log(inputs)
});
Раушан
источник