ช่องทำเครื่องหมายป้อนข้อมูลโพสต์เฉพาะในกรณีที่พวกเขากำลังทำเครื่องหมาย?


184

มันเป็นพฤติกรรมมาตรฐานหรือไม่สำหรับเบราว์เซอร์ที่จะส่งเฉพาะข้อมูลค่าอินพุตของช่องทำเครื่องหมายหากตรวจสอบเมื่อมีการส่งแบบฟอร์ม?

และหากไม่มีการระบุข้อมูลค่าใด ๆ ค่าเริ่มต้นจะเป็น "เปิด" เสมอหรือไม่

ถ้าสมมติว่าข้างต้นถูกต้องพฤติกรรมนี้สอดคล้องกันในทุกเบราว์เซอร์หรือไม่?

คำตอบ:


187

ใช่พฤติกรรมมาตรฐานคือค่าจะถูกส่งเฉพาะเมื่อทำเครื่องหมายที่ช่องทำเครื่องหมายเท่านั้น โดยทั่วไปแล้วนี่หมายความว่าคุณต้องมีวิธีการจดจำช่องทำเครื่องหมายที่คุณคาดหวังในฝั่งเซิร์ฟเวอร์เนื่องจากข้อมูลบางส่วนไม่ได้กลับมาจากแบบฟอร์ม

ค่าเริ่มต้นจะเป็น "เปิด" เสมอซึ่งควรสอดคล้องกับเบราว์เซอร์

สิ่งนี้ครอบคลุมอยู่ในคำแนะนำ W3C HTML 4 :

ช่องทำเครื่องหมาย (และปุ่มตัวเลือก) เป็นสวิตช์เปิด / ปิดที่ผู้ใช้สามารถสลับได้ สวิตช์เป็น "เปิด" เมื่อมีการตั้งค่าแอตทริบิวต์ที่ตรวจสอบขององค์ประกอบการควบคุม เมื่อมีการส่งแบบฟอร์มการควบคุมช่องทำเครื่องหมาย "กับ" เท่านั้นที่จะประสบความสำเร็จ


18
น่าเสียดายที่เป็นความเจ็บปวดอันเจ็บปวดกล่องกาเครื่องหมายที่ถูกเลือกเท่านั้นที่จะถูกส่งไปยังเซิร์ฟเวอร์ไม่ใช่ตัวเลือกที่ไม่ได้ตรวจสอบ หากคุณทราบล่วงหน้าว่ามีช่องทำเครื่องหมายใดอยู่บนหน้านั่นก็ไม่ใช่ปัญหาที่สคริปต์ฝั่งเซิร์ฟเวอร์จะจัดการได้ ปัญหาคือเมื่อคุณไม่ทราบล่วงหน้าว่า - ช่องทำเครื่องหมายที่สร้างขึ้นแบบไดนามิกในหน้าขึ้นอยู่กับตรรกะทางธุรกิจบางอย่าง จากนั้นคุณต้องสร้างกลวิธีและใช้ช่องป้อนข้อมูลที่ซ่อนไว้แบบขนานสำหรับช่องทำเครื่องหมายเหล่านั้นและเติมเต็มด้วย JavaScript
sbrbot

กุญแจสำคัญในการสร้างความสอดคล้องกับการตรวจสอบ "การควบคุมไม่ประสบความสำเร็จได้รับอนุญาต (ชนิดเช่น =" ช่องทำเครื่องหมาย ") คือการกำหนดรูปแบบการควบคุมเหล่านี้เป็นชั่วคราวเมื่อพวกเขาจะไม่ประสบความสำเร็จแบบไดนามิกเปลี่ยนเจลทำความสะอาดและตรวจสอบของคุณตาม..
แอนโธนี Rutledge

3
วิธีแก้ปัญหา: ใช้<select>กับสองตัวเลือกonและoff:-)
andy

83

ใน HTML แต่ละ<input />องค์ประกอบจะเชื่อมโยงกับชื่อและค่า (แต่ไม่ซ้ำกัน) คู่เดียว คู่นี้จะถูกส่งไปในคำขอต่อมา (ในกรณีนี้เนื้อหาคำขอ POST) ก็ต่อเมื่อ<input />"สำเร็จ"

ดังนั้นหากคุณมีปัจจัยการผลิตเหล่านี้ในของคุณ <form> DOM :

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

จะสร้างคู่ชื่อ + ค่าเหล่านี้ซึ่งจะถูกส่งไปยังเซิร์ฟเวอร์:

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

