Як я можу отримати дані форми за допомогою JavaScript / jQuery?


404

Чи є простий, однорядковий спосіб отримати дані форми таким, як це було б, якби він був поданий класичним способом, що відповідає лише HTML?

Наприклад:

<form>
    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />
    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
</form>

Вихід:

{
    "foo": "1",
    "bar": "xxx",
    "this": "hi"
}

Щось подібне занадто просто, оскільки воно не містить (правильно) текстових областей, вибору, перемикачів і прапорців:

$("#form input").each(function () {
    data[theFieldName] = theFieldValue;
});

3
Інше питання схожий на цей: stackoverflow.com/questions/169506 / ...
Марсело Rodovalho

Відповіді:


431
$('form').serialize() //this produces: "foo=1&bar=xxx&this=hi"

демонстрація


15
Закрити, але, можливо, щось, що повертає масив з парами ключ-значення замість одного рядка?
Барт ван Хекелом

80
Nvm, знайшов це у коментарях до функції serialize (). Це називається serializeArray. Він повертає масив масивів (які містять записи "ім'я" та "значення"), але це має бути досить простим для перетворення.
Барт ван Хекелом

22
А за допомогою бібліотеки підкреслення можна перетворити, використовуючи:_.object($("#myform").serializeArray().map(function(v) {return [v.name, v.value];} ))
MhdSyrwan

8
@BartvanHeukelom Я знаю, що це через 4 роки, але .serializeArray () поверне масив.
TJ WealthEngine API Evangelist

6
Переконайтеся, що кожен вхідний тег містить атрибут імені, інакше він нічого не поверне.
Євген Кулабухов

505

Використовувати $('form').serializeArray(), що повертає масив :

[
  {"name":"foo","value":"1"},
  {"name":"bar","value":"xxx"},
  {"name":"this","value":"hi"}
]

Інший варіант $('form').serialize(), який повертає рядок :

"foo=1&bar=xxx&this=hi"

Погляньте на цю демонстрацію jsfiddle


91
serializeArrayбуло б набагато корисніше, якби він повернув об’єкт з парами ключ-значення
GetFree

8
Я згоден, що предмет був би ідеальним. Однак є проблема - ключ може мати кілька значень. Чи повертаєте ви об’єкт "ключ масиву значень", ключ- "перше значення" чи щось інше? Я думаю, що хлопці jQuery не вибрали нічого з вищезазначеного :)
Пол

Будьте в курсі проблеми з кількома значеннями (як зазначено вище @Paul), прапорці та кілька входів name="multiple[]"не працюють. Рішення для методу POST те саме, просто використовуйте $ ('form'). Serialize (). Також метод POST не має обмеження до 2000 символів, як це робить GET у більшості браузерів, тому його можна використовувати навіть для досить великих даних.
Artru

Будь ласка, майте на увазі, що для того, щоб записати значення з будь-якого введення форми, вхід повинен мати nameатрибут.
Кріс - молодший

@GetFree чому не просто використовувати функцію карти jQuery? функція getFormData (форма) {var rawJson = form.serializeArray (); var модель = {}; $ .map (rawJson, функція (n, i) {model [n ['name']] = n ['value'];}); модель повернення; }
Том МакДонаф

196

Оновлена ​​відповідь за 2014 рік: HTML5 FormData робить це

var formData = new FormData(document.querySelector('form'))

Потім ви можете розмістити formData точно таким, яким він є - він містить усі імена та значення, які використовуються у формі.


13
Плюс один , як FormData добре і корисно, але варто відзначити , що якщо ви хочете , щоб прочитати дані всередині FormData це не зовсім так просто (див stackoverflow.com/questions/7752188 / ... )
StackExchange Що клямка

1
Пам’ятайте, що FormData є частиною розширених функцій XMLHttpRequest (раніше відомих як XMLHttpRequest Level 2), тому ви повинні покластися на полізасипку для Internet Explorer <10. caniuse.com/#feat=xhr2
Pier-Luc Gendreau

3
@yochannah, не так. Звичайно, не можна просто отримати доступ та редагувати дані, як звичайний об’єкт, але все одно тривіально отримати дані. Перевірте entries()метод [сторінка MDN ].
Веб і потік

