Jak mogę uzyskać dane formularza za pomocą JavaScript / jQuery?


404

Czy istnieje prosty, jednowierszowy sposób na uzyskanie danych formularza, tak jak by to było, gdyby był on przesyłany w klasyczny sposób oparty tylko na HTML?

Na przykład:

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

Wynik:

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

Coś takiego jest zbyt proste, ponieważ nie obejmuje (poprawnie) obszarów tekstowych, zaznaczeń, przycisków opcji i pól wyboru:

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

3
Kolejne pytanie podobne do tego: stackoverflow.com/questions/169506/…
Marcelo Rodovalho

Odpowiedzi:


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

próbny


15
Zamknij, ale może coś, co zwraca tablicę z parami klucz-wartość zamiast pojedynczego ciągu?
Bart van Heukelom

80
Nvm, znalazł to w komentarzach do funkcji serialize (). Nazywa się to serializeArray. Zwraca tablicę tablic (które zawierają wpis „nazwa” i „wartość”), ale powinno to być dość łatwe do przekształcenia.
Bart van Heukelom

22
Za pomocą biblioteki podkreślania można przekształcić, używając:_.object($("#myform").serializeArray().map(function(v) {return [v.name, v.value];} ))
MhdSyrwan

8
@BartvanHeukelom Wiem, że to 4 lata później, ale .serializeArray () zwróci tablicę.
TJ WealthEngine API Evangelist

6
Upewnij się, że każdy tag wejściowy zawiera atrybut name, w przeciwnym razie nic nie zwróci.
Eugene Kulabuhov

505

Użyj $('form').serializeArray(), która zwraca tablicę :

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

Inną opcją jest $('form').serialize(), która zwraca ciąg znaków :

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

Spójrz na to demo jsfiddle


91
serializeArraybyłby o wiele bardziej przydatny, gdyby zwrócił obiekt z parami klucz-wartość
GetFree

8
Zgadzam się, że przedmiot byłby idealny. Istnieje jednak problem - klucz może mieć wiele wartości. Czy zwróciłbyś obiekt klucz- „tablica wartości”, klucz „pierwsza wartość” czy coś innego? Myślę, że chłopaki jQuery nie wybrali żadnego z powyższych :)
Paul,

Należy pamiętać o problemie z wieloma wartościami (jak wspomniano powyżej @Paul), pola wyboru i wiele danych wejściowych name="multiple[]"nie działają. Rozwiązanie dla metody POST jest takie samo, wystarczy użyć $ („forma”). Serialize (). Również metoda POST nie ma limitu 2000 znaków, podobnie jak GET w większości przeglądarek, więc można jej używać nawet w przypadku dość dużych danych.
Artru,

Uwaga: aby zapisać wartość z dowolnego formularza wejściowego, dane wejściowe muszą mieć nameatrybut.
Chris - Jr

@ GetFree, dlaczego nie skorzystać z funkcji mapy jQuery? funkcja getFormData (formularz) {var rawJson = form.serializeArray (); var model = {}; $ .map (rawJson, funkcja (n, i) {model [n ['nazwa']] = n ['wartość'];}); model powrotu; }
Tom McDonough,

196

Zaktualizowana odpowiedź dla 2014: HTML5 FormData to robi

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

Następnie możesz opublikować formData dokładnie tak, jak jest - zawiera wszystkie nazwy i wartości użyte w formularzu.


13
Plus jeden jako FormData jest dobry i użyteczny, ale warto zauważyć, że jeśli chcesz CZYTAĆ dane w FormData, nie jest to takie łatwe (zobacz stackoverflow.com/questions/7752188/... )
StackExchange What The Heck

1
Pamiętaj, że FormData jest częścią zaawansowanych funkcji XMLHttpRequest (wcześniej znanych jako XMLHttpRequest poziom 2), więc musisz polegać na wypełnieniu w przeglądarce Internet Explorer <10. caniuse.com/#feat=xhr2
Pier-Luc Gendreau

