รับฟิลด์อินพุตแบบฟอร์มโดยใช้ jQuery หรือไม่


412

ฉันมีรูปแบบที่มีช่องป้อนข้อมูลมากมาย

เมื่อฉันจับเหตุการณ์ส่งแบบฟอร์มด้วย jQuery เป็นไปได้หรือไม่ที่จะรับฟิลด์อินพุตทั้งหมดของฟอร์มนั้นในอาเรย์แบบเชื่อมโยง


23
มันเป็นคำถามที่ดี ในความเป็นจริงฉันคิดว่ามันแปลกจริง ๆ ที่ jQuery ไม่มีฟังก์ชันที่ทำสิ่งนี้ได้อย่างแม่นยำ มีฟังก์ชั่นเพื่อรับข้อมูลฟอร์มในสองรูปแบบที่แตกต่างกัน แต่ไม่ใช่สิ่งที่สะดวกที่สุดสำหรับคุณรู้สคริปต์ ... (อาจเป็น. วาล () ควรกลับอาร์เรย์เช่นนี้ถ้าเรียกว่าองค์ประกอบแบบฟอร์ม?)
Luke Maurer

คำตอบ:


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 นั้นแข็งแกร่งและง่ายกว่า
MightyE

1
@MightyE & @Simon_Weaver - คุณพูดถูกมันเป็นวิธีที่แข็งแกร่งกว่า แต่ก็ไม่ได้ทำตามที่ OP ต้องการ serializeArray ส่งกลับอาร์เรย์ของวัตถุที่มีคุณสมบัติที่และname valueทางออกที่ดีกว่าอาจเป็นการประมวลผลเอาต์พุตจาก serializeArray เป็นรูปแบบที่จำเป็น
nickf

1
ฉันคิดว่า serializeArray () ทำสิ่งที่คุณต้องการอย่างแน่นอนและมีรหัสน้อยกว่ามาก
slacy

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 เช่นที่คุณมีฟิลด์ [บางสิ่ง] และฟิลด์ [something_else] เป็นชื่อของอินพุต ... อย่างน้อย ฉันไม่สามารถเห็นได้ว่ามันจะเป็นอย่างไร ...
msumme

43
ตามเอกสาร jQuery API .serialize()( api.jquery.com/serialize ) ทำให้องค์ประกอบทั้งหมดของฟอร์มในสตริงเดียวพร้อมสำหรับการต่อท้าย URL ในสตริงข้อความค้นหาซึ่งเป็นการเลียนแบบคำขอ GET สิ่งนี้จะไม่สำเร็จในสิ่งที่คำตอบของ Nickf ทำได้
Christopher Parker

นี่คือคำตอบที่ดีที่สุด!
Daniel Hunter

5
น่ารู้: .serialize()ยังใช้งานได้ในรูปแบบองค์ประกอบเท่านั้น ดังนั้น$('form select').serialize()จะทำให้เป็นอนุกรมข้อมูลเท่านั้นสำหรับการเลือก
ต้านพิษ

3
แทนที่จะทำซ้ำ$('#myForm')ให้ใช้ $ (สิ่งนี้)
Jimothy

23

jquery.formปลั๊กอินอาจช่วยให้กับสิ่งที่คนอื่นกำลังมองหาสิ้นสุดที่ขึ้นกับคำถามนี้ ฉันไม่แน่ใจว่ามันจะตรงกับสิ่งที่คุณต้องการหรือไม่

นอกจากนี้ยังมีฟังก์ชั่นserializeArray


15

บางครั้งฉันพบว่าการใช้ทีละครั้งก็มีประโยชน์มากกว่า สำหรับสิ่งนี้มีสิ่งนี้:

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

ต่อท้าย[0].valueคือ$(...)[0].value;ให้ค่าของอินพุตโดยตรงขอบคุณ!
โป Coma Ramirez

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

ตัวแปรองค์ประกอบจะมีอินพุตทั้งหมดเลือก textareas และ fieldets ภายในแบบฟอร์ม


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

เหตุใดจึงเป็นรายการอาเรย์ คุณกำลังใช้มันเหมือนวัตถุธรรมดา ไม่จำเป็นต้องมีอาร์เรย์ในที่นี้
Jonathan Morales Vélez

3
@ JonathanMoralesVélezปี 2008 Oli ไม่มีความคิดเห็นอีกต่อไป ปี 2015 เห็นด้วยกับคุณ
Oli

4

jQuery serializeArrayไม่รวมเขตข้อมูลที่ถูกปิดใช้งานดังนั้นหากคุณต้องการสิ่งเหล่านั้นด้วยให้ลอง:

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



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

ดูเหมือนแปลกที่ไม่มีใคร upvoted หรือเสนอวิธีแก้ปัญหาสั้น ๆ เพื่อรับข้อมูลรายการ แทบทุกรูปแบบจะเป็นวัตถุขนาดเดียว

ข้อเสียของการแก้ปัญหานี้คือแน่นอนว่าวัตถุเดี่ยวของคุณจะต้องเข้าถึงได้ที่ดัชนี [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;
}, {});

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

แรงบันดาลใจจากคำตอบของLance Rushingและ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
relipse

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

ทำให้เป็นอันดับ () เป็นวิธีที่ดีที่สุด @ Christopher Parker บอกว่า anwser ของ Nickf ทำงานได้สำเร็จมากขึ้นอย่างไรก็ตามไม่คำนึงว่ารูปแบบอาจมี textarea และเมนูที่เลือก เป็นการดีกว่าที่จะใช้ 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

คำตอบทั้งหมดเป็นสิ่งที่ดี แต่ถ้ามีเขตข้อมูลที่คุณต้องการละเว้นในฟังก์ชันนั้น ง่าย ๆ ให้คุณสมบัติกับฟิลด์ตัวอย่างเช่นละเว้น _:

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

และในฟังก์ชั่นต่อเนื่องของคุณ:

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

นั่นคือวิธีที่คุณไม่สนใจบางฟิลด์


1
นี่เป็นความคิดเห็นมากกว่าคำตอบเนื่องจากไม่ได้ตอบคำถามเดิม
Wai Ha Lee

อาจเป็นเพราะเขามีคำตอบมากมายอยู่แล้ว? มันเป็นส่วนประกอบของคำตอบที่เขาได้รับ
Marcelo Rocha

ฉันจะใช้สิ่งนี้ด้วยชื่อคลาสอย่างบังคับถ้ากรอกข้อมูลแล้วฉันสามารถตรวจสอบ$('.mandatory');และ!$('.mandatory');
lharby

เปลี่ยนignore_thisเป็นdata-ignore-this="true"แทนที่จะสร้างแอตทริบิวต์ของคุณเองที่ไม่ตรวจสอบความถูกต้อง w3c
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)
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.