Do hộp kiểm đầu vào chỉ đăng dữ liệu nếu chúng được chọn?


183

Đây có phải là hành vi tiêu chuẩn cho các trình duyệt chỉ gửi dữ liệu giá trị đầu vào hộp kiểm nếu nó được kiểm tra khi gửi biểu mẫu không?

Và nếu không có dữ liệu giá trị nào được cung cấp, giá trị mặc định luôn luôn "bật"?

Giả sử những điều trên là chính xác, đây có phải là hành vi nhất quán trên tất cả các trình duyệt không?

Câu trả lời:


186

Có, hành vi tiêu chuẩn là giá trị chỉ được gửi nếu hộp kiểm được chọn. Điều này thường có nghĩa là bạn cần có một cách để nhớ những hộp kiểm bạn đang mong đợi ở phía máy chủ vì không phải tất cả dữ liệu đều quay trở lại từ biểu mẫu.

Giá trị mặc định luôn là "bật", giá trị này phải nhất quán trên các trình duyệt.

Điều này được đề cập trong đề xuất W3C HTML 4 :

Các hộp kiểm (và các nút radio) là công tắc bật / tắt có thể được bật bởi người dùng. Công tắc được "bật" khi thuộc tính đã kiểm tra của phần tử điều khiển được đặt. Khi một biểu mẫu được gửi, chỉ các điều khiển hộp kiểm "bật" có thể thành công.


18
Thật không may, điều đó thật đau đớn, chỉ những hộp kiểm tra được gửi đến máy chủ chứ không phải những hộp kiểm không được chọn. Nếu bạn biết trước các hộp kiểm trên trang nào thì việc quản lý chúng không phải là vấn đề. Vấn đề là khi bạn không biết trước - các hộp kiểm được tạo động trên trang tùy thuộc vào một số logic nghiệp vụ. Sau đó, bạn phải thực hiện các thủ thuật và sử dụng các trường nhập ẩn song song cho các hộp kiểm đó và hoàn thành chúng bằng JavaScript.
sbrbot

Chìa khóa để tạo ra một validator phù hợp với "điều khiển không thành công cho phép (loại tức là =" checkbox ") là để chỉ những hình thức kiểm soát như thoáng qua Khi họ không thành công, tự động thay đổi khử trùng và validator của bạn cho phù hợp..
Anthony Rutledge

3
Giải pháp thay thế: sử dụng <select>với hai tùy chọn onoff:-)
andy

82

Trong HTML, mỗi <input />phần tử được liên kết với một cặp giá trị và tên duy nhất (nhưng không phải là duy nhất). Cặp này được gửi trong yêu cầu tiếp theo (trong trường hợp này là phần thân yêu cầu POST) chỉ khi <input />"thành công".

Vì vậy, nếu bạn có những đầu vào này trong <form>DOM của bạn :

<input type="text"     name="one"   value="foo"                        />
<input type="text"     name="two"   value="bar"    disabled="disabled" />
<input type="text"     name="three" value="first"                      />
<input type="text"     name="three" value="second"                     />

<input type="checkbox" name="four"  value="baz"                        />
<input type="checkbox" name="five"  value="baz"    checked="checked"   />
<input type="checkbox" name="six"   value="qux"    checked="checked" disabled="disabled" />
<input type="checkbox" name=""      value="seven"  checked="checked"   />

<input type="radio"    name="eight" value="corge"                      />
<input type="radio"    name="eight" value="grault" checked="checked"   />
<input type="radio"    name="eight" value="garply"                     />

Sẽ tạo các cặp tên + giá trị này sẽ được gửi đến máy chủ:

one=foo
three=first
three=second
five=baz
eight=grault

Thông báo rằng:

  • twosixbị loại vì họ có tập disabledthuộc tính.
  • three đã được gửi hai lần vì nó có hai đầu vào hợp lệ có cùng tên.
  • fourđã không được gửi bởi vì nó checkboxkhông phải làchecked
  • sixđã không được gửi mặc dù là checkeddisabledthuộc tính có quyền ưu tiên cao hơn.
  • sevenkhông có name=""thuộc tính được gửi, vì vậy nó không được gửi.