สังเกตว่า:

  • twoและsixถูกยกเว้นเพราะพวกเขามีdisabledชุดแอตทริบิวต์
  • three ถูกส่งสองครั้งเนื่องจากมีอินพุตที่ใช้ได้สองรายการที่มีชื่อเดียวกัน
  • four ไม่ได้ส่งเพราะมันเป็น checkboxที่ไม่checked
  • sixไม่ได้ส่งแม้ว่าจะเป็นcheckedเพราะdisabledแอตทริบิวต์มีลำดับความสำคัญสูงกว่า
  • sevenไม่ได้name=""ส่งแอตทริบิวต์ดังนั้นจึงไม่ได้ส่ง

ด้วยความเคารพต่อคำถามของคุณ: คุณจะเห็นว่าช่องทำเครื่องหมายที่ไม่ได้ตรวจสอบจะไม่มีการส่งคู่ + ชื่อ + ค่าไปยังเซิร์ฟเวอร์ - แต่อินพุตอื่นที่ใช้ชื่อเดียวกันจะถูกส่งไปด้วย

เฟรมเวิร์กเช่น ASP.NET MVC ทำงานได้โดยจับคู่ทุกcheckboxอินพุตกับhiddenอินพุตใน HTML ที่เรนเดอร์เช่น:

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

วาทกรรม:

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

หากผู้ใช้ไม่ได้ทำเครื่องหมายที่ช่องทำเครื่องหมายข้อมูลต่อไปนี้จะถูกส่งไปยังเซิร์ฟเวอร์:

SomeBooleanProperty=false

หากผู้ใช้ทำเครื่องหมายที่ช่องทำเครื่องหมายทั้งคู่จะถูกส่ง:

SomeBooleanProperty=true
SomeBooleanProperty=false

แต่เซิร์ฟเวอร์จะเพิกเฉยต่อ=falseเวอร์ชันเพราะเห็น=trueเวอร์ชั่นแล้วดังนั้นหากไม่เห็น=trueสามารถระบุได้ว่ามีการแสดงช่องทำเครื่องหมายและผู้ใช้ไม่ได้ตรวจสอบ - ซึ่งต่างจากSomeBooleanPropertyอินพุตที่ไม่ได้แสดงผลเลย


น่าสังเกตว่าถ้าคุณมีหลายฟิลด์เช่นกับกล่องข้อความที่ซ่อนพิเศษส่วนแบ็คเอนด์จะได้รับอาร์เรย์ของค่า
Salami

มันจะได้รับอาร์เรย์เฉพาะเมื่อคุณใช้[]ที่ส่วนท้ายของชื่ออินพุตพฤติกรรมเริ่มต้นคือการส่งองค์ประกอบสุดท้ายที่มีชื่อนั้นเท่านั้นตราบใดที่อินพุตที่ซ่อนอยู่อยู่ด้านหน้าช่องทำเครื่องหมายมันจะทำงาน
beeglebug

ด้วยการมีสองฟิลด์ที่มีชื่อเหมือนกัน (ซ่อนฟิลด์ + ช่องทำเครื่องหมาย) และตรวจสอบช่องทำเครื่องหมายค่าโพสต์เป็นสตริงที่คั่นด้วยเครื่องหมายจุลภาคของค่าคือ บางอย่างเช่น "0,1"
ʞᴉɯ

1
@beeglebug สิ่งที่คุณอธิบายว่า PHP จัดการชื่อและค่าได้อย่างไร[]คำต่อท้ายไม่ได้เป็นส่วนหนึ่งของข้อกำหนด HTML และเบราว์เซอร์ไม่ได้จัดการเป็นพิเศษ หากไม่มี[]PHP จะอนุญาตการเข้าถึงค่าเดียว (ค่าสุดท้าย) แทนค่าทั้งหมด
ได

1
การใช้คุณสมบัติที่ซ่อนอยู่ก่อนที่ช่องทำเครื่องหมายจะทำงานสำหรับฉันในเบราว์เซอร์ทั้งหมดที่ฉันได้ทดสอบโดยใช้ GET และ POST ด้วย PHP เมื่อฉันวางไว้หลังช่องทำเครื่องหมายควบคุมมันจะแสดงผลลัพธ์เป็นเท็จเสมอ
adrianwadey

16

หากไม่ได้ทำเครื่องหมายที่ช่องทำเครื่องหมายจะไม่ส่งผลต่อข้อมูลที่ส่งมาในการส่งแบบฟอร์ม

