Có được các trường nhập mẫu bằng cách sử dụng jQuery?


412

Tôi có một hình thức với nhiều lĩnh vực đầu vào.

Khi tôi bắt sự kiện biểu mẫu gửi bằng jQuery, có thể lấy tất cả các trường đầu vào của biểu mẫu đó trong một mảng kết hợp không?


23
Đó là một câu hỏi hay; thực tế, tôi thấy thật lạ khi jQuery không có chức năng thực hiện chính xác điều này. Có các hàm để lấy dữ liệu biểu mẫu ở hai định dạng khác nhau, nhưng không phải là thuận tiện nhất, bạn biết đấy, scripting (Có lẽ .val () sẽ trả về một mảng như vậy nếu được gọi trên một phần tử biểu mẫu?)
Luke Maurer

Câu trả lời:


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

});

Nhờ mẹo từ Simon_Weaver, đây là một cách khác bạn có thể làm bằng cách sử dụng serializeArray:

var values = {};
$.each($('#myForm').serializeArray(), function(i, field) {
    values[field.name] = field.value;
});

Lưu ý rằng đoạn mã này sẽ thất bại trên <select multiple>các yếu tố.

Dường như các đầu vào dạng HTML 5 mới không hoạt động serializeArraytrong phiên bản jQuery 1.3. Điều này hoạt động trong phiên bản 1.4+


1
Trong các phiên bản mới hơn của jQuery, câu trả lời của Simon_Weaver mạnh mẽ và dễ dàng hơn.
MightyE

1
@MightyE & @Simon_Weaver - bạn nói đúng, đây là một phương pháp mạnh mẽ hơn, nhưng nó không thực hiện chính xác những gì OP đang tìm kiếm. serializeArray trả về một mảng các đối tượng với các thuộc tính namevalue. Một giải pháp tốt hơn có thể là xử lý đầu ra từ serializeArray thành bất kỳ định dạng nào được yêu cầu.
nickf

1
Tôi nghĩ serializeArray () thực hiện chính xác những gì bạn muốn và ít mã hơn nhiều.
Slacy

1
Đối với tùy chọn đầu tiên, những gì về <select>các yếu tố? Tôi đã thử var $inputs = $('#new-ticket :input, :select');nhưng không được. Có ai biết cách thích hợp để làm điều này bởi vì tôi không nghĩ rằng tôi đang làm đúng.
Nathan

2
@Nathan, bạn nên sử dụng $("#new-ticket :input, #new-ticket :select"), hoặc thậm chí tốt hơn,$(":input, :select", "#new-ticket")
nickf

252

Đến bữa tiệc muộn về câu hỏi này, nhưng điều này thậm chí còn dễ dàng hơn:

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

});

8
Đây thực sự là câu trả lời tốt nhất. Nó thậm chí giữ bất kỳ định dạng mảng nào bạn có thể có cho các trường đầu vào của mình. Tôi không nghĩ câu trả lời của nickf thực sự sẽ giữ nguyên cấu trúc dữ liệu của bạn nếu nó được hình thành bằng cách sử dụng Zend_Form chẳng hạn, trong đó bạn có trường [cái gì đó] và trường [Something_else] làm tên của đầu vào ... ít nhất là Về mặt ngữ nghĩa, tôi không thể thấy nó sẽ như thế nào ...
msumme

43
Theo các tài liệu API jQuery, .serialize()( api.jquery.com/serialize ) đặt tất cả các thành phần của biểu mẫu trong một chuỗi sẵn sàng để nối vào URL trong chuỗi truy vấn, về cơ bản bắt chước yêu cầu biểu mẫu GET. Điều này sẽ không hoàn thành những gì câu trả lời của nickf hoàn thành.
Christopher Parker

Đây là câu trả lời tốt nhất!
Daniel Hunter

5
Đáng để biết: .serialize()cũng hoạt động trên chỉ các yếu tố hình thức. Vì vậy, $('form select').serialize()sẽ tuần tự hóa dữ liệu chỉ cho các lựa chọn.
chống độc

3
Thay vì lặp lại $('#myForm'), hãy sử dụng $ (cái này).
Jimothy

23

