POST ไม่เลือกช่องทำเครื่องหมาย HTML


303

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

มีวิธีใดที่จะทำให้รูปแบบ POST ช่องทำเครื่องหมายที่ไม่ได้มีการตรวจสอบมากกว่าคนที่ได้รับการตรวจสอบ?

คำตอบ:


217

เพิ่มอินพุตที่ซ่อนอยู่สำหรับช่องทำเครื่องหมายด้วย ID อื่น:

<input id='testName' type='checkbox' value='Yes' name='testName'>
<input id='testNameHidden' type='hidden' value='No' name='testName'>

ก่อนส่งแบบฟอร์มให้ปิดการใช้งานอินพุตที่ซ่อนอยู่ตามเงื่อนไขที่เลือก:

if(document.getElementById("testName").checked) {
    document.getElementById('testNameHidden').disabled = true;
}

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

12
gamov, คุณเข้าใจผิด, ป้ายกำกับจะถูกแนบกับอินพุตตามคุณลักษณะ id ไม่ใช่แอตทริบิวต์ชื่ออินพุต
Justin Emery

14
ผู้ออกแบบยากที่จะเชื่อเช่นนี้ ทำไมไม่ส่งเขตข้อมูลอินพุตทั้งหมดที่มีค่าเริ่มต้นบางอย่างสำหรับผู้ที่ไม่ได้ตรวจสอบ :( มันจะเป็นทางออกที่ชัดเจนมากขึ้นแล้วต้องดำเนินการบางอย่างที่ซ่อน "แฮ็ค" เขตข้อมูลมันจะต้องมีความชัดเจนว่ามันเป็นสิ่งจำเป็น ดูล่วงหน้าว่า
Srneczek

34
นี่รู้สึกแฮ็คมาก
EralpB

65
ฉันเป็นคนเดียวที่คิดว่าองค์ประกอบพื้นฐานของการออกแบบcheckboxนั้นแย่มาก? พวกมันคือการควบคุมไบนารีพวกเขาควรส่งค่าไบนารี
alexw

474

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

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>

3
ตอนนี้ฉันอ่านคำถามอีกครั้งดูเหมือนว่านี่ไม่ใช่สิ่งที่คุณต้องการจริงๆ อย่างไรก็ตามฉันถึงคำถามนี้เมื่อฉันพยายามหาคำตอบนี้ดังนั้นอาจเป็นประโยชน์กับคนอื่น
Sam

2
.NET แตกต่างกันแทนที่จะดูstackoverflow.com/questions/7600817/…
KCD

121
ควรสังเกตว่าถ้าคุณทำเครื่องหมายในช่องเบราว์เซอร์จะส่งทั้งค่าที่ซ่อนอยู่และช่องทำเครื่องหมาย วิธีนี้จะขึ้นอยู่กับการจัดการตัวแปร post ของเซิร์ฟเวอร์ด้วยค่า 2 ค่านี้ หากใช้เพียงค่าสุดท้าย (เช่น PHP) รหัสของคุณจะทำงานตามที่คาดไว้ อย่างไรก็ตามเซิร์ฟเวอร์บางตัวจัดการเรื่องนี้แตกต่างกันบางคนเลือกค่าแรกในขณะที่คนอื่นวางค่าทั้งสองไว้ในรายการ / อาร์เรย์
Michael Ekoka

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

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

75

ฉันแก้ไขได้โดยใช้วานิลลา JavaScript:

<input type="hidden" name="checkboxName" value="0"><input type="checkbox" onclick="this.previousSibling.value=1-this.previousSibling.value">

ระวังอย่าให้มีช่องว่างหรือ linebreaks ระหว่างอิลิเมนต์ทั้งสองนี้!

คุณสามารถใช้this.previousSibling.previousSiblingเพื่อรับองค์ประกอบ "ส่วนบน"

ด้วย PHP คุณสามารถตรวจสอบฟิลด์ที่ซ่อนชื่อเป็น 0 (ไม่ได้ตั้งค่า) หรือ 1 (ชุด)


ทำไมคุณไม่มีช่องว่างหรือตัวแบ่งบรรทัดระหว่างองค์ประกอบทั้งสอง
Michael Potter

@MichaelPotter: this.previousSibling จะได้รับช่องว่างเป็นพี่น้องดังนั้นจึงไม่ทำงาน
Marcel Ennix

4
โอ้นี่เป็นสิ่งที่สมบูรณ์แบบ! มันแก้ปัญหาของการโพสต์หลายชุดเขตข้อมูลที่มีชื่อซ้ำกันในนั้นไม่มีวิธีการแก้ปัญหาอื่นทำ ใช้วิธีของ Marcel เขตข้อมูลที่คุณโพสต์จะมีอาร์เรย์ความยาวเท่ากัน ดังนั้นสถานการณ์นี้: <fieldset name='fs1'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset> <fieldset name='fs2'> <input type="text" name="somefield[]"> <input type="checkbox" name="live[]"> </fieldset>* สมมติว่ามีบรรทัดใหม่ที่นั่น ดูเหมือนว่าพวกเขาจะไม่ทำงานในบล็อคโค้ดขนาดเล็ก
Brian Layman

1
นี่ควรเป็นคำตอบที่ยอมรับได้ มันทำงานร่วมกับอาร์เรย์ (ex / name = "soup []")
jdavid05

2
คุณสามารถใช้แทนpreviousElementSibling previousSiblingรองรับได้เกือบทุกที่และไม่สนใจโหนดข้อความ
MarSoft

23

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

หากคุณเพิ่มรหัสนี้:

<form>
  <input type='hidden' value='0' name='selfdestruct'>
  <input type='checkbox' value='1' name='selfdestruct'>
</form>

เบราว์เซอร์จะไม่สนใจสิ่งที่คุณทำที่นี่จริงๆ เบราว์เซอร์จะส่งพารามิเตอร์ทั้งสองไปยังเซิร์ฟเวอร์และเซิร์ฟเวอร์จะต้องตัดสินใจว่าจะทำอย่างไรกับพวกเขา

ตัวอย่างเช่น PHP ใช้ค่าสุดท้ายเป็นค่าที่ใช้ (ดู: ตำแหน่งที่มีสิทธิ์ของคีย์คิวรี่ HTTP GET ที่ซ้ำกัน )

แต่ระบบอื่น ๆ ที่ฉันทำงานด้วย (ขึ้นอยู่กับ Java) ทำสิ่งรอบตัว - พวกเขาให้คุณเฉพาะค่าแรก .NET แทนจะให้อาเรย์กับองค์ประกอบทั้งสองแทน

ฉันจะลองทดสอบกับ node.js, Python และ Perl ในบางครั้ง


2
ruby และ node.js ทั้งคู่จะใช้ค่าสุดท้ายของเขตข้อมูลฟอร์มที่ซ้ำกัน วิธีการช่วยเหลือของ Ruby on Rails สร้างช่องทำเครื่องหมายในลักษณะนี้ด้วยเหตุผลนี้
nzifnab

7
เพียงแค่ปัดเศษขึ้น - นี่คือการโจมตีที่เรียกว่า HTTP Parameter Pollution และได้รับการวิเคราะห์โดย OWASP: owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf (หน้า 9) ซึ่งคุณสามารถค้นหารายการ 20 ระบบและดูว่าพวกเขาจัดการกับมันอย่างไร
SimonSimCity

1
Java Servlets มอบทุกอย่างให้คุณตราบใดที่คุณโทรrequest.getParameterValues
mauhiz

20

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

<input type="checkbox" name="mycheckbox" />
<input type="hidden" name="mycheckbox.hidden"/>

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

อัลกอริทึมฝั่งเซิร์ฟเวอร์อาจมีลักษณะดังนี้:

for input in form data such that input.name endswith .hidden
  checkboxName = input.name.rstrip('.hidden')
  if chceckbName is not in form, user has unchecked this checkbox

ข้างต้นไม่ได้ตอบคำถามอย่างถูกต้อง แต่มีวิธีการอื่นในการรับฟังก์ชั่นที่คล้ายกัน


20

คุณไม่จำเป็นต้องสร้างเขตข้อมูลที่ซ่อนอยู่สำหรับช่องทำเครื่องหมายทั้งหมดเพียงคัดลอกรหัสของฉัน มันจะเปลี่ยนค่าของช่องทำเครื่องหมายหากไม่ได้ตรวจสอบvalueจะได้รับมอบหมาย0และถ้าช่องทำเครื่องหมายตรวจสอบแล้วกำหนดvalueเป็น1

$("form").submit(function () {

    var this_master = $(this);

    this_master.find('input[type="checkbox"]').each( function () {
        var checkbox_this = $(this);


        if( checkbox_this.is(":checked") == true ) {
            checkbox_this.attr('value','1');
        } else {
            checkbox_this.prop('checked',true);
            //DONT' ITS JUST CHECK THE CHECKBOX TO SUBMIT FORM DATA    
            checkbox_this.attr('value','0');
        }
    })
})

1
โซลูชันนี้ใช้งานได้ดีและสวยงามยิ่งกว่าการสร้างมลภาวะของ Dom ด้วยฟิลด์ที่ซ่อนอยู่
Prasad Paranjape

9
สิ่งนี้ทำให้กล่องเพื่อรับการตรวจสอบชั่วคราวในขณะที่ส่งแบบฟอร์ม สิ่งนี้ทำให้ผู้ใช้สับสน (อย่างดีที่สุด)
มาร์คเฟรเซอร์

12
$('input[type=checkbox]').on("change",function(){
    var target = $(this).parent().find('input[type=hidden]').val();
    if(target == 0)
    {
        target = 1;
    }
    else
    {
        target = 0;
    }
    $(this).parent().find('input[type=hidden]').val(target);
});

<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>
<p>
    <input type="checkbox" />
    <input type="hidden" name="test_checkbox[]" value="0" />
</p>

หากคุณไม่ใช้ชื่อช่องทำเครื่องหมายจะไม่ผ่าน เฉพาะอาร์เรย์ test_checkbox


1
ทางออกที่ดีมาก แต่ในกรณีของฉัน live () ไม่ทำงานดังนั้นฉันจึงใช้วิธี (): $ ('input [type = checkbox]'). on ("change", function () {... }) ;
Massa

4
สดล้าสมัยแล้ว อย่าใช้กับคำตอบใน stackoverflow อีกต่อไป Amem
Ismael

คำตอบนี้ดีที่สุดจริงๆ .. ใช้งานได้ตามที่คาดไว้ แม้สำหรับช่องทำเครื่องหมายกลุ่ม
Alemoh Rapheal Baja

11

คุณสามารถทำ Javascript บางส่วนในกิจกรรมส่งของแบบฟอร์ม นั่นคือทั้งหมดที่คุณทำได้แม้ว่าจะไม่มีวิธีที่จะทำให้เบราว์เซอร์ทำสิ่งนี้ด้วยตนเอง นอกจากนี้ยังหมายความว่าแบบฟอร์มของคุณจะแตกสำหรับผู้ใช้ที่ไม่มี Javascript ดีกว่าคือการรู้บนเซิร์ฟเวอร์ที่มีช่องทำเครื่องหมายเพื่อให้คุณสามารถอนุมานได้ว่าสิ่งที่ขาดหายไปจากค่าแบบฟอร์มที่โพสต์ ( $_POSTใน PHP) จะไม่ถูกตรวจสอบ


2
ตั้งแต่ php 4.1 คุณอาจใช้ $ _REQUEST php.net/manual/en/reserved.variables.request.php
Karl Adler

$_REQUESTเป็นการปฏิบัติที่ดีเนื่องจากจะอนุญาตให้นำรหัสมาใช้ใหม่หากสคริปต์ของคุณรองรับทั้งสองวิธี
แน่นอน

9

ฉันจะทำสิ่งต่อไปนี้จริง ๆ

มีช่องอินพุตที่ซ่อนของฉันด้วยชื่อเดียวกันกับช่องทำเครื่องหมาย

<input type="hidden" name="checkbox_name[]" value="0" />
<input type="checkbox" name="checkbox_name[]" value="1" />

และเมื่อฉันโพสต์ฉันก่อนอื่นให้ลบค่าที่ซ้ำกันที่หยิบขึ้นมาในอาร์เรย์ $ _POST, ซึ่งจะแสดงค่าที่ไม่ซ้ำกันแต่ละค่า

  $posted = array_unique($_POST['checkbox_name']);
  foreach($posted as $value){
    print $value;
  }

ฉันได้สิ่งนี้จากการโพสต์ลบค่าที่ซ้ำกันออกจากอาร์เรย์


จุดประสงค์ของ [] บนค่าฟิลด์ชื่อคืออะไร
Michael Potter

@MichaelPotter ดังนั้นเมื่อโพสต์ถูกส่งไปยัง PHP มันจะอ่านชื่อ `checkbox_name []
Twister1002

@ Twister1002 ฉันคิดว่าคุณอธิบายถึงวัตถุประสงค์ของแอตทริบิวต์ชื่อไม่ใช่เพื่อเพิ่ม [] ในชื่อ ฉันค้นหาเว็บและดูเหมือนว่าบางคนทำสิ่งนี้ด้วยชื่อ: groupname [elementname] เพื่อจัดกลุ่มเขตข้อมูลร่วมกัน แต่ฉันไม่พบคำอธิบายสำหรับว่าง []
Michael Potter

1
@MichaelPotter ขออภัยฉันคิดว่าฉันได้ทำคำสั่งนั้นเสร็จแล้ว แต่ดูเหมือนจะไม่ ขอผมทำใหม่นะ เมื่อมันถูกส่งไปยัง php โปรเซสเซอร์ PHP จะอ่านมันเป็นอาร์เรย์ ดังนั้นด้วยชื่อแต่ละชื่อcheckbox_name[]แต่ละค่าจะถูกป้อนลงในอาร์เรย์ซึ่งคุณสามารถดึง ตัวอย่าง: $_POST['checkbox_name'][0]และอื่น ๆ ด้วยการเพิ่มจำนวนฟิลด์ที่มีชื่อเดียวกัน อีกตัวอย่างหนึ่งคือถ้าคุณได้สามช่องชื่อfield_name[]คุณจะได้รับค่าที่สองของชอบfield_name $_POST['field_name'][1]มันมีจุดประสงค์ที่น่าทึ่งหากคุณมีหลายสาขาที่มีชื่อเดียวกัน
Twister1002

8

"ฉันใช้วิธีเซิร์ฟเวอร์แล้วดูเหมือนว่าจะทำงานได้ดีขอบคุณ - reach4thelasers 1 ธ.ค. 2552 เวลา 15:19 น." ฉันอยากจะแนะนำจากเจ้าของ ตามที่ยกมา: วิธีการแก้ปัญหาจาวาสคริปต์ขึ้นอยู่กับวิธีจัดการเซิร์ฟเวอร์ (ฉันไม่ได้ตรวจสอบ)

เช่น

if(!isset($_POST["checkbox"]) or empty($_POST["checkbox"])) $_POST["checkbox"]="something";

8

ฉันรู้ว่าคำถามนี้มีอายุ 3 ปี แต่ฉันพบวิธีแก้ปัญหาที่ฉันคิดว่าใช้ได้ดี

คุณสามารถตรวจสอบว่าตัวแปร $ _POST ถูกกำหนดและบันทึกไว้ในตัวแปรหรือไม่

$value = isset($_POST['checkboxname'] ? 'YES' : 'NO';

ฟังก์ชั่น isset () ตรวจสอบว่ามีการกำหนดตัวแปร $ _POST หรือไม่ โดยลอจิกถ้ามันไม่ได้รับมอบหมายจากนั้นช่องทำเครื่องหมายไม่ได้ตรวจสอบ


สิ่งนี้ดีกว่ามากเนื่องจากการตอบสนองที่ได้รับความนิยมมากที่สุดเป็นวิธีการแก้ปัญหาที่ยอดเยี่ยมสำหรับโปรแกรมอ่านหน้าจอ
Kevin Waterson

7

คำตอบส่วนใหญ่ที่นี่ต้องการการใช้ JavaScript หรือการควบคุมอินพุตที่ซ้ำกัน บางครั้งสิ่งนี้ต้องจัดการทั้งหมดในฝั่งเซิร์ฟเวอร์

ฉันเชื่อว่ากุญแจ (ตั้งใจ) เพื่อแก้ไขปัญหาที่พบบ่อยนี้คือการควบคุมการป้อนข้อมูลของแบบฟอร์ม

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

  1. ชื่อของช่องทำเครื่องหมาย
  2. ชื่อขององค์ประกอบป้อนข้อมูลการส่งแบบฟอร์ม

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

ตัวอย่างเช่น:

<form name="form" method="post">
  <input name="value1" type="checkbox" value="1">Checkbox One<br/>
  <input name="value2" type="checkbox" value="1" checked="checked">Checkbox Two<br/>
  <input name="value3" type="checkbox" value="1">Checkbox Three<br/>
  <input name="submit" type="submit" value="Submit">
</form>

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

<?php

$checkboxNames = array('value1', 'value2', 'value3');

// Persisted (previous) checkbox state may be loaded 
// from storage, such as the user's session or a database.
$checkboxesThatAreChecked = array(); 

// Only process if the form was actually submitted.
// This provides an opportunity to update the user's 
// session data, or to persist the new state of the data.

if (!empty($_POST['submit'])) {
    foreach ($checkboxNames as $checkboxName) {
        if (!empty($_POST[$checkboxName])) {
            $checkboxesThatAreChecked[] = $checkboxName;
        }
    }
    // The new state of the checkboxes can be persisted 
    // in session or database by inspecting the values 
    // in $checkboxesThatAreChecked.
    print_r($checkboxesThatAreChecked);
}

?>

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


6

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

ฉันใช้ความคิดของ Shailesh ใน PHP ได้ผลสำหรับฉัน นี่คือรหัสของฉัน:

/ * ลบฟิลด์ '.hidden' หากมีอยู่ให้ใช้ค่า '.hidden' ถ้าไม่ * /
foreach ($ _POST ['frmmain'] เป็น $ field_name => $ value)
{
    // ดูเฉพาะองค์ประกอบที่ลงท้ายด้วย '.hidden'
    if (! substr ($ field_name, -strlen ('. hidden'))) {
        หยุดพัก;
    }

    // รับชื่อโดยไม่มี '. hidden'
    $ real_name = substr ($ key, strlen ($ field_name) - strlen ('. hidden'));

    // สร้างเขตข้อมูลต้นฉบับ 'ปลอม' ด้วยค่าใน '.hidden' หากไม่มีต้นฉบับอยู่
    if (! array_key_exists ($ real_name, $ POST_copy)) {
        $ _POST [$ real_name] = $ value;
    }

    // ลบองค์ประกอบ '.hidden'
    ไม่มีการตั้งค่า ($ _ POST [$ FIELD_NAME]);
}

6

ฉันชอบวิธีแก้ปัญหาที่คุณเพิ่งโพสต์ฟิลด์ป้อนข้อมูลเพิ่มเติมโดยใช้ JavaScript ดูเหมือนว่าแฮ็คเล็กน้อยสำหรับฉัน

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

สำหรับเซิร์ฟเวอร์ส่วนหลังที่มีการใช้งานครั้งแรก (JSP) คุณควรทำสิ่งต่อไปนี้

  <input type="checkbox" value="1" name="checkbox_1"/>
  <input type="hidden" value="0" name="checkbox_1"/>


สำหรับแบ็กเอนด์เซิร์ฟเวอร์ที่มีการใช้งานครั้งล่าสุด (PHP, Rails) คุณควรทำสิ่งต่อไปนี้

  <input type="hidden" value="0" name="checkbox_1"/>
  <input type="checkbox" value="1" name="checkbox_1"/>


สำหรับแบ็กเอนด์เซิร์ฟเวอร์ที่จัดเก็บข้อมูลทั้งหมดในรายการชนิดข้อมูล ( [], array) (Python / Zope)

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


สำหรับเซิร์ฟเวอร์แบ็กเอนด์ที่มีการเชื่อมต่อทั้งหมดที่เกิดขึ้นด้วยเครื่องหมายจุลภาค (ASP.NET / IIS) คุณจะต้อง (แยก / ระเบิด) สตริงโดยใช้เครื่องหมายจุลภาคเป็นตัวคั่นเพื่อสร้างชนิดข้อมูลรายการ ( [])

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

การจัดการพารามิเตอร์แบ็กเอนด์

แหล่งที่มาของภาพ


6

ฉันใช้ jQuery บล็อกนี้ซึ่งจะเพิ่มอินพุตที่ซ่อนในเวลาส่งให้กับทุกช่องที่ไม่ได้ทำเครื่องหมาย มันจะรับประกันว่าคุณจะได้รับค่าที่ส่งมาสำหรับทุกช่องทำเครื่องหมายทุกครั้งทุกครั้งโดยไม่ทำให้ยุ่งเหยิงมาร์กอัปของคุณและเสี่ยงที่จะลืมทำในช่องทำเครื่องหมายที่คุณเพิ่มในภายหลัง นอกจากนี้ยังไม่เชื่อในสิ่งที่กองแบ็กเอนด์ (PHP, Ruby, ฯลฯ ) ที่คุณใช้

// Add an event listener on #form's submit action...
$("#form").submit(
    function() {

        // For each unchecked checkbox on the form...
        $(this).find($("input:checkbox:not(:checked)")).each(

            // Create a hidden field with the same name as the checkbox and a value of 0
            // You could just as easily use "off", "false", or whatever you want to get
            // when the checkbox is empty.
            function(index) {
                var input = $('<input />');
                input.attr('type', 'hidden');
                input.attr('name', $(this).attr("name")); // Same name as the checkbox
                input.attr('value', "0"); // or 'off', 'false', 'no', whatever

                // append it to the form the checkbox is in just as it's being submitted
                var form = $(this)[0].form;
                $(form).append(input);

            }   // end function inside each()
        );      // end each() argument list

        return true;    // Don't abort the form submit

    }   // end function inside submit()
);      // end submit() argument list

5

คุณยังสามารถดักจับเหตุการณ์ form.submit และย้อนกลับการตรวจสอบก่อนที่จะส่ง

$('form').submit(function(event){
    $('input[type=checkbox]').prop('checked', function(index, value){
        return !value;
    });
});

4

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

    $('form').submit(function(e){
    var b = $("input:checkbox:not(:checked)");
    $(b).each(function () {
        $(this).val(0); //Set whatever value you need for 'not checked'
        $(this).attr("checked", true);
    });
    return true;
});

วิธีนี้คุณจะมีอาร์เรย์ $ _POST ดังนี้:

Array
(
            [field1] => 1
            [field2] => 0
)

ไม่ได้ทำงานที่ด้านข้างของฉัน พยายามทำเช่นนี้ แต่ก็ยังไม่โพสต์ช่องทำเครื่องหมายทั้งหมด [รหัส] $ ("# ตัวกรองอินพุต") เปลี่ยน (ฟังก์ชั่น (e) {console.log ('sublmit'); var b = $ ("อินพุต: ช่องทำเครื่องหมาย: ไม่ (: เลือก)"); $ (b) .each (ฟังก์ชั่น () {$ (นี้) .val (2); $ (นี่) .attr ("ทำเครื่องหมาย", จริง);}); $ ("# ตัวกรอง") ส่ง ();}); [/ code]
lio

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

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

4
$('form').submit(function () {
    $(this).find('input[type="checkbox"]').each( function () {
        var checkbox = $(this);
        if( checkbox.is(':checked')) {
            checkbox.attr('value','1');
        } else {
            checkbox.after().append(checkbox.clone().attr({type:'hidden', value:0}));
            checkbox.prop('disabled', true);
        }
    })
});

1
สิ่งนี้ใช้ได้สำหรับฉัน แทนที่จะใช้. ส่งคุณจะใช้. คลิก จากนั้นลบบิตที่ปิดใช้งานช่องทำเครื่องหมาย หลังจากนั้นก็ทำงานได้อย่างสมบูรณ์
cgrouge

1
คำตอบที่ดีที่สุดไม่จำเป็นต้องเพิ่มการป้อนข้อมูลอื่นที่ซ่อนอยู่สำหรับแต่ละคน
Sky

3

สิ่งที่ฉันทำแตกต่างกันเล็กน้อย ก่อนอื่นฉันเปลี่ยนค่าของช่องทำเครื่องหมายทั้งหมดที่ไม่ได้ทำเครื่องหมาย ถึง "0" จากนั้นเลือกทั้งหมดดังนั้นค่าจะถูกส่ง

function checkboxvalues(){
  $("#checkbox-container input:checkbox").each(function({ 
    if($(this).prop("checked")!=true){
      $(this).val("0");
      $(this).prop("checked", true);
    }
  });
}


คำตอบนั้นดี แต่ฉันอยากรู้ว่ามันแตกต่างจากคำตอบของ @Rameez SOOMRO หรือไม่?
Imran Qamer

ผลลัพธ์สุดท้ายที่คล้ายกันด้วยวิธีนี้เท่านั้นคุณจะไม่เปลี่ยนค่าของช่องทำเครื่องหมายที่เลือก
Seborreia

2

ฉันต้องการเปรียบเทียบ $ _POST

if (!$_POST['checkboxname']) !$_POST['checkboxname'] = 0;

เป็นสิ่งที่ควรคำนึงถึงหาก POST ไม่มี 'checkboxname'value แสดงว่าไม่ได้ทำเครื่องหมายดังนั้นให้กำหนดค่า

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


1

ตัวอย่างการกระทำของ Ajax คือ (': checked') ใช้แล้ว jQuery แทนที่จะเป็น. val ();

            var params = {
                books: $('input#users').is(':checked'),
                news : $('input#news').is(':checked'),
                magazine : $('input#magazine').is(':checked')
            };

params จะได้รับความคุ้มค่าเป็น TRUE หรือ FALSE ..


1

ช่องทำเครื่องหมายมักจะแสดงข้อมูลไบนารีที่เก็บอยู่ในฐานข้อมูลเป็นค่าใช่ / ไม่ใช่, Y / N หรือ 1/0 ช่องทำเครื่องหมาย HTML มีลักษณะไม่ดีในการส่งค่าไปยังเซิร์ฟเวอร์เฉพาะเมื่อทำเครื่องหมายที่ช่องทำเครื่องหมาย! นั่นหมายความว่าสคริปต์เซิร์ฟเวอร์ในเว็บไซต์อื่นต้องทราบล่วงหน้าว่ามีช่องทำเครื่องหมายที่เป็นไปได้ทั้งหมดในหน้าเว็บเพื่อให้สามารถจัดเก็บค่าบวก (ตรวจสอบ) หรือลบ (ไม่ถูกตรวจสอบ) ได้ ที่จริงแล้วค่าลบเป็นปัญหา (เมื่อผู้ใช้ยกเลิกการเลือกก่อนหน้านี้ (ก่อน) ตรวจสอบค่า - เซิร์ฟเวอร์จะรู้ได้อย่างไรเมื่อไม่มีสิ่งใดถูกส่งหากไม่ทราบล่วงหน้าว่าควรส่งชื่อนี้ไป) หากคุณมีสคริปต์ฝั่งเซิร์ฟเวอร์ซึ่งสร้างสคริปต์ UPDATE แบบไดนามิกจะมีปัญหาเพราะคุณไม่ทราบว่าควรได้รับช่องทำเครื่องหมายใดบ้างเพื่อตั้งค่า Y สำหรับการตรวจสอบและค่า N สำหรับการไม่เลือก (ไม่ได้รับ)

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

<input type="hidden" id="N1" name="N1" value="Y" />
<input type="checkbox"<?php if($N1==='Y') echo ' checked="checked"'; ?> onclick="check(this);" />
<label for="N1">Checkbox #1</label>

ใช้หนึ่งฟัง JavaScript onclick และฟังก์ชั่นการตรวจสอบการโทร () สำหรับแต่ละช่องทำเครื่องหมายบนหน้าเว็บของฉัน:

function check(me)
{
  if(me.checked)
  {
    me.previousSibling.previousSibling.value='Y';
  }
  else
  {
    me.previousSibling.previousSibling.value='N';
  }
}

วิธีนี้ค่า 'Y' หรือ 'N' จะถูกส่งไปยังสคริปต์ฝั่งเซิร์ฟเวอร์เสมอรู้ว่าฟิลด์ใดที่ควรได้รับการอัปเดตและไม่จำเป็นต้องแปลง checbox "เป็น" ค่า "เป็น" Y "หรือไม่ได้รับช่องทำเครื่องหมายเป็น 'N '

หมายเหตุ: white space หรือ new line เป็นพี่น้องด้วยดังนั้นที่นี่ฉันต้องการ. prepreSibling.previousSibling.value หากไม่มีช่องว่างระหว่างนั้นเท่านั้นชัดเจนก่อนหน้านี้ค่า


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

$('input[type=checkbox]').click(function()
{
  if(this.checked)
  {
    $(this).prev().val('Y');
  }
  else
  {
    $(this).prev().val('N');
  }
});

1

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

<input type="hidden" class="checkbox_handler" name="is_admin[]" value="0" />
<input type="checkbox" name="is_admin_ck[]" value="1" />

จากนั้นควบคุมสถานะการเปลี่ยนแปลงของช่องทำเครื่องหมายด้านล่างรหัส jquery:

$(documen).on("change", "input[type='checkbox']", function() {
    var checkbox_val = ( this.checked ) ? 1 : 0;
    $(this).siblings('input.checkbox_handler').val(checkbox_val);
});

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

หวังว่าสิ่งนี้จะช่วยให้ใครบางคนมีปัญหาประเภทนี้ เชียร์ :)


1

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

ใน PHP คุณมักจะได้รับปัญหานี้โดยการทำ isset () ตรวจสอบองค์ประกอบช่องทำเครื่องหมายของคุณ หากองค์ประกอบที่คุณคาดหวังไม่ได้ตั้งอยู่ในตัวแปร $ _POST เรารู้ว่าช่องทำเครื่องหมายไม่ได้ถูกตรวจสอบและค่าอาจเป็นเท็จ

if(!isset($_POST['checkbox1']))
{
     $checkboxValue = false;
} else {
     $checkboxValue = $_POST['checkbox1'];
}

แต่ถ้าคุณสร้างฟอร์มแบบไดนามิกคุณจะไม่ทราบคุณลักษณะชื่อของช่องทำเครื่องหมายของคุณเสมอหากคุณไม่ทราบชื่อของช่องทำเครื่องหมายคุณจะไม่สามารถใช้ฟังก์ชัน isset เพื่อตรวจสอบว่าสิ่งนี้ถูกส่งไปด้วยหรือไม่ ตัวแปร $ _POST


1
function SubmitCheckBox(obj) {
     obj.value   = obj.checked ? "on" : "off";
     obj.checked = true;
     return obj.form.submit();
}

<input type=checkbox name="foo" onChange="return SubmitCheckBox(this);">

0

มีวิธีแก้ปัญหาที่ดีกว่าคือ ก่อนอื่นให้แอตทริบิวต์ชื่อเฉพาะช่องทำเครื่องหมายที่มีการตรวจสอบ จากนั้นเมื่อคลิกsubmitผ่านจาวาสคริปต์ที่functionคุณทำเครื่องหมายในช่องทั้งหมด ดังนั้นเมื่อคุณsubmitเท่านั้นที่จะถูกเรียกคืนในform collectionผู้ที่มีnameคุณสมบัติ

  //removing name attribute from all checked checkboxes
                  var a = $('input:checkbox:checked');
                   $(a).each(function () {
                       $(this).removeAttr("name");        
                   });

   // checking all unchecked checkboxes
                   var b = $("input:checkbox:not(:checked)");
                   $(b).each(function () {
                       $(this).attr("checked", true);
                   });

ข้อได้เปรียบ: ไม่จำเป็นต้องสร้างกล่องพิเศษที่ซ่อนอยู่และจัดการมัน


0

@cpburnz ทำให้ถูกต้อง แต่มีรหัสมากนี่คือแนวคิดเดียวกันโดยใช้รหัสน้อยลง:

JS:

// jQuery OnLoad
$(function(){
    // Listen to input type checkbox on change event
    $("input[type=checkbox]").change(function(){
        $(this).parent().find('input[type=hidden]').val((this.checked)?1:0);
    });
});

HTML (จดชื่อฟิลด์โดยใช้ชื่ออาร์เรย์):

<div>
    <input type="checkbox" checked="checked">
    <input type="hidden" name="field_name[34]" value="1"/>
</div>
<div>
    <input type="checkbox">
    <input type="hidden" name="field_name[35]" value="0"/>
</div>
<div>

และสำหรับ PHP:

<div>
    <input type="checkbox"<?=($boolean)?' checked="checked"':''?>>
    <input type="hidden" name="field_name[<?=$item_id?>]" value="<?=($boolean)?1:0?>"/>
</div>

0

คำตอบของ @ vishnu รุ่น jQuery

if($('#testName').is(":checked")){
    $('#testNameHidden').prop('disabled', true);
}

หากคุณใช้ jQuery 1.5 หรือต่ำกว่าโปรดใช้ฟังก์ชั่น. atr () แทน. prop ()


0

โซลูชันนี้ได้รับแรงบันดาลใจจาก @ desw's one

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

<input type="text" name="employee[]" />
<input type="hidden" name="isSingle[] value="no" />
<input type="checkbox" name="isSingle[] value="yes" />

ในกรณีที่คุณใส่พนักงานสามคนในครั้งเดียวและครั้งแรกและครั้งที่สองเป็นคนเดียวคุณจะจบลงด้วยisSingleอาร์เรย์5 องค์ประกอบดังนั้นคุณจะไม่สามารถทำซ้ำได้ในสามอาร์เรย์เพื่อยกตัวอย่างเช่น ใส่พนักงานในฐานข้อมูล

คุณสามารถเอาชนะสิ่งนี้ได้ด้วยการทำอาเรย์อย่างง่าย ฉันใช้ PHP ที่ฝั่งเซิร์ฟเวอร์และฉันก็ทำสิ่งนี้:

$j = 0;
$areSingles = $_POST['isSingle'];
foreach($areSingles as $isSingle){
  if($isSingle=='yes'){
    unset($areSingles[$j-1]);
  }
  $j++;
}
$areSingles = array_values($areSingles);

0

ดังนั้นวิธีนี้จึง overkill สำหรับคำถามนี้ แต่ช่วยฉันเมื่อฉันมีช่องทำเครื่องหมายเดียวกันที่เกิดขึ้นหลายครั้งสำหรับแถวที่แตกต่างกันในตาราง ฉันต้องการรู้ว่าแถวที่มีช่องทำเครื่องหมายแสดงและรู้สถานะของช่องทำเครื่องหมาย (ตรวจสอบ / ไม่ถูกตรวจสอบ)

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

HTML

 <table id="permissions-table">
    <tr>
	<td>
	    <input type="checkbox" class="has-permission-cb" value="Jim">
	    <input type="checkbox" class="has-permission-cb" value="Bob">
	    <input type="checkbox" class="has-permission-cb" value="Suzy">
	</td>
    </tr>
 </table>
 <input type="hidden" id="has-permissions-values" name="has-permissions-values" value="">

Javascript ที่จะเรียกใช้บนแบบฟอร์มส่ง

var perms = {};
$(".has-permission-checkbox").each(function(){
  var userName = this.value;
  var val = ($(this).prop("checked")) ? 1 : 0
  perms[userName] = {"hasPermission" : val};
});
$("#has-permissions-values").val(JSON.stringify(perms));

สตริง json จะถูกส่งผ่านด้วยแบบฟอร์มเป็น $ _POST ["has-permission-values"] ใน PHP ถอดรหัสสตริงเป็นอาร์เรย์และคุณจะมีอาร์เรย์เชื่อมโยงที่มีแต่ละแถวและค่าจริง / เท็จสำหรับแต่ละช่องทำเครื่องหมายที่เกี่ยวข้อง จากนั้นง่ายมากที่จะตรวจสอบและเปรียบเทียบกับค่าฐานข้อมูลปัจจุบัน

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