HTML5 ส่วน4.10.22.4 การสร้างชุดข้อมูลแบบฟอร์มอธิบายวิธีการสร้างข้อมูลในแบบฟอร์ม:

หากตรงตามเงื่อนไขใด ๆ ต่อไปนี้ให้ข้ามขั้นตอนย่อยเหล่านี้สำหรับองค์ประกอบนี้: [... ]

องค์ประกอบเขตข้อมูลเป็นองค์ประกอบการป้อนข้อมูลที่มีแอตทริบิวต์ประเภทอยู่ในสถานะช่องทำเครื่องหมายและการตรวจสอบที่เป็นเท็จ

จากนั้นค่าเริ่มต้นonจะถูกระบุหากvalueไม่มี:

มิฉะนั้นหากองค์ประกอบฟิลด์เป็นองค์ประกอบอินพุตที่มีแอตทริบิวต์ประเภทอยู่ในสถานะช่องทำเครื่องหมายหรือสถานะปุ่มวิทยุจากนั้นเรียกใช้ขั้นตอนย่อยซ้อนกันต่อไปนี้:

หากองค์ประกอบของเขตข้อมูลมีแอตทริบิวต์ค่าที่ระบุแล้วให้ค่าเป็นค่าของคุณลักษณะนั้น มิฉะนั้นให้ค่าเป็นสตริง "on"

ดังนั้นช่องทำเครื่องหมายที่ไม่ได้ทำเครื่องหมายจะถูกข้ามในระหว่างการสร้างข้อมูลแบบฟอร์ม

ลักษณะการทำงานคล้าย ๆ กันคือต้องอยู่ภายใต้HTML4 มีความสมเหตุสมผลที่จะคาดหวังพฤติกรรมนี้จากเบราว์เซอร์ที่เข้ากันได้ทั้งหมด


10

ช่องทำเครื่องหมายกำลังโพสต์ค่า 'เปิด' ถ้าและเฉพาะถ้าช่องทำเครื่องหมายมีการตรวจสอบ อินสแตนซ์ของการจับค่าช่องทำเครื่องหมายคุณสามารถใช้อินพุตที่ซ่อนอยู่

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

มันเป็นพฤติกรรมมาตรฐานหรือไม่สำหรับเบราว์เซอร์ที่จะส่งเฉพาะข้อมูลค่าอินพุตของช่องทำเครื่องหมายหากตรวจสอบเมื่อมีการส่งแบบฟอร์ม?

ใช่เพราะมิฉะนั้นจะไม่มีวิธีที่ชัดเจนในการพิจารณาว่ามีการทำเครื่องหมายที่ช่องทำเครื่องหมายจริงหรือไม่ (ถ้าเปลี่ยนค่ากรณีอาจมีอยู่เมื่อค่าที่คุณต้องการถ้ามีการตรวจสอบจะเป็นเช่นเดียวกับที่เป็นจริง เปลี่ยนเป็น)

และหากไม่มีการระบุข้อมูลค่าใด ๆ ค่าเริ่มต้นจะเป็น "เปิด" เสมอหรือไม่

คำตอบอื่น ๆ ยืนยันว่า "เปิด" เป็นค่าเริ่มต้น อย่างไรก็ตามหากคุณไม่สนใจคุณค่าเพียงใช้:

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

7

จากสเป็ค HTML 4 ซึ่งควรสอดคล้องกันในเบราว์เซอร์เกือบทั้งหมด:

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

ช่องทำเครื่องหมาย (และปุ่มตัวเลือก) เป็นสวิตช์เปิด / ปิดที่ผู้ใช้สามารถสลับได้ สวิตช์เป็น "เปิด" เมื่อมีการตั้งค่าแอตทริบิวต์ที่ตรวจสอบขององค์ประกอบการควบคุม เมื่อมีการส่งแบบฟอร์มการควบคุมช่องทำเครื่องหมาย "กับ" เท่านั้นที่จะประสบความสำเร็จ

ประสบความสำเร็จถูกกำหนดดังนี้:

การควบคุมที่ประสบความสำเร็จคือ "ถูกต้อง" สำหรับการส่ง การควบคุมที่สำเร็จทุกครั้งจะมีชื่อการควบคุมจับคู่กับค่าปัจจุบันเป็นส่วนหนึ่งของชุดข้อมูลแบบฟอร์มที่ส่ง การควบคุมที่สำเร็จจะต้องกำหนดไว้ในองค์ประกอบ FORM และจะต้องมีชื่อควบคุม


5

อินพุต type = "hidden" name = "is_main" value = "0"