Các jquery.form Plugin có thể giúp đỡ với những gì người khác đang tìm kiếm kết thúc mà lên về câu hỏi này. Tôi không chắc liệu nó có trực tiếp làm những gì bạn muốn hay không.

Ngoài ra còn có chức năng serializeArray .


15

Đôi khi tôi thấy nhận được một lúc là hữu ích hơn. Vì thế, có cái này:

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

Áp dụng [0].valuecho điều này tức là $(...)[0].value;đã cho tôi giá trị của đầu vào trực tiếp, cảm ơn!
Pau Coma Ramirez

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

Biến phần tử sẽ chứa tất cả các yếu tố đầu vào, lựa chọn, textareas và các trường trong biểu mẫu.


9

Đây là một giải pháp khác, theo cách này bạn có thể tìm nạp tất cả dữ liệu về biểu mẫu và sử dụng nó trong một cuộc gọi bên máy chủ hoặc một cái gì đó.

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

Sau đó, bạn có thể sử dụng điều này với các cuộc gọi 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" );
       });
}

Hy vọng điều này có ích cho bất kỳ bạn nào :)


5

Có một vấn đề tương tự với một chút thay đổi và tôi nghĩ rằng tôi sẽ ném nó ra. Tôi có một hàm gọi lại có được biểu mẫu vì vậy tôi đã có một đối tượng biểu mẫu và không thể biến đổi dễ dàng trên đó $('form:input'). Thay vào đó tôi nghĩ ra:

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

Tình huống tương tự nhưng không giống nhau của nó, nhưng tôi thấy chủ đề này rất hữu ích và nghĩ rằng tôi đã kết thúc vấn đề này và hy vọng ai đó thấy nó hữu ích.


4

Liên kết? Không phải không có một số công việc, nhưng bạn có thể sử dụng các công cụ chọn chung:

var items = new Array();

$('#form_id:input').each(function (el) {
    items[el.name] = el;
});

trên thực tế, câu trả lời của Lance giữ nguyên mảng kết hợp cho các giá trị POST và lấy một dòng mã lớn.
msumme

Tại sao các mục là một mảng? bạn đang sử dụng nó như một đối tượng đơn giản. Không cần mảng ở đây
Jonathan Morales Vélez

3
@ JonathanMoralesVélez 2008 Oli không còn để bình luận. 2015 đồng ý với bạn.
Oli

4

jQuery serializeArraykhông bao gồm các trường bị vô hiệu hóa, vì vậy nếu bạn cũng cần những trường đó, hãy thử:

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


4

Đừng quên các hộp kiểm và nút radio -

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

Đoạn mã này sẽ hoạt động thay vì tên, email nhập tên trường mẫu của bạn

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

Có vẻ lạ rằng không ai đã nâng cấp hoặc đề xuất một giải pháp ngắn gọn để có được dữ liệu danh sách. Hầu như không có hình thức nào sẽ là đối tượng một chiều.

Tất nhiên, nhược điểm của giải pháp này là các đối tượng đơn lẻ của bạn sẽ phải được truy cập tại chỉ mục [0]. Nhưng IMO cách đó tốt hơn so với sử dụng một trong các giải pháp lập bản đồ hàng chục dòng.

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

Tôi đã có cùng một vấn đề và giải quyết nó theo một cách khác.

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

Nó trả về giá trị của tất cả các trường đầu vào. Bạn có thể thay đổi $(':input')để được cụ thể hơn.


2

Giải pháp tương tự như được đưa ra bởi nickf , nhưng với tên đầu vào mảng được đưa vào tài khoản, vd

<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

Nếu bạn cần nhận nhiều giá trị từ đầu vào và bạn đang sử dụng [] để xác định đầu vào có nhiều giá trị, bạn có thể sử dụng các giá trị sau:

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

Lấy cảm hứng từ câu trả lời của Lance RushingSimon_Weaver , đây là giải pháp yêu thích của tôi.

$('#myForm').submit( function( event ) {
    var values = $(this).serializeArray();
    // In my case, I need to fetch these data before custom actions
    event.preventDefault();
});

Đầu ra là một mảng các đối tượng, vd

[{name: "start-time", value: "11:01"}, {name: "end-time", value: "11:11"}]

Với mã dưới đây,

