Làm cách nào để sử dụng form.serialize của jQuery nhưng loại trừ các trường trống


107

Tôi có một biểu mẫu tìm kiếm với một số đầu vào văn bản và trình đơn thả xuống gửi qua GET. Tôi muốn có một url tìm kiếm sạch hơn bằng cách xóa các trường trống khỏi chuỗi truy vấn khi tìm kiếm được thực hiện.

var form = $("form");  
var serializedFormStr = form.serialize();  
// I'd like to remove inputs where value is '' or '.' here
window.location.href = '/search?' + serializedFormStr

Bất kỳ ý tưởng nào về cách tôi có thể thực hiện việc này bằng jQuery?

Câu trả lời:


167

Tôi đã xem qua các tài liệu jQuery và tôi nghĩ rằng chúng ta có thể làm điều này trong một dòng bằng cách sử dụng các bộ chọn :

$("#myForm :input[value!='']").serialize() // does the job!

Rõ ràng là #myForm nhận phần tử có id "myForm" nhưng điều tôi thấy ít rõ ràng hơn lúc đầu là ký tự khoảng trắng cần thiết giữa #myForm và: input vì nó là toán tử con .

: input khớp với tất cả các phần tử input, textarea, select và button.

[value! = ''] là một thuộc tính không phải là bộ lọc bình đẳng. Điều kỳ lạ (và hữu ích) là tất cả: các loại phần tử đầu vào đều có thuộc tính giá trị, thậm chí cả các hộp chọn và hộp kiểm, v.v.

Cuối cùng cũng để loại bỏ các đầu vào có giá trị là '.' (như đã đề cập trong câu hỏi):

$("#myForm :input[value!=''][value!='.']").serialize()

Trong trường hợp này, việc đặt cạnh nhau, tức là đặt hai bộ chọn thuộc tính bên cạnh nhau , ngụ ý một AND. Sử dụng dấu phẩy ngụ ý OR. Xin lỗi nếu điều đó là rõ ràng đối với những người CSS!


3
@Mvision, đó là bởi vì có một thiếu sót nhỏ nhưng đáng kể trong câu trả lời này. Đối với các bộ chọn CSS bình thường / thuần túy trong jQuery 1.8 trở về trước, [value]khớp với bất kỳ phần tử nào có thuộc tính value hiện tại , kể cả những phần tử có giá trị trống (hoặc không). Điều này là do một lỗi trong các phiên bản jQuery trước đó đã tạo ra sự không nhất quán giữa các biến thể nhất định của input[value]:input[value]. Lấy ví dụ <input value="foo"><input value=""><input value><input>,; lỗi được minh họa trong trò chơi này .
Noyo

4
Đối với tôi, điều này đã hoạt động: $form.find(":input[value]")- các trường trống không được chọn. Điều này không hoạt động: $form.find(":input[value!='']")- tất cả các trường đã được chọn. Hy vọng rằng sẽ giúp một ai đó. (jQuery 2.0.0)
Ryan Wheale

1
$form.find(":input[value]")cũng làm việc cho tôi (jQuery 1.11.0)
GSTAR

Chỉ hoạt động nếu valuethuộc tính đã ở đó. Nó đã không nhận ra nó bằng cách khác.
starcorn,

1
Trong một số trường hợp valueđược đặt theo chương trình, điều này sẽ không hoạt động ( valuesẽ không tồn tại dưới dạng thuộc tính HTML, nhưng sẽ là thuộc tính dữ liệu trên đầu vào). Trong những trường hợp, hãy thử này: $('#myForm :input').filter(function(i) { return ($(this).val().length != 0); }).serialize(). CHỈNH SỬA: Vừa thấy câu trả lời của Rich có cùng hiệu ứng.
Fateh Khalsa

54

Tôi không thể làm cho giải pháp của Tom hoạt động (?), Nhưng tôi có thể thực hiện việc này bằng cách sử dụng .filter()một hàm ngắn để xác định các trường trống. Tôi đang sử dụng jQuery 2.1.1.

var formData = $("#formid :input")
    .filter(function(index, element) {
        return $(element).val() != '';
    })
    .serialize();

2
Không thể nhận được câu trả lời đã được phê duyệt để hoạt động, nhưng điều này đã hoạt động tốt! Cảm ơn!
bfritz

Trả lời câu hỏi của riêng tôi: "Bộ :inputchọn về cơ bản chọn tất cả các điều khiển biểu mẫu. Chọn tất cả các yếu tố đầu vào, vùng văn bản, lựa chọn và nút." nguồn
Dinei

