Отримати поля введення форми за допомогою 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+


1
У нових версіях jQuery відповідь Simon_Weaver є більш надійною та легшою.
Могутній

1
@MightyE & @Simon_Weaver - ти маєш рацію, це більш надійний метод, але він не робить саме те, що шукала ОП. serializeArray повертає масив об'єктів із властивостями nameта value. Кращим рішенням може бути обробка результатів з serializeArray в будь-який формат.
nickf

1
Я думаю, що serializeArray () робить саме те, що ви хочете, і набагато менше коду.
шибениця

1
Перший варіант, як щодо <select>елементів? Я спробував, var $inputs = $('#new-ticket :input, :select');але це не працює. Хтось знає правильний спосіб зробити це, тому що я не думаю, що я роблю це правильно.
Натан

2
@Nathan, ви повинні використовувати $("#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, де ви мали б поле [щось] та поле [something_else] як назви вхідних даних ... принаймні семантично я не бачу, як би це було ...
msumme

43
Згідно з документами API jQuery .serialize()( api.jquery.com/serialize ) розміщує всі елементи форми в єдиний рядок, готовий до додавання до URL у рядку запиту, по суті імітуючи запит форми GET. Це не дозволить досягти відповіді нікфа.
Крістофер Паркер

Це найкраща відповідь!
Даніель Хантер

5
Варто знати: .serialize()також працює на елементах просто форми. Так $('form select').serialize()буде серіалізувати дані лише для вибраних.
антитоксичний

3
Замість того, щоб повторювати $('#myForm'), використовуйте $ (це).
Джимотій

23

Jquery.form плагін може допомогти з тим, що інші шукають , що в кінцевому підсумку на це питання. Я не впевнений, чи це безпосередньо робить те, що ти хочеш чи ні.

Існує також функція serializeArray .


15

Іноді мені здається, що отримати один за одним корисніше. Для цього є ось що:

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

Звертаючись [0].valueдо цього, тобто $(...)[0].value;дав мені значення вводу безпосередньо, дякую!
Pau Coma Ramirez

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

Змінна елементів буде містити всі входи, виділення, текстові області та набори полів у формі.


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;
});

насправді, відповідь Ланса зберігає асоціативний масив недоторканим для значень POST і приймає колосальний один рядок коду.
msumme

Чому елементи - це масив? ви використовуєте його як звичайний об'єкт. Тут немає необхідності в масиві
Джонатан Моралес Велес

3
@ JonathanMoralesVélez 2008 року Oli вже не є для коментарів. 2015 рік з вами згоден.
Олі-

4

jQuery's 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]. Але ІМО - це набагато краще, ніж використання одного із десятків ліній для картографування.

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

2

У мене була така ж проблема і вирішувалася по-іншому.

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

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


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();
  }
});

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"}

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();
  });

Як не дивно, це не спрацювало над останньою версією jquery 3.4.1
перегляньте

0

Коли мені потрібно було здійснити виклик 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, щоб включати прапорці та текстові поля, а також стандартний тип вибору.


0

serialize () - найкращий метод. @ Крістофер Паркер зазначає, що прихильник Нікфа виконує більше, проте він не враховує, що форма може містити текстові області та меню вибору. Набагато краще використовувати serialize (), а потім маніпулювати цим, як потрібно. Дані з serialize () можна використовувати або в публікації в Ajax, або отримувати, тому проблем там немає.


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
Будь ласка, поясніть свою відповідь
Ling Vu

0

Для декількох елементів вибору ( <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)
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.