@Web and Flow дякую, що вказали на це! Мені подобається, коли браузери додають нові корисні функції :) раз, вони змінюються.
StackExchange What The Heck

Я намагаюся використовувати FormData для надсилання об’єкта до мого сценарію Flask-python, але він, схоже, не надходить як звичайний об'єкт запиту, який я можу розпакувати. Чи може хтось вказати на пояснення будь-яких спеціальних кроків для обробки цього на серверній стороні? Ось де мені це здається порожнім.
manisha

180

На основі jQuery.serializeArray, повертає пари ключ-значення.

var data = $('#form').serializeArray().reduce(function(obj, item) {
    obj[item.name] = item.value;
    return obj;
}, {});

11
Пара ключових значень тут, хлопці, всі, приходьте сюди! Це золото !!! Дякую! Якщо я хочу значення елемента, який називається "роздрібний продавець", я роблю це console.log ($ ('# form'). SerializeArray (). Reduct (function (obj, item) {obj [item.name] = item. значення; return obj;}, {}) ['роздрібний продавець']);
Євген Афанасьєв

Я вчора створив метод JQuery на основі цієї відповіді, але працюючи з мультиселективами та вхідними масивами (з назвою 'example []'). Ви можете знайти його в моїй відповіді нижче. У будь-якому випадку, хороший підхід нейронта, дякую! :)
manuman94

Цей мені найбільше підходив із усіх відповідей!
В.Петрович

Цей ІМХО - найкраща відповідь!
Рахул

74
document.querySelector('form').addEventListener('submit', (e) => {
  const formData = new FormData(e.target);
  // Now you can use formData.get('foo'), for example.
  // Don't forget e.preventDefault() if you want to stop normal form .submission
});

Це неприємна відповідь, але дозвольте мені пояснити, чому це краще рішення:

  • Ми належним чином обробляємо подачу форми, а не натискання кнопки. Дехто любить натискати на введення на поля. Деякі люди використовують альтернативні пристрої введення, такі як мовленнєвий вхід або інші пристрої для доступу. Обробіть форму подання, і ви правильно вирішите її для всіх.

  • Ми перекопуємо дані форми для фактично наданої форми. Якщо пізніше ви зміните селектор форми, вам не доведеться змінювати селектори для всіх полів. Крім того, у вас може бути кілька форм з однаковими іменами введення. Не потрібно розлучатись із надмірними ідентифікаторами, а що ні, просто відстежуйте дані на основі поданої форми. Це також дозволяє використовувати один обробник подій для декількох форм, якщо це підходить для вашої ситуації.

  • Інтерфейс FormData є досить новим, але добре підтримується браузерами. Це прекрасний спосіб побудувати цей збір даних, щоб отримати реальні значення того, що є у формі. Без цього вам доведеться переглядати всі елементи (наприклад, з form.elements) і з'ясувати, що перевірено, що ні, які значення і т. Д. Цілком можливо, якщо вам потрібна стара підтримка браузера, але FormData інтерфейс простіший.

  • Тут я використовую ES6 ... жодним чином не вимогою, тому змініть його назад, щоб воно було сумісним з ES5, якщо вам потрібна стара підтримка браузера.


fyi, об'єкти FormData не піддають своїх значень. Щоб отримати простий об'єкт з нього, см stackoverflow.com/questions/41431322 / ...
phil294

2
@Blauhirn Дурниці, звичайно, вони викривають значення. Код у моїй відповіді працює. Ви повинні спробувати. Тут я склав загадку для вас: jsfiddle.net/zv9s1xq5 Якщо ви хочете ітератор, використовуйте formData.entries().
Бред

Я знаю, що це працює, але властивості недоступні за допомогою ключа. Наприклад, formData.foo не визначено. Як видно з вашої відповіді, .get() потрібно викликати те, що я вважаю незручним. Можливо, "не виставляє" натрапив на неправильний шлях. Таким чином, щоб сформувати що - щось на зразок { foo: 'bar' }від submitподії, вам потрібно перебрати їх вручну. Звідси . To get a plain object from it, see [link].
phil294