Đối với câu hỏi của bạn: bạn có thể thấy rằng một hộp kiểm tra không được kiểm tra do đó sẽ không có cặp tên + giá trị được gửi đến máy chủ - nhưng các đầu vào khác có cùng tên sẽ được gửi cùng với nó.

Các khung như ASP.NET MVC giải quyết vấn đề này bằng cách (lén lút) ghép nối mọi checkboxđầu vào với hiddenđầu vào trong HTML được kết xuất, như vậy:

@Html.CheckBoxFor( m => m.SomeBooleanProperty )

Riders:

<input type="checkbox" name="SomeBooleanProperty" value="true" />
<input type="hidden"   name="SomeBooleanProperty" value="false" />

Nếu người dùng không chọn hộp kiểm, thì phần sau sẽ được gửi đến máy chủ:

SomeBooleanProperty=false

Nếu người dùng kiểm tra hộp kiểm, thì cả hai sẽ được gửi:

SomeBooleanProperty=true
SomeBooleanProperty=false

Nhưng máy chủ sẽ bỏ qua =falsephiên bản vì nó nhìn thấy =truephiên bản, và vì vậy nếu không thấy =truenó có thể xác định rằng hộp kiểm được hiển thị và người dùng không kiểm tra nó - trái ngược với các SomeBooleanPropertyđầu vào không được hiển thị.


Đáng lưu ý rằng nếu bạn có nhiều trường, chẳng hạn như với hộp văn bản ẩn thêm, thì phần phụ trợ sẽ nhận được một mảng các giá trị.
Salami

Nó chỉ nhận được một mảng nếu bạn sử dụng []ở cuối tên đầu vào, hành vi mặc định là chỉ gửi phần tử cuối cùng với tên đó, miễn là đầu vào ẩn trước hộp kiểm, nó sẽ hoạt động.
bọ cánh cứng

Bằng cách có hai trường có cùng tên (trường ẩn + trường hộp kiểm) và kiểm tra hộp kiểm, giá trị bài đăng là một chuỗi được phân tách bằng dấu phẩy của các giá trị, nghĩa là. một cái gì đó như "0,1"
ʞᴉɯ

1
@beegleorms Những gì bạn mô tả là cách PHP xử lý tên và giá trị, []hậu tố không phải là một phần của đặc tả HTML và các trình duyệt không xử lý nó đặc biệt. Không có []PHP sẽ chỉ cho phép truy cập vào một giá trị duy nhất (giá trị cuối cùng) thay vì tất cả các giá trị.
Đại

1
Sử dụng thuộc tính ẩn trước khi hộp kiểm hoạt động với tôi trong tất cả các trình duyệt tôi đã kiểm tra bằng GET và POST với PHP. Khi tôi đặt nó sau khi kiểm soát hộp kiểm, nó luôn hiển thị kết quả sai.
adrianwadey

16

Nếu hộp kiểm không được chọn thì nó không đóng góp vào dữ liệu được gửi khi gửi biểu mẫu.

Phần HTML5 4.10.22.4 Xây dựng bộ dữ liệu biểu mẫu mô tả cách xây dựng dữ liệu biểu mẫu:

Nếu bất kỳ điều kiện nào sau đây được đáp ứng, thì hãy bỏ qua các bước phụ cho phần tử này: [...]

Phần tử trường là một phần tử đầu vào có thuộc tính loại ở trạng thái Hộp kiểm và độ kiểm tra của nó là sai.

và sau đó giá trị mặc định onđược chỉ định nếu valuebị thiếu:

Mặt khác, nếu phần tử trường là một phần tử đầu vào có thuộc tính loại ở trạng thái Hộp kiểm hoặc trạng thái Nút Radio, thì hãy chạy các bước phụ được lồng thêm này:

Nếu phần tử trường có thuộc tính giá trị được chỉ định, thì hãy để giá trị là giá trị của thuộc tính đó; mặt khác, hãy để giá trị là chuỗi "bật".