3
@yochannah, nie tak. Jasne, nie można po prostu uzyskać dostępu do danych i edytować ich jak zwykły obiekt, ale uzyskanie danych jest nadal trywialne. Sprawdź entries()metodę [strona MDN ].
Web and Flow

@ Web i Flow dziękuję za zwrócenie na to uwagi! Uwielbiam, gdy przeglądarki dodają nowe i przydatne funkcje :) razy, zmieniają się.
StackExchange What The Heck 18.09.16

Próbuję użyć FormData, aby wysłać obiekt do mojego skryptu Flask-python, ale nie wydaje się, aby był to zwykły obiekt żądania, który można rozpakować. Czy ktoś może wskazać wyjaśnienie specjalnych kroków, które należy wykonać po stronie serwera? To wydaje mi się puste.
manisha

180

Na podstawie jQuery.serializeArrayzwraca pary klucz-wartość.

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

11
Pary klucz-wartość tutaj, chłopaki, wszyscy, chodźcie tutaj! To jest złote !!! Dzięki! Jeśli chcę wartość elementu o nazwie „sprzedawca”, robię to console.log ($ ('# form'). SerializeArray (). Redukuj (function (obj, item) {obj [item.name] = item. wartość; return obj;}, {}) ['sprzedawca detaliczny]]);
Jewgienij Afanasyjew,

Wczoraj stworzyłem metodę JQuery na podstawie tej odpowiedzi, ale pracuję z multiselects i tablicami wejściowymi (o nazwie „przykład []”). Możesz to znaleźć w mojej odpowiedzi poniżej. W każdym razie, dobre podejście do neuront, dzięki! :)
manuman94,

Ten najbardziej mi odpowiadał spośród wszystkich odpowiedzi!
VPetrovic

To IMHO jest najlepszą odpowiedzią!
Rahul

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

To kiepska odpowiedź, ale pozwól mi wyjaśnić, dlaczego jest to lepsze rozwiązanie:

  • Prawidłowo obsługujemy przesyłanie formularza, a nie naciśnięcie przycisku. Niektórzy ludzie lubią naciskać enter na polach. Niektóre osoby używają alternatywnych urządzeń wejściowych, takich jak wprowadzanie mowy lub inne urządzenia ułatwiające dostęp. Zajmij się przesłaniem formularza i poprawnie go rozwiąż dla wszystkich.

  • Wnikamy w dane formularza dla faktycznie przesłanego formularza. Jeśli zmienisz selektor formularza później, nie musisz zmieniać selektorów dla wszystkich pól. Ponadto możesz mieć kilka formularzy o takich samych nazwach wejściowych. Nie trzeba rozróżniać z nadmiernymi identyfikatorami, a co nie, wystarczy śledzić dane wejściowe na podstawie przesłanego formularza. Umożliwia to również użycie jednego modułu obsługi zdarzeń dla wielu formularzy, jeśli jest to odpowiednie w danej sytuacji.

  • Interfejs FormData jest dość nowy, ale jest dobrze obsługiwany przez przeglądarki. To świetny sposób na zbudowanie tego zbioru danych, aby uzyskać rzeczywiste wartości tego, co jest w formularzu. Bez niego będziesz musiał przejrzeć wszystkie elementy (np. Za pomocą form.elements) i dowiedzieć się, co jest zaznaczone, a co nie, jakie są wartości itp. Całkowicie możliwe, jeśli potrzebujesz obsługi starej przeglądarki, ale FormData interfejs jest prostszy.

  • Używam tutaj ES6 ... w żadnym wypadku nie jest to wymóg, więc zmień go ponownie, aby był zgodny z ES5, jeśli potrzebujesz obsługi starej przeglądarki.


fyi, obiekty FormData nie ujawniają swoich wartości. Aby uzyskać z niego zwykły obiekt, zobacz stackoverflow.com/questions/41431322/...
phil294

2
@Blauhirn Nonsense, oczywiście ujawniają wartości. Kod w mojej odpowiedzi działa. Powinieneś spróbować. Tutaj zrobiłem dla ciebie skrzypce: jsfiddle.net/zv9s1xq5 Jeśli chcesz iteratora, użyj formData.entries().
Brad

Wiem, że to działa, ale właściwości nie są dostępne według klucza. Na przykład formData.foo jest niezdefiniowany. Jak widać w twojej odpowiedzi.get() należy wezwać do tego, co moim zdaniem jest niewygodne. Może „nie ujawnia się” przyszło w niewłaściwy sposób. Aby więc wygenerować coś { foo: 'bar' }na podstawie submitzdarzenia, musisz iterować je ręcznie. Stąd . To get a plain object from it, see [link].
phil294,

1
@Blauhirn Mylisz się co do tego. XMLHttpRequest bezpośrednio obsługuje FormData. xhr.send(formData);
Brad

1
@Blauhirn JSON.stringify([...formData]) Lub jeśli chcesz, aby twoje klucze / wartości były oddzielne ... [...formData].reduce((prev, cur) => { prev[cur[0]] = cur[1]; return prev;}, {})
Brad

25

użyj .serializeArray (), aby uzyskać dane w formacie tablicowym, a następnie przekonwertować je na obiekt:

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

To zastępuje moje pola wyboru, jeśli mam coś takiego <input type="checkbox" name="someList" value="one" /> <input type="checkbox" name="someList" value="two" />. Jeśli oba są zaznaczone, obiekt zawiera tylko drugą wartość pola wyboru.
dmathisen

2
Czy to nie jest przypadek, w którym someListpowinien być type="radio"?
dylanjameswagner

głosuj, ponieważ zaakceptowana odpowiedź nie zwraca obiektu z kluczami, ponieważ:name:value
Matt-the-Marksist

24

Oto naprawdę proste i krótkie rozwiązanie, które nawet nie wymaga 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
Nie działa to z przyciskami opcji: ostatnia opcja jest zawsze zapisana w postData.
Kyle Falconer,

3
Dziękujemy za udzielenie nam odpowiedzi niewymagającej odpowiedzi.
Glen Pierce,

23

Jest rok 2019 i jest na to lepszy sposób:

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

lub jeśli zamiast tego chcesz zwykły Obiekt

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

chociaż pamiętaj, że nie będzie to działać ze zduplikowanymi kluczami, takimi jak w przypadku wielokrotnego wyboru i duplikowania pól wyboru o tej samej nazwie.


Całkowicie. Chociaż nie dostałem tablicy dla listy danych wejściowych, które wszystkie mają tę samą nazwę, co oznaczało, że musiałem użyć document.getElementsByClassNamei pętli for, ale hej, wciąż ładniejszy niż wymaganie jQuery itp.
alphanumeric0101

1
Ta odpowiedź jest moją ulubioną. Ale powinien czytać document.querySelectorzamiast po prostu querySelector.
adabru

Uwaga „FormData użyje tylko pól wejściowych, które używają atrybutu name” - z MDN
binaryfunt


13

Używam tego:

jQuery Plugin

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

Formularz HTML

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

Uzyskaj dane

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

Pamiętaj, że ta wtyczka nie działa w przypadkach, w których występuje wiele wpisów formularza o tej samej nazwie. Ostatni wpis zastąpiłby poprzedni, podczas gdy oczekiwanym zachowaniem byłoby uzyskanie wszystkich wartości jakoArray
Milli

1
Tylko uwaga, że ​​rok później uważam, że to okropna odpowiedź i nikt nie powinien jej używać. Jak mówi poprzedni komentarz, rzeczy takie jak przyciski opcji nie działałyby. Powyżej są lepsze odpowiedzi, zamiast tego użyj jednej z nich.
Dustin Poissant,

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

poza tym, możesz chcieć spojrzeć na serialize () ;


11

Oto działająca implementacja tylko JavaScript, która poprawnie obsługuje pola wyboru, przyciski opcji i suwaki (prawdopodobnie także inne typy danych wejściowych, ale tylko je przetestowałem).

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

Przykład roboczy:

    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>

edytować:

Jeśli szukasz bardziej kompletnej implementacji, zapoznaj się z tą częścią projektu, dla którego to zrobiłem . W końcu zaktualizuję to pytanie o kompletne rozwiązanie, które wymyśliłem, ale być może będzie to pomocne dla kogoś.


1
Ładne rozwiązanie :) Znalazłem jednak jeden błąd, z funkcją setOrPush. Nie obejmuje sprawdzenia, czy cel jest już tablicą, co powoduje utworzenie głęboko zagnieżdżonej tablicy w przypadku wielu zaznaczonych pól wyboru o tej samej nazwie.
Wouter van Dam