Phải, Tom bị hỏng . Của bạn còn trong sạch hơn cả nỗ lực của tôi trong trò đùa đó nữa. Up'd
Hashbrown

11

Điều này phù hợp với tôi:

data = $( "#my_form input").filter(function () {
        return !!this.value;
    }).serialize();

Chà, callback là cho phép các giá trị truyền trả về true, !!nhập lại bất cứ thứ gì thành bool, bạn có thể thử trong console. !!('test'), !!(5),!!(0)
Aiphee

2
Và thay vì inputbộ chọn, phải :inputbao gồm các lựa chọn, v.v.
Aiphee

Tôi đề nghị thay đổi này:data = $( "#my_form :input").filter(function () { return $(this).val() != ""; }).serialize();
Mahoor

9

Bạn có thể làm điều đó với regex ...

var orig = $('#myForm').serialize();
var withoutEmpties = orig.replace(/[^&]+=\.?(?:&|$)/g, '')

Các trường hợp kiểm tra:

orig = "a=&b=.&c=&d=.&e=";
new => ""

orig = "a=&b=bbb&c=.&d=ddd&e=";
new => "b=bbb&d=ddd&"  // dunno if that trailing & is a problem or not

.replace (/[^&]+=\.?(& | $) / g, '') bao gồm cả hai trường hợp. Nhưng tôi muốn thêm .replace (/ & $ /, '') để xóa dấu &
Tom Viner

15
Không có vấn đề gì mà regex không thể làm tệ hơn.
Michael Cook

3

Tôi đã sử dụng giải pháp trên nhưng đối với tôi những giải pháp đó không hoạt động. Vì vậy, tôi đã sử dụng mã sau

$('#searchform').submit(function(){

            var serializedData = $(this).serializeArray();
            var query_str = '';

            $.each(serializedData, function(i,data){
                if($.trim(data['value'])){
                    query_str += (query_str == '') ? '?' + data['name'] + '=' + data['value'] : '&' + data['name'] + '=' + data['value'];
                }
            });
            console.log(query_str);
            return false;
        });

Có thể hữu ích cho ai đó


1

Tôi sẽ xem xét mã nguồn cho jQuery. Ở phiên bản mới nhất dòng 3287.

Tôi có thể thêm vào một hàm "serialize2" và "serializeArray2". tất nhiên đặt tên cho họ một cái gì đó ma quái.

Hoặc cách tốt hơn là viết một cái gì đó để kéo các vars không sử dụng ra khỏi serializedFormStr. Một số regex tìm kiếm = & ở giữa chuỗi hoặc kết thúc bằng = Bất kỳ trình thuật sĩ regex nào xung quanh?

CẬP NHẬT: Tôi thích câu trả lời của rogeriopvl hơn (+1) ... đặc biệt là vì tôi không thể tìm thấy bất kỳ công cụ regex tốt nào ngay bây giờ.


1

Một giải pháp thay thế cho giải pháp của Rich :

$('#form').submit(function (e) {
  e.preventDefault();

  var query = $(this).serializeArray().filter(function (i) {
    return i.value;
  });

   window.location.href = $(this).attr('action') + (query ? '?' + $.param(query) : '');
});

Giải thích:

  • .submit()bám vào submitsự kiện của biểu mẫu
  • e.preventDefault() ngăn biểu mẫu gửi
  • .serializeArray() cung cấp cho chúng tôi một biểu diễn mảng của chuỗi truy vấn sẽ được gửi.
  • .filter() loại bỏ các giá trị sai (bao gồm cả trống) trong mảng đó.
  • $.param(query) tạo bản trình bày được tuần tự hóa và tuân theo URL của mảng đã cập nhật của chúng tôi
  • đặt một giá trị để window.location.hrefgửi yêu cầu

0

Trong coffeescript, hãy làm như sau:

serialized_form = $(_.filter($(context).find("form.params input"), (x) -> $(x).val() != '')).serialize()

-1

Bạn có thể muốn xem xét hàm jquery .each (), cho phép bạn lặp qua mọi phần tử của bộ chọn, vì vậy, bằng cách này bạn có thể kiểm tra từng trường đầu vào và xem nó có trống hay không và sau đó xóa nó khỏi biểu mẫu bằng cách sử dụng element.remove (). Sau đó, bạn có thể tuần tự hóa biểu mẫu.


1
Vấn đề duy nhất với điều đó là người dùng sẽ thấy trống từ các điều khiển biến mất ngay trước khi trang được gửi. Sẽ tốt hơn nếu đặt tên thành "" để serialize bỏ qua nó.
Tom Viner
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.