var inputs = {};
$.each(values, function(k, v){
    inputs[v.name]= v.value;
});

sản lượng cuối cùng của nó sẽ là

{"start-time":"11:01", "end-time":"11:01"}

1

Tôi đang sử dụng mã này mà không có mỗi vòng lặp:

$('.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

Tôi hy vọng điều này là hữu ích, cũng như dễ dàng nhất.

 $("#form").submit(function (e) { 
    e.preventDefault();
    input_values =  $(this).serializeArray();
  });

Điều kỳ lạ là nó không hoạt động trên phiên bản mới nhất của jquery 3.4.1
tái hiện

0

Khi tôi cần thực hiện cuộc gọi ajax với tất cả các trường của biểu mẫu, tôi gặp vấn đề với : bộ chọn đầu vào trả về tất cả các hộp kiểm cho dù chúng có được kiểm tra hay không. Tôi đã thêm một bộ chọn mới để chỉ lấy các phần tử biểu mẫu có thể gửi:

$.extend($.expr[':'],{
    submitable: function(a){
        if($(a).is(':checkbox:not(:checked)'))
        {
            return false;
        }
        else if($(a).is(':input'))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
});

sử dụng:

$('#form_id :submitable');

Tôi chưa thử nghiệm nó với nhiều hộp chọn nhưng nó hoạt động để có được tất cả các trường mẫu theo cách gửi tiêu chuẩn.

Tôi đã sử dụng điều này khi tùy chỉnh các tùy chọn sản phẩm trên trang web OpenCart để bao gồm các hộp kiểm và trường văn bản cũng như loại hộp chọn tiêu chuẩn.


0

serialize () là phương thức tốt nhất. @ Christopher Parker nói rằng anwser của Nickf hoàn thành nhiều hơn, tuy nhiên không tính đến việc biểu mẫu có thể chứa textarea và chọn các menu. Sẽ tốt hơn nhiều khi sử dụng serialize () và sau đó thao tác điều đó khi bạn cần. Dữ liệu từ serialize () có thể được sử dụng trong bài viết Ajax hoặc get, do đó không có vấn đề gì ở đó.


0

Hy vọng điều này sẽ giúp ai đó. :)

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

Tất cả các câu trả lời đều tốt, nhưng nếu có một lĩnh vực mà bạn muốn bỏ qua trong chức năng đó? Dễ dàng, cung cấp cho trường một thuộc tính, ví dụ ign_this:

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

Và trong Chức năng nối tiếp của bạn:

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

Đó là cách bạn bỏ qua một số lĩnh vực.


1
Đây là một nhận xét nhiều hơn là một câu trả lời vì nó không trả lời câu hỏi ban đầu.
Wai Ha Lee

Có lẽ bởi vì anh ta đã có hàng tấn câu trả lời? Đó là một bổ sung cho câu trả lời anh ấy nhận được.
Marcelo Rocha

Tôi sẽ thực hiện điều này với một tên lớp như bắt buộc nếu đầu vào phải được điền vào. Sau đó tôi có thể kiểm tra $('.mandatory');!$('.mandatory');
lharby

Thay đổi ignore_thisthành data-ignore-this="true"thay vì tạo các thuộc tính của riêng bạn mà không xác thực w3c
zanderwar

0

Hãy thử đoạn mã sau:

jQuery("#form").serializeArray().filter(obje => 
obje.value!='').map(aobj=>aobj.name+"="+aobj.value).join("&")

2
Hãy giải thích câu trả lời của bạn
Ling Vu

0

Đối với nhiều phần tử chọn ( <select multiple="multiple">), tôi đã sửa đổi giải pháp từ @Jason Norwood-Young để làm cho nó hoạt động.

Câu trả lời (như đã đăng) chỉ lấy giá trị từ phần tử đầu tiên được chọn, không phải tất cả chúng . Nó cũng không khởi tạo hoặc trả về data, lỗi trước đây gây ra lỗi JavaScript.

Đây là phiên bản mới:

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
}

Sử dụng:

_get_values($('#form'))

Lưu ý: Bạn chỉ cần đảm bảo rằng namelựa chọn của bạn đã được []thêm vào cuối của nó, ví dụ:

<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)
});
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.