1
@Blauhirn Ти в цьому помилився. XMLHttpRequest безпосередньо підтримує FormData. xhr.send(formData);
Бред

1
@Blauhirn JSON.stringify([...formData]) Або, якщо ви хочете, щоб ваші ключі / значення були окремими ... [...formData].reduce((prev, cur) => { prev[cur[0]] = cur[1]; return prev;}, {})
Бред

25

використовувати .serializeArray (), щоб отримати дані у форматі масиву, а потім перетворити їх у об'єкт:

function getFormObj(formId) {
    var formObj = {};
    var inputs = $('#'+formId).serializeArray();
    $.each(inputs, function (i, input) {
        formObj[input.name] = input.value;
    });
    return formObj;
}

Це замінює мої прапорці, якщо у мене є щось подібне <input type="checkbox" name="someList" value="one" /> <input type="checkbox" name="someList" value="two" />. Якщо обидва встановлені, об'єкт містить лише друге значення прапорця.
dmathisen

2
Хіба це не той випадок, де someListмає бути type="radio"?
dylanjameswagner

оновлення, оскільки прийнята відповідь не повертає об'єкт з ключами, як:name:value
Метт-Марксист

24

Ось справді простий і короткий солютон, який навіть не вимагає Jquery.

var formElements=document.getElementById("myForm").elements;    
var postData={};
for (var i=0; i<formElements.length; i++)
    if (formElements[i].type!="submit")//we dont want to include the submit-buttom
        postData[formElements[i].name]=formElements[i].value;

1
Це не працює з перемикачами: останній варіант завжди є тим, що зберігається postData.
Кайл Фальконер

3
Дякуємо, що надали нам відповідь без запитання.
Глен Пірс

23

Настав 2019 рік, і є кращий спосіб зробити це:

const form = document.querySelector('form');
const data = new URLSearchParams(new FormData(form).entries());

або якщо ви хочете звичайний об'єкт замість цього

const form = document.querySelector('form');
const data = Object.fromEntries(new FormData(form).entries());

хоча зауважте, що це не працюватиме з повторюваними ключами, як це ви отримуєте з однотипних прапорів з декількома виборами та дублікатами.


Повністю. Хоча я не отримав масив для списку вхідних даних, які мають все те саме ім’я, що означало, що я повинен використовувати document.getElementsByClassNameі для циклу, але ей, все ж приємніше, ніж вимагати jQuery тощо
alphanumeric0101

1
Ця відповідь моя улюблена. Але слід читати document.querySelectorзамість просто querySelector.
адабр

Примітка "FormData використовуватиме лише поля введення, які використовують атрибут імені" - від MDN
binaryfunt


13

Я використовую це:

jQuery плагін

(function($){
  $.fn.getFormData = function(){
    var data = {};
    var dataArray = $(this).serializeArray();
    for(var i=0;i<dataArray.length;i++){
      data[dataArray[i].name] = dataArray[i].value;
    }
    return data;
  }
})(jQuery);

Форма HTML

<form id='myform'>
  <input name='myVar1' />
  <input name='myVar2' />
</form>

Отримати дані

var myData = $("#myForm").getFormData();

Зауважте, що цей плагін не працює для випадків, коли вводиться кілька записів форми з тим самим іменем. Останній запис замінить попередній, тоді як очікувана поведінка полягатиме в тому, щоб отримати всі значення якArray
Міллі

1
Лише зауважте, що через рік я зараз думаю, що це жахлива відповідь, і ніхто не повинен її використовувати. Як говориться в попередньому коментарі, такі речі, як радіо кнопки, не працюватимуть. Вище є кращі відповіді, замість цього використовуйте один із них.
Дастін Пуассан

12
$("#form input, #form select, #form textarea").each(function() {
 data[theFieldName] = theFieldValue;
});

крім цього, ви можете подивитися на serialize () ;


11

Ось робоча реалізація лише JavaScript, яка правильно обробляє прапорці, радіо кнопки та повзунки (напевно, і інші типи вводу, але я лише тестував їх).

function setOrPush(target, val) {
    var result = val;
    if (target) {
        result = [target];
        result.push(val);
    }
    return result;
}