Do đó, các hộp kiểm không được kiểm tra được bỏ qua trong quá trình xây dựng dữ liệu biểu mẫu.

Hành vi tương tự được yêu cầu trong HTML4 . Thật hợp lý khi mong đợi hành vi này từ tất cả các trình duyệt tuân thủ.


10

Các hộp kiểm đang đăng giá trị 'trên' khi và chỉ khi hộp kiểm được chọn. Ngay lập tức bắt giá trị hộp kiểm, bạn có thể sử dụng các đầu vào ẩn

JS :

var chk = $('input[type="checkbox"]');
    chk.each(function(){
        var v = $(this).attr('checked') == 'checked'?1:0;
        $(this).after('<input type="hidden" name="'+$(this).attr('rel')+'" value="'+v+'" />');
    });

chk.change(function(){ 
        var v = $(this).is(':checked')?1:0;
        $(this).next('input[type="hidden"]').val(v);
    });

HTML :

<label>Active</label><input rel="active" type="checkbox" />

8

Đây có phải là hành vi tiêu chuẩn cho các trình duyệt chỉ gửi dữ liệu giá trị đầu vào hộp kiểm nếu nó được kiểm tra khi gửi biểu mẫu không?

Có, bởi vì nếu không, sẽ không có cách xác định chắc chắn liệu hộp kiểm có thực sự được kiểm tra hay không (nếu nó thay đổi giá trị, trường hợp có thể tồn tại khi giá trị mong muốn của bạn nếu nó được kiểm tra sẽ giống như hộp kiểm đổi sang).

Và nếu không có dữ liệu giá trị nào được cung cấp, giá trị mặc định luôn luôn "bật"?

Các câu trả lời khác xác nhận rằng "bật" là mặc định. Tuy nhiên, nếu bạn không quan tâm đến giá trị, chỉ cần sử dụng:

if (isset($_POST['the_checkbox'])){
    // name="the_checkbox" is checked
}

7

Từ thông số kỹ thuật HTML 4, cần nhất quán trên hầu hết các trình duyệt:

http://www.w3.org/TR/html401/interact/forms.html#checkbox

Các hộp kiểm (và các nút radio) là công tắc bật / tắt có thể được bật bởi người dùng. Công tắc được "bật" khi thuộc tính đã kiểm tra của phần tử điều khiển được đặt. Khi một biểu mẫu được gửi, chỉ các điều khiển hộp kiểm "bật" có thể thành công.

Thành công được định nghĩa như sau:

Một kiểm soát thành công là "hợp lệ" để nộp. Mọi điều khiển thành công đều có tên điều khiển được ghép với giá trị hiện tại của nó như là một phần của tập dữ liệu biểu mẫu đã gửi. Điều khiển thành công phải được xác định trong phần tử FORM và phải có tên điều khiển.


5

kiểu nhập = "ẩn" tên = "is_main" value = "0"

kiểu nhập = "hộp kiểm" name = "is_main" value = "1"

vì vậy bạn có thể kiểm soát như thế này như tôi đã làm trong ứng dụng. nếu nó kiểm tra thì gửi giá trị 1 nếu không 0


3

Không có câu trả lời trên làm tôi hài lòng. Tôi tìm thấy giải pháp tốt nhất là bao gồm một đầu vào ẩn trước mỗi đầu vào hộp kiểm có cùng tên.

<input type="hidden" name="foo[]" value="off"/>

<input type="checkbox" name="foo[]"/>

Sau đó, về phía máy chủ, sử dụng một thuật toán nhỏ, bạn có thể nhận được một cái gì đó giống như HTML sẽ cung cấp.

function checkboxHack(array $checkbox_input): array
{
    $foo = [];
    foreach($checkbox_input as $value) {
        if($value === 'on') {
            array_pop($foo);
        }
        $foo[] = $value;
    }
    return $foo;
}

Đây sẽ là đầu vào thô