อินพุต type = "checkbox" name = "is_main" value = "1"

เพื่อให้คุณสามารถควบคุมสิ่งนี้เหมือนที่ฉันทำในแอปพลิเคชัน ถ้ามันตรวจสอบแล้วส่งค่า 1 มิฉะนั้น 0


3

ไม่มีคำตอบใดที่ทำให้ฉันพอใจ ฉันพบทางออกที่ดีที่สุดคือการรวมอินพุตที่ซ่อนไว้ก่อนหน้าแต่ละช่องทำเครื่องหมายด้วยชื่อเดียวกัน

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

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

จากนั้นในฝั่งเซิร์ฟเวอร์โดยใช้อัลกอริทึมเล็ก ๆ น้อย ๆ ที่คุณจะได้รับมากกว่าที่ควรจะเป็น HTML

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

นี่จะเป็นข้อมูลดิบ

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

และฟังก์ชั่นจะกลับมา

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

1

ฉันมีหน้า (ฟอร์ม) ที่สร้างช่องทำเครื่องหมายแบบไดนามิกดังนั้นคำตอบเหล่านี้เป็นความช่วยเหลือที่ดีมาก โซลูชันของฉันคล้ายกับที่นี่มาก แต่ฉันอดคิดไม่ได้ว่าจะนำไปใช้งานได้ง่ายขึ้น

ครั้งแรกที่ฉันใส่กล่องใส่ที่ซ่อนอยู่ในแนวเดียวกับช่องทำเครื่องหมายของฉันคือ

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

ตอนนี้ถ้าทั้งหมด checkboxesยกเลิกการเลือกทั้งหมดค่าที่ส่งคืนโดยฟิลด์ที่ซ่อนจะถูกปิด

ตัวอย่างเช่นที่นี่พร้อมช่องทำเครื่องหมายห้าช่องที่แทรกแบบไดนามิกจะสร้างPOSTSค่าต่อไปนี้:

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

นี้แสดงให้เห็นว่ามีเพียงช่องทำเครื่องหมายที่ 3 และ 4 มี หรือ onchecked

ในสาระสำคัญเขตข้อมูลดัมมี่หรือซ่อนอยู่เพียงบ่งบอกว่าทุกอย่างปิดเว้นแต่ว่ามี"ใน"ด้านล่างดัชนีปิดซึ่งจะช่วยให้คุณดัชนีที่คุณต้องการโดยไม่ต้องมีบรรทัดด้านข้างของลูกค้ารหัสเดียว

.


0

เช่นเดียวกับตัวแปร ASP.NET ยกเว้นใส่อินพุตที่ซ่อนไว้ด้วยชื่อเดียวกันหน้าช่องทำเครื่องหมายจริง (ของชื่อเดียวกัน) จะส่งเฉพาะค่าสุดท้าย วิธีนี้หากทำเครื่องหมายในช่องแล้วชื่อและค่าของมันจะเป็น "เปิด" ในขณะที่หากไม่ได้ทำเครื่องหมายไว้ชื่อของอินพุตที่ซ่อนที่เกี่ยวข้องและค่าใด ๆ ที่คุณอาจต้องการให้มันถูกส่ง ในที่สุดคุณจะได้รับอาร์เรย์ $ _POST เพื่ออ่านด้วยองค์ประกอบที่ตรวจสอบและไม่ได้ตรวจสอบทั้งหมดในนั้นค่า "on" และ "false" ไม่มีคีย์ที่ซ้ำกัน ง่ายต่อการประมวลผลใน PHP


0

มีปัญหาเดียวกันกับช่องทำเครื่องหมายที่ไม่ได้ทำเครื่องหมายที่จะไม่ถูกส่งในแบบฟอร์มการส่งฉันออกมาพร้อมกับวิธีแก้ปัญหาอื่นนอกเหนือจากการทำรายการช่องทำเครื่องหมาย

รับช่องทำเครื่องหมายที่ไม่ได้ทำเครื่องหมายทั้งหมดด้วย

var checkboxQueryString;

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

-2

ฉันแก้ไขปัญหาด้วยรหัสนี้:

แบบฟอร์ม HTML

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

และฟังก์ชั่นจาวาสคริปต์โดยเปลี่ยนรูปแบบค่าช่องทำเครื่องหมาย:

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

และเซิร์ฟเวอร์จะตรวจสอบว่าการโพสต์ข้อมูลเป็น "เปิด" หรือ "ปิด" ฉันใช้ playframework java

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