function getFormResults(formElement) {
    var formElements = formElement.elements;
    var formParams = {};
    var i = 0;
    var elem = null;
    for (i = 0; i < formElements.length; i += 1) {
        elem = formElements[i];
        switch (elem.type) {
            case 'submit':
                break;
            case 'radio':
                if (elem.checked) {
                    formParams[elem.name] = elem.value;
                }
                break;
            case 'checkbox':
                if (elem.checked) {
                    formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
                }
                break;
            default:
                formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
        }
    }
    return formParams;
}

Робочий приклад:

    function setOrPush(target, val) {
      var result = val;
      if (target) {
        result = [target];
        result.push(val);
      }
      return result;
    }

    function getFormResults(formElement) {
      var formElements = formElement.elements;
      var formParams = {};
      var i = 0;
      var elem = null;
      for (i = 0; i < formElements.length; i += 1) {
        elem = formElements[i];
        switch (elem.type) {
          case 'submit':
            break;
          case 'radio':
            if (elem.checked) {
              formParams[elem.name] = elem.value;
            }
            break;
          case 'checkbox':
            if (elem.checked) {
              formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
            }
            break;
          default:
            formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
        }
      }
      return formParams;
    }

    //
    // Boilerplate for running the snippet/form
    //

    function ok() {
      var params = getFormResults(document.getElementById('main_form'));
      document.getElementById('results_wrapper').innerHTML = JSON.stringify(params, null, ' ');
    }

    (function() {
      var main_form = document.getElementById('main_form');
      main_form.addEventListener('submit', function(event) {
        event.preventDefault();
        ok();
      }, false);
    })();
<form id="main_form">
  <div id="questions_wrapper">
    <p>what is a?</p>
    <div>
      <input type="radio" required="" name="q_0" value="a" id="a_0">
      <label for="a_0">a</label>
      <input type="radio" required="" name="q_0" value="b" id="a_1">
      <label for="a_1">b</label>
      <input type="radio" required="" name="q_0" value="c" id="a_2">
      <label for="a_2">c</label>
      <input type="radio" required="" name="q_0" value="d" id="a_3">
      <label for="a_3">d</label>
    </div>
    <div class="question range">
      <label for="a_13">A?</label>
      <input type="range" required="" name="q_3" id="a_13" min="0" max="10" step="1" list="q_3_dl">
      <datalist id="q_3_dl">
        <option value="0"></option>
        <option value="1"></option>
        <option value="2"></option>
        <option value="3"></option>
        <option value="4"></option>
        <option value="5"></option>
        <option value="6"></option>
        <option value="7"></option>
        <option value="8"></option>
        <option value="9"></option>
        <option value="10"></option>
      </datalist>
    </div>
    <p>A and/or B?</p>
    <div>
      <input type="checkbox" name="q_4" value="A" id="a_14">
      <label for="a_14">A</label>
      <input type="checkbox" name="q_4" value="B" id="a_15">
      <label for="a_15">B</label>
    </div>
  </div>
  <button id="btn" type="submit">OK</button>
</form>
<div id="results_wrapper"></div>

редагувати:

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


1
Хороше рішення :) Я знайшов одну помилку, але з функцією setOrPush. Він не включає перевірку, щоб дізнатися, чи є цільовим масив, що викликає створення глибокого вкладеного масиву у випадку декількох прапорців з тим самим іменем.
Wouter van Dam

@KyleFalconer Приємно! Чому ви не з’єднали корпуси комутаторів для радіо та прапорця - вони працюватимуть правильно (я думаю).
Етан

@Ethan Це тому, що в прапорець може бути вибрано кілька значень, і радіо може мати лише одне значення, тому спосіб зберігання значення змінюється.
Кайл Фальконер

@KyleFalconer Так, я це розумію. Код для обробки "прапорець" також бере участь у єдиному можливому виборі для "радіо", завдяки процедурі "SetOrPush".
Етан

@Ethan О, я думаю, я знаю, що ти кажеш. Це можна зробити в будь-якому випадку, але я думаю, що я зробив це саме тому, що хотів лише одне значення, а не масив значень.
Кайл Фальконер

9