array (
    0 => 'off',
    1 => 'on',
    2 => 'off',
    3 => 'off',
    4 => 'on',
    5 => 'off',
    6 => 'on',
),

Và chức năng sẽ trở lại

array (
    0 => 'on',
    1 => 'off',
    2 => 'on',
    3 => 'on',
)  

1

Tôi có một trang (biểu mẫu) tự động tạo hộp kiểm để những câu trả lời này rất hữu ích. Giải pháp của tôi rất giống với nhiều người ở đây nhưng tôi không thể nghĩ rằng việc thực hiện sẽ dễ dàng hơn.

Đầu tiên tôi đặt một hộp nhập ẩn phù hợp với hộp kiểm của mình, nghĩa là

 <td><input class = "chkhide" type="hidden" name="delete_milestone[]" value="off"/><input type="checkbox" name="delete_milestone[]"   class="chk_milestone" ></td>

Bây giờ nếu tất cả các checkboxeskhông được chọn thì các giá trị được trả về bởi trường ẩn sẽ bị tắt.

Ví dụ: ở đây với năm hộp kiểm được chèn động, mẫu có POSTScác giá trị sau:

  'delete_milestone' => 
array (size=7)
  0 => string 'off' (length=3)
  1 => string 'off' (length=3)
  2 => string 'off' (length=3)
  3 => string 'on' (length=2)
  4 => string 'off' (length=3)
  5 => string 'on' (length=2)
  6 => string 'off' (length=3)

Điều này cho thấy chỉ có hộp kiểm thứ 3 và thứ 4 là onhoặc checked.

Về bản chất, trường đầu vào giả hoặc ẩn chỉ cho biết rằng mọi thứ đều tắt trừ khi có "bật" bên dưới chỉ mục tắt, sau đó cung cấp cho bạn chỉ mục bạn cần mà không cần một dòng mã phía máy khách.

.


0

Giống như biến thể ASP.NET, ngoại trừ đặt đầu vào ẩn có cùng tên trước hộp kiểm thực tế (cùng tên). Chỉ các giá trị cuối cùng sẽ được gửi. Bằng cách này, nếu một hộp được chọn thì tên và giá trị "bật" của nó sẽ được gửi, trong khi nếu nó không được chọn thì tên của đầu vào ẩn tương ứng và bất kỳ giá trị nào bạn muốn cung cấp sẽ được gửi. Cuối cùng, bạn sẽ nhận được mảng $ _POST để đọc, với tất cả các yếu tố được kiểm tra và không được kiểm tra trong đó, các giá trị "bật" và "sai", không có khóa trùng lặp. Dễ dàng xử lý trong PHP.


0

Có cùng một vấn đề với các hộp kiểm không được kiểm tra sẽ không được gửi trên các biểu mẫu gửi, tôi đã đưa ra một giải pháp khác ngoài việc phản chiếu các mục hộp kiểm.

Bắt tất cả các hộp kiểm không được kiểm tra với

var checkboxQueryString;

$form.find ("input[type=\"checkbox\"]:not( \":checked\")" ).each(function( i, e ) {
  checkboxQueryString += "&" + $( e ).attr( "name" ) + "=N"
});

-2

Tôi đã giải quyết vấn đề với mã này:

Biểu mẫu HTML

<input type="checkbox" id="is-business" name="is-business" value="off" onclick="changeValueCheckbox(this)" >
<label for="is-business">Soy empresa</label>

và hàm javascript bằng cách thay đổi biểu mẫu giá trị hộp kiểm:

//change value of checkbox element
function changeValueCheckbox(element){
   if(element.checked){
    element.value='on';
  }else{
    element.value='off';
  }
}

và máy chủ kiểm tra xem bài đăng dữ liệu là "bật" hay "tắt". Tôi đã sử dụng java playframework

        final Map<String, String[]> data = request().body().asFormUrlEncoded();

        if (data.get("is-business")[0].equals('on')) {
            login.setType(new MasterValue(Login.BUSINESS_TYPE));
        } else {
            login.setType(new MasterValue(Login.USER_TYPE));
        }
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.