@KyleFalconer Nice! Dlaczego nie scaliłeś skrzynek przełączników dla radia i pola wyboru - będą działać poprawnie (tak myślę).
Ethan

@ Ethan To dlatego, że pole wyboru może mieć wybrane wiele wartości, a radio może mieć tylko jedną wybraną wartość, więc sposób przechowywania wartości zmienia się.
Kyle Falconer,

@KyleFalconer Tak, rozumiem to. Kod obsługi „pola wyboru” zajmuje się również jednym możliwym wyborem dla „radia”, zgodnie z procedurą „SetOrPush”.
Ethan,

@ Ethan Och, chyba wiem, co mówisz. Można to zrobić w obie strony, ale myślę, że zrobiłem to w ten sposób tylko dlatego, że chciałem tylko jednej wartości, a nie tablicy wartości.
Kyle Falconer,

9

Jeśli używasz jQuery, oto mała funkcja, która zrobi to, czego szukasz.

Najpierw dodaj identyfikator do formularza (chyba że jest to jedyny formularz na stronie, możesz po prostu użyć „formularza” jako zapytania 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>

Dane wyjściowe wyglądałyby następująco:

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

7

Możesz także użyć obiektów FormData ; Obiekt FormData pozwala skompilować zestaw par klucz / wartość do wysłania za pomocą XMLHttpRequest. Jest przeznaczony przede wszystkim do przesyłania danych formularzy, ale można go używać niezależnie od formularzy w celu przesyłania danych z kluczem.

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

Dzięki, ale co, jeśli nie masz dokumentu tożsamości? Co jeśli masz formularz jako obiekt JQuery? var form = $ (this) .closest ('form'); ? Należy var formElement = document.getElementById (formularz [0]); pracować zamiast swojej linii firs? Niestety nie działa. Wiesz dlaczego?
Jewgienij Afanasiew

W rzeczywistości FormData nie jest obsługiwana przez wszystkie przeglądarki :( więc lepiej użyj innego podejścia
numediaweb

Dzięki. Użyłem najnowszego chromu i nadal nie działał. Więc poszedłem z odpowiedzią #neuront z góry.
Jewgienij Afanasiew

6

Spowoduje to dołączenie wszystkich pól formularza do obiektu JavaScript „res”:

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

Prawdopodobnie dlatego, że ta sama odpowiedź została już opublikowana w 2010 r.
nathanvda

Nie wiedziałem tego Przy tak krótkiej odpowiedzi nie jest to zaskakujące. A mimo to, gdzie jest odniesienie?
gamliela

Poważnie? Nie wierzysz w mój komentarz bez odniesienia i nie możesz nawet przejrzeć listy odpowiedzi, aby sprawdzić, czy są one takie same? stackoverflow.com/a/2276469/216513
nathanvda

Myślałem, że masz na myśli odpowiedź na inne pytanie. Nie pamiętam teraz szczegółów i moich powodów; może dlatego, że nie jest dokładnie taki sam
gamliela

1
Idealna odpowiedź dla kogoś, kto chce, aby działał na potrzeby wprowadzania, wybierz wielokrotność i pole tekstowe. Ponieważ przy użyciu serializacji nie otrzymasz wszystkich elementów wybranych w tagu select. Ale używając .val () dostaniesz dokładnie to, co chcesz jako tablicę. Prosta, bezpośrednia odpowiedź.
Sailesh Kotha

6

Podałem odpowiedź, aby również zwrócić wymagany przedmiot.

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

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

return model;
}

To w ogóle nie obsługuje tablic; foo[bar][] = 'qux'powinien serializować do { foo: { bar: [ 'qux' ] } }.
amfetamachina

6

Na podstawie odpowiedzi neuronta stworzyłem prostą metodę JQuery, która pobiera dane formularza w parach klucz-wartość, ale działa w przypadku wielokrotnego wyboru i dla danych wejściowych tablic o nazwie = „przykład []”.

Oto jak jest używany:

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

Poniżej znajduje się przykład jego definicji i sposobu działania.

// 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

możesz użyć tej funkcji do uzyskania obiektu lub kodu JSON z formularza.

do użycia:

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
Chociaż ten link może odpowiedzieć na pytanie, lepiej dołączyć tutaj istotne części odpowiedzi i podać link w celach informacyjnych. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie. - Z recenzji
Wahyu Kristianto,

Ale ten link ma funkcję pomagającą jego (tak mi się wydaje). Ale następnym razem umieszczę kod.
Marcos Costa

3

Napisałem bibliotekę, aby rozwiązać ten bardzo problem: JSONForms . Przybiera formę, przechodzi przez każde wejście i buduje obiekt JSON, który można łatwo odczytać.

Powiedz, że masz następującą formę:

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

Przekazanie formularza do metody kodowania JSONForms powoduje zwrócenie następującego obiektu:

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

Oto demo ze swoim formularzem.


Ładnie wygląda i działa, dzięki. Tylko jedna rzecz, zminimalizowana wersja wywołuje plik mapy, powinna być opcjonalna 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

Dla tych z Was, którzy wolą Objectłańcuch zamiast serializowanego (jak ten zwrócony przez $(form).serialize()i niewielka poprawa $(form).serializeArray()), skorzystaj z poniższego kodu:

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

Aby go wykonać, po prostu użyj, Form.serialize(form)a funkcja zwróci Objectpodobny do tego:

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

Jako bonus oznacza to, że nie musisz instalować całego pakietu jQuery tylko dla jednej funkcji serializacji.


1

Napisałem funkcję, która zajmuje się wieloma polami wyboru i wieloma zaznaczeniami. W takich przypadkach zwraca tablicę.

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

wyświetlanie pól elementu formularza i pliku wejściowego w celu przesłania formularza bez odświeżania strony i pobrania wszystkich wartości z plikiem zawartym w nim tutaj

<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>
na stronie przycisku Prześlij wyśle ​​żądanie ajax do twojego pliku 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 !');

                }

     });

}))


Jaka jest tutaj potrzeba nowych formularzy FormData?
Sahu V Kumar

1
@VishalKumarSahu przesyłam plik, dlatego do tego używam 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;
}, {});

Naprawi to problem: nie może działać z wieloma zaznaczeniami.


0

Nie jesteście w pełni poprawni. Nie możesz pisać:

formObj[input.name] = input.value;

Ponieważ w ten sposób, jeśli masz listę wielokrotnego wyboru - jej wartości zostaną zastąpione ostatnią, ponieważ jest przesyłana jako: „param1”: „wartość1”, „param1”: „wartość2”.

Prawidłowe podejście to:

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

Ta metoda powinna to zrobić. Serializuje dane formularza, a następnie przekształca je w obiekt. Dba również o grupy pól wyboru.

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

Działa w przypadku pól wyboru, ale nie w przypadku przycisków opcji, w których elementy sterujące mają wspólny nameatrybut.
Kyle Falconer,

0

Oto fajna waniliowa funkcja JS, którą napisałem, aby wyodrębnić dane formularza jako obiekt. Posiada również opcje wstawiania dodatków do obiektu i czyszczenia pól wprowadzania formularza.

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

Oto przykład jego użycia z żądaniem postu:

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))
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.