Якщо ви використовуєте jQuery, ось невелика функція, яка буде робити те, що ви шукаєте.

Спочатку додайте ідентифікатор до своєї форми (якщо це не єдина форма на сторінці, тоді ви можете просто використовувати "form" як запит dom)

<form id="some-form">
 <input type="radio" name="foo" value="1" checked="checked" />
 <input type="radio" name="foo" value="0" />
 <input name="bar" value="xxx" />
 <select name="this">
  <option value="hi" selected="selected">Hi</option>
  <option value="ho">Ho</option>
</form>

<script>
//read in a form's data and convert it to a key:value object
function getFormData(dom_query){
    var out = {};
    var s_data = $(dom_query).serializeArray();
    //transform into simple data/value object
    for(var i = 0; i<s_data.length; i++){
        var record = s_data[i];
        out[record.name] = record.value;
    }
    return out;
}

console.log(getFormData('#some-form'));
</script>

Вихід виглядатиме так:

{
 "foo": "1",
 "bar": "xxx",
 "this": "hi"
}

7

Ви також можете використовувати об'єкти FormData ; Об'єкт FormData дозволяє скласти набір пар ключів / значень для надсилання за допомогою XMLHttpRequest. Її в основному призначені для використання у передачі даних форми, але можуть використовуватися незалежно від форм для передачі ключових даних.

        var formElement = document.getElementById("myform_id");
        var formData = new FormData(formElement);
        console.log(formData);

Дякую, але що робити, якщо у вас немає посвідчення особи? Що робити, якщо у вас є форма як об'єкт JQuery? var форма = $ (це) .closest ('форма'); ? If var formElement = document.getElementById (форма [0]); працювати замість вашої ялинкової лінії? Ну це не працює, на жаль. Ти знаєш чому?
Євген Афанасьєв

Насправді FormData підтримується не у всіх браузерах :( тому краще використовувати інший підхід
numediaweb

Дякую. Я використав останній хром і досі не працював. Тож я пішов з #neuront відповідь звідкись.
Євген Афанасьєв

6

Це додасть усі поля форми до об’єкта JavaScript "res":

var res = {};
$("#form input, #form select, #form textarea").each(function(i, obj) {
    res[obj.name] = $(obj).val();
})

Можливо, тому, що ця така сама відповідь була опублікована в 2010 році
nathanvda

Я цього не знав. Для такої короткої відповіді це не дивно. І навіть так, де посилання?
gamliela

Серйозно? Ви не вірите моєму коментарю без посилання, і ви навіть не можете переглянути список відповідей, щоб побачити, чи вони однакові? stackoverflow.com/a/2276469/216513
nathanvda

Я подумав, що ти маєш на увазі відповідь на інше запитання. Я зараз не пам'ятаю деталей та моїх причин; можливо тому, що це зовсім не те саме
gamliela

1
Ідеальна відповідь для тих, хто хоче, щоб це працювало для введення даних, виберіть декілька та текстові області. Тому що, використовуючи серіалізацію, ви не отримаєте всіх елементів, вибраних у виділеному тезі. Але, використовуючи .val (), ви отримаєте саме те, що хочете як масив. Проста, пряма відповідь.
Сайлеш Кота

6

Я включив відповідь, щоб також повернути необхідний об'єкт.

function getFormData(form) {
var rawJson = form.serializeArray();
var model = {};

$.map(rawJson, function (n, i) {
    model[n['name']] = n['value'];
});

return model;
}

Це взагалі не обробляє масиви; foo[bar][] = 'qux'слід серіалізувати до { foo: { bar: [ 'qux' ] } }.
amphetamachine

6

На основі відповіді нейронта я створив простий метод JQuery, який отримує дані форми у парах ключових значень, але він працює для мультиселекцій та для входів масиву з именем = 'example []'.

Ось як це використовується:

var form_data = $("#form").getFormObject();

Нижче ви можете знайти приклад його визначення та способу його роботи.

// Function start
$.fn.getFormObject = function() {
    var object = $(this).serializeArray().reduce(function(obj, item) {
        var name = item.name.replace("[]", "");
        if ( typeof obj[name] !== "undefined" ) {
            if ( !Array.isArray(obj[name]) ) {
                obj[name] = [ obj[name], item.value ];
            } else {
               obj[name].push(item.value);
            }
        } else {
            obj[name] = item.value;
        }
        return obj;
    }, {});
    return object;
}
// Function ends

// This is how it's used
$("#getObject").click( function() {
  var form_data = $("#form").getFormObject();
  console.log(form_data);
});
/* Only to make view better ;) */
#getObject {
  padding: 10px;
  cursor:pointer;
  background:#0098EE;
  color:white;
  display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<form id="form">
  <input type="text" name="text" value="Hola amigo" /> 
  
  <input type="text" name="text_array[]" value="Array 1" /> 
  <input type="text" name="text_array[]" value="Array 2" /> 
  <input type="text" name="text_array[]" value="Array 3" /> 
  
  <select name="multiselect" multiple>
    <option name="option1" selected> option 1 </option>
    <option name="option2" selected> option 2 </option>
  </select>
  
  <input type="checkbox" name="checkbox" value="checkbox1" checked/>
  <input type="checkbox" name="checkbox" value="checkbox2" checked/>
  
  <input type="radio" name="radio" value="radio1" checked/>
  <input type="radio" name="radio" value="radio2"/>

</form>

<div id="getObject"> Get object (check the console!) </div>


5
var formData = new FormData($('#form-id'));
params   = $('#form-id').serializeArray();

$.each(params, function(i, val) {
    formData.append(val.name, val.value);
});

4
function getFormData($form){
    var unindexed_array = $form.serializeArray();
    var indexed_array = {};

    $.map(unindexed_array, function(n, i){
        if(indexed_array[n['name']] == undefined){
            indexed_array[n['name']] = [n['value']];
        }else{
            indexed_array[n['name']].push(n['value']);
        }
    });

    return indexed_array;
}

4

Ви можете використовувати цю функцію для об'єкта або JSON з форми.

для його використання:

var object = formService.getObjectFormFields("#idform");

 function  getObjectFormFields(formSelector)
        {
            /// <summary>Função que retorna objeto com base nas propriedades name dos elementos do formulário.</summary>
            /// <param name="formSelector" type="String">Seletor do formulário</param>

            var form = $(formSelector);

            var result = {};
            var arrayAuxiliar = [];
            form.find(":input:text").each(function (index, element)
            {
                var name = $(element).attr('name');

                var value = $(element).val();
                result[name] = value;
            });

            form.find(":input[type=hidden]").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });


            form.find(":input:checked").each(function (index, element)
            {
                var name;
                var value;
                if ($(this).attr("type") == "radio")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    result[name] = value;
                }
                else if ($(this).attr("type") == "checkbox")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    if (result[name])
                    {
                        if (Array.isArray(result[name]))
                        {
                            result[name].push(value);
                        } else
                        {
                            var aux = result[name];
                            result[name] = [];
                            result[name].push(aux);
                            result[name].push(value);
                        }

                    } else
                    {
                        result[name] = [];
                        result[name].push(value);
                    }
                }

            });

            form.find("select option:selected").each(function (index, element)
            {
                var name = $(element).parent().attr('name');
                var value = $(element).val();
                result[name] = value;

            });

            arrayAuxiliar = [];
            form.find("checkbox:checked").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = arrayAuxiliar.push(value);
            });

            form.find("textarea").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });

            return result;
        }


2
Хоча це посилання може відповісти на питання, краще включити сюди суттєві частини відповіді та надати посилання для довідки. Відповіді лише на посилання можуть стати недійсними, якщо пов’язана сторінка зміниться. - З огляду
Вахіу Крістіанто

Але це посилання має функцію для його допомоги (я думаю). Але я збираюся поставити код наступного разу.
Маркос Коста

3

Я написав бібліотеку, щоб вирішити цю саму проблему: JSONForms . Він приймає форму, проходить кожен вхід і створює об'єкт JSON, який ви можете легко прочитати.

Скажімо, у вас є така форма:

<form enctype='application/json'>
  <input name='places[0][city]' value='New York City'>
  <input type='number' name='places[0][population]' value='8175133'>
  <input name='places[1][city]' value='Los Angeles'>
  <input type='number' name='places[1][population]' value='3792621'>
  <input name='places[2][city]' value='Chicago'>
  <input type='number' name='places[2][population]' value='2695598'>
</form>

Передача форми методу кодування JSONForms повертає вам наступний об'єкт:

{
  "places": [
    {
      "city": "New York City",
      "population": 8175133
    },
    {
      "city": "Los Angeles",
      "population": 3792621
    },
    {
      "city": "Chicago",
      "population": 2695598
    }
  ]
}

Ось демонстрація вашої форми.


Чудово виглядає і працює, дякую. Тільки одне, що мінімізована версія викликає файл карти, має бути необов’язковим imo.
adi518

2

$( "form" ).bind( "submit", function(e) {
    e.preventDefault();
    
    console.log(  $(this).serializeObject() );    

    //console.log(  $(this).serialize() );
    //console.log(  $(this).serializeArray() );

});


$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();

    $.each( a, function() {
        if ( o[this.name] !== undefined) 
        {
            if ( ! o[this.name].push ) 
            {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        }
        else 
        {
            o[this.name] = this.value || '';
        }
    });

    return o;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<form>

    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />

    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
    </select>

    <input type="submit" value="Submit" />

</form>

Codepen


2

Тим із вас, хто вважає за краще Objectсеріалізований рядок (наприклад, той, який повернувся $(form).serialize(), і незначне поліпшення $(form).serializeArray()), сміливо використовуйте код нижче:

var Form = {
    _form: null,
    _validate: function(){
        if(!this._form || this._form.tagName.toLowerCase() !== "form") return false;
        if(!this._form.elements.length) return false;
    }, _loopFields: function(callback){
        var elements = this._form.elements;
        for(var i = 0; i < elements.length; i++){
            var element = form.elements[i];
            if(name !== ""){
                callback(this._valueOfField(element));
            }
        }
    }, _valueOfField: function(element){
        var type = element.type;
        var name = element.name.trim();
        var nodeName = element.nodeName.toLowerCase();
        switch(nodeName){
            case "input":
                if(type === "radio" || type === "checkbox"){
                    if(element.checked){
                        return element.value;
                    }
                }
                return element.value;
                break;
            case "select":
                if(type === "select-multiple"){
                    for(var i = 0; i < element.options.length; i++){
                        if(options[i].selected){
                            return element.value;
                        }
                    }
                }
                return element.value;
                break;
            case "button":
                switch(type){
                    case "reset": 
                    case "submit": 
                    case "button":
                        return element.value;
                        break;
                }
                break;
        } 
    }, serialize: function(form){
        var data = {};
        this._form = form;

        if(this._validate()){
            this._loopFields(function(value){
                if(value !== null) data[name] = value;
            });
        }
        return data;
    }
};

Щоб виконати його, просто використовуйте, Form.serialize(form)і функція поверне Objectаналогічну цьому:

<!-- { username: "username", password: "password" } !-->
<input type="text" value="username">
<input type="password" value="password">

Як бонус, це означає, що вам не доведеться встановлювати весь пакет jQuery лише для однієї функції серіалізації.


1

Я написав функцію, яка піклується про декілька прапорців і кілька виборів. У цих випадках він повертає масив.

function getFormData(formId) {
    return $('#' + formId).serializeArray().reduce(function (obj, item) {
        var name = item.name,
            value = item.value;

        if (obj.hasOwnProperty(name)) {
            if (typeof obj[name] == "string") {
                obj[name] = [obj[name]];
                obj[name].push(value);
            } else {
                obj[name].push(value);
            }
        } else {
            obj[name] = value;
        }
        return obj;
    }, {});
}

1

показуючи поля введення форми форми та вхідний файл, щоб подати форму без оновлення сторінки та захопити всі значення, якщо файл включить у нього ось воно

<form id="imageUploadForm"   action="" method="post" enctype="multipart/form-data">
<input type="text" class="form-control" id="fname" name='fname' placeholder="First Name" >
<input type="text" class="form-control" name='lname' id="lname" placeholder="Last Name">
<input type="number" name='phoneno'  class="form-control" id="phoneno" placeholder="Phone Number">
<textarea class="form-control" name='address' id="address" rows="5" cols="5" placeholder="Your Address"></textarea>
<input type="file" name="file" id="file" >
<input type="submit" id="sub" value="Registration">					   
</form>
на сторінці кнопки "Надіслати" надішлемо запит ajax у ваш файл PHP.
$('#imageUploadForm').on('submit',(function(e) 
{
     fname = $('#fname').val();
     lname =  $('#lname').val();
     address =  $('#address').val();
     phoneno =  $('#phoneno').val();
     file =  $('#file').val();
     e.preventDefault();
     var formData = new FormData(this);
     formData.append('file', $('#file')[0]);
     formData.append('fname',$('#fname').val());
     formData.append('lname',$('#lname').val());
     formData.append('phoneno',$('#phoneno').val());
     formData.append('address',$('#address').val());
     $.ajax({
		type:'POST',
                url: "test.php",
                //url: '<?php echo base_url().'edit_profile/edit_profile2';?>',

                data:formData,
                cache:false,
                contentType: false,
                processData: false,
                success:function(data)
                {
                     alert('Data with file are submitted !');

                }

     });

}))


У чому потреба нового FormData?
Саху V Кумар

1
@VishalKumarSahu я завантажую файл, тому я використовую для цього formData.
Mohsin Shoukat

1
$(form).serializeArray().reduce(function (obj, item) {
      if (obj[item.name]) {
           if ($.isArray(obj[item.name])) {
               obj[item.name].push(item.value);
           } else {
                var previousValue = obj[item.name];
                obj[item.name] = [previousValue, item.value];
           }
      } else {
           obj[item.name] = item.value;
      }

     return obj;
}, {});

Це виправить проблему: не вдалося працювати з багатоселекторами.


0

Ви всі не зовсім правильні. Ви не можете написати:

formObj[input.name] = input.value;

Тому що, якщо у вас є багатоселекційний список - його значення будуть перезаписані останніми, оскільки вони передаються як: "param1": "value1", "param1": "value2".

Отже, правильний підхід:

if (formData[input.name] === undefined) {
    formData[input.name] = input.value;
}
else {
    var inputFieldArray = $.merge([], $.isArray(formData[input.name]) ? formData[input.name] : [formData[input.name]]);
    $.merge(inputFieldArray, [input.value]);
    formData[input.name] = $.merge([], inputFieldArray);
}

0

Цей метод повинен це зробити. Він серіалізує дані форми, а потім перетворює їх на об'єкт. Опікується також групами прапорців.

function getFormObj(formId) {
  var formParams = {};
  $('#' + formId)
    .serializeArray()
    .forEach(function(item) {
      if (formParams[item.name]) {
        formParams[item.name] = [formParams[item.name]];
        formParams[item.name].push(item.value)
      } else {
        formParams[item.name] = item.value
      }
    });
  return formParams;
}

Працює для прапорців, але не для радіо кнопок, де елементи керування поділяють nameатрибут.
Кайл Фальконер

0

Ось приємна функція JS ванілі, яку я написав для отримання даних форми як об’єкта. Він також має параметри для вставки доповнень в об’єкт та для очищення полів введення форми.

const extractFormData = ({ form, clear, add }) => {
  return [].slice.call(form.children).filter(node => node.nodeName === 'INPUT')
  .reduce((formData, input) => {
    const value = input.value
    if (clear) { input.value = '' }
    return {
      ...formData,
      [input.name]: value
    }
  }, add)
}

Ось приклад його використання із запитом на пошту:

submitGrudge(e) {
  e.preventDefault()

  const form = e.target
  const add = { id: Date.now(), forgiven: false }
  const grudge = extractFormData({ form, add, clear: true })

  // grudge = {
  //  "name": "Example name",
  //  "offense": "Example string",
  //  "date": "2017-02-16",
  //  "id": 1487877281983,
  //  "forgiven": false
  // }

  fetch('http://localhost:3001/api/grudge', {
    method: 'post',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(grudge)
  })
    .then(response => response.json())
    .then(grudges => this.setState({ grudges }))
    .catch(err => console.log('error: ', err))
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.