จะมั่นใจได้อย่างไรว่าฟิลด์ฟอร์ม <select> ถูกส่งเมื่อปิดการใช้งาน


180

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

readonlyแอตทริบิวต์จะใช้ได้เฉพาะinputและtextareaสาขา แต่ที่เป็นพื้นสิ่งที่ฉันต้องการ มีวิธีใดบ้างที่จะทำงานนี้ได้?

สองความเป็นไปได้ที่ฉันกำลังพิจารณารวมถึง:

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

2
ขออภัยที่เข้าร่วมสาย แต่วิธีแก้ปัญหาของ @ trafalmadorianworkest ดีที่สุด มันปิดการใช้งานอินพุตทั้งหมดที่ไม่ได้เลือก มันจะทำงานถ้ามันเลือกเปิดใช้งานหลายตัวเลือก $('#toSelect')find(':not(:selected)').prop('disabled',true);
Abhishek Madhani

หรือคุณสามารถปล่อยให้ตัวควบคุมถูกปิดการใช้งานบน UI แต่ดึงค่าในวิธีการดำเนินการ: สาธารณะ ActionResult InsertRecord (รุ่น MyType) {ถ้า (model.MyProperty == null) {model.MyProperty = คำขอ ["MyProperty"]; }}
beastieboy

คำตอบ:


118
<select disabled="disabled">
    ....
</select>
<input type="hidden" name="select_name" value="selected value" />

ไหนเป็นชื่อที่คุณตามปกติจะให้select_name<select>

ตัวเลือกอื่น

<select name="myselect" disabled="disabled">
    <option value="myselectedvalue" selected="selected">My Value</option>
    ....
</select>
<input type="hidden" name="myselect" value="myselectedvalue" />

ขณะนี้มีหนึ่งในนี้ผมได้สังเกตเห็นว่าขึ้นอยู่กับสิ่งที่เว็บเซิร์ฟเวอร์ที่คุณกำลังใช้คุณอาจจะต้องใส่การป้อนข้อมูลทั้งก่อนหรือหลังhidden<select>

หากหน่วยความจำของฉันให้บริการฉันอย่างถูกต้องด้วย IIS คุณต้องใส่ไว้ก่อนหน้านี้ด้วย Apache ที่คุณใส่ไว้ เช่นเคยการทดสอบเป็นกุญแจสำคัญ


3
สิ่งนี้จะขึ้นอยู่กับเว็บเซิร์ฟเวอร์อย่างไร ไม่ใช่ลูกค้าที่แสดงหน้าเว็บด้วยฟิลด์เลือกและในกรณีที่มีข้อขัดแย้งเช่นนั้นลูกค้าจะเป็นผู้ตัดสินใจว่าจะส่งค่าไปยังเซิร์ฟเวอร์หรือไม่
Ilari Kajaste

8
ขึ้นอยู่กับวิธีที่เซิร์ฟเวอร์จัดการอินพุตหลายรายการด้วยชื่อเดียวกัน
Jordan S. Jones

1
คุณไม่ควรพึ่งพาเซิร์ฟเวอร์ชนิดใดชนิดหนึ่งเป็นพิเศษดังนั้นฉันคิดว่าวิธีแรกนั้นสะอาดกว่าและมีข้อผิดพลาดน้อยลง ..
ลุค

5
@Jordan: เบราว์เซอร์จะไม่ส่งค่าฟิลด์ที่ถูกปิดใช้งานไปยังเซิร์ฟเวอร์ซึ่งเป็นสาเหตุว่าทำไมมันว่างเปล่าเมื่อคุณพยายามจัดการกับฝั่งเซิร์ฟเวอร์ หากคุณมีฟิลด์ที่ซ่อนอยู่ซึ่งมีค่าที่ต้องการและฟิลด์ที่มองเห็นถูกปิดใช้งานเฉพาะฟิลด์ที่ซ่อนอยู่เท่านั้นที่จะถูกส่งไปยังเซิร์ฟเวอร์ ดังนั้น, ฟิลด์ที่ซ่อนอยู่ควรถูกสร้างขึ้น (ผ่าน JS หรือรหัสฝั่งเซิร์ฟเวอร์) เมื่อปิดการใช้งานฟิลด์ที่มองเห็นได้และไม่มีปัญหาสำคัญ
Matt van Andel

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

224

ปิดการใช้งานเขตข้อมูลและเปิดใช้งานก่อนที่จะส่งแบบฟอร์ม:

รหัส jQuery:

jQuery(function ($) {        
  $('form').bind('submit', function () {
    $(this).find(':input').prop('disabled', false);
  });
});

15
เป็นทางออกที่ดีทีเดียว!
Chris

2
นี่คือสิ่งที่ฉันตัดสินเพราะส่วนใหญ่เป็นสิ่งที่ไม่น่าสนใจ
Jonathan

3
jQuery docs แนะนำให้ใช้. prop และ .removeProp สำหรับ 'ทำเครื่องหมาย', 'เลือก' และ 'ปิดใช้งาน' แทนที่จะเป็น. atr และ .removeAttr ดูที่ http://api.jquery.com/prop/
จิมเบิร์กแมน

2
บิตที่เกี่ยวข้องกับความคิดเห็นของ @ JimBergman - "คุณสมบัติโดยทั่วไปจะมีผลต่อสถานะไดนามิกขององค์ประกอบ DOM โดยไม่เปลี่ยนแอตทริบิวต์ HTML ที่เป็นอนุกรมตัวอย่างเช่นคุณสมบัติค่าขององค์ประกอบอินพุตคุณสมบัติปิดใช้งานของอินพุตและปุ่มหรือคุณสมบัติที่ถูกตรวจสอบของช่องทำเครื่องหมาย ควรใช้เมธอด .prop () เพื่อตั้งค่าปิดใช้งานและตรวจสอบแทนเมธอด. atr () ควรใช้วิธี. val () เพื่อรับและตั้งค่า " - จากapi.jquery.com/prop
Joshua Dance

2
คุณเป็นอัจฉริยะ (Y)
TommyDo

13

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

// With jQuery
$('#selectbox').focus(function(e) {
    $(this).blur();
});

เรียบง่ายคุณเพียงแค่เบลอเขตข้อมูลเมื่อคุณมุ่งเน้นไปที่สิ่งที่ต้องการปิดการใช้งาน แต่คุณส่งข้อมูลจริง


ว้าวทางออกที่ดีและง่าย ขอบคุณ .. +1 จากฉัน :)
Naeem Ul Wahhab

ฉันชอบสิ่งนี้มาก .. ขึ้นอยู่กับการโต้ตอบในฟอร์มของฉันองค์ประกอบกลายเป็นเปิดใช้งาน / ปิดการใช้งาน back-n-out ... ฉันจะเปิดใช้งานฟิลด์ 'เบลอ' อีกครั้งในสถานการณ์นี้ได้อย่างไร
bkwdesign

จาก googling ดูเหมือนว่า $ ('# selectbox'). off ('focus'); จะหลอกลวงของการเปิดใช้งานใหม่
bkwdesign

2
ใช้งานได้กับกล่องข้อความไม่สามารถใช้กับกล่องที่เลือกได้รวมถึงการใช้งานที่สะดวกสบายโดยการคลิกและกดปุ่มค้างไว้
Andrew

7

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

$('#toSelect')find(':not(:selected)').attr('disabled','disabled');

ขอบคุณฉันพบว่าคุณมีเหตุผลที่ง่ายที่สุด อย่างไรก็ตามattrควรเปลี่ยนด้วยpropจะมีลักษณะเหมือน$('#toSelect')find(':not(:selected)').prop('disabled',true);
Abhishek Madhani

6

โซลูชันเดียวกันที่ Tres แนะนำโดยไม่ใช้ jQuery

<form onsubmit="document.getElementById('mysel').disabled = false;" action="..." method="GET">

   <select id="mysel" disabled="disabled">....</select>

   <input name="submit" id="submit" type="submit" value="SEND FORM">
</form>

สิ่งนี้อาจช่วยให้บางคนเข้าใจมากขึ้น แต่เห็นได้ชัดว่ายืดหยุ่นน้อยกว่า jQuery


แต่มันไม่ดีสำหรับตัวเลือกหลายตัว เราสามารถใช้getElementsByTagName('select')ไหม
โชคดี

6

ไม่สามารถใช้งานกับ: ตัวเลือกอินพุตสำหรับฟิลด์ที่เลือกใช้สิ่งนี้:

    jQuery(function() {

    jQuery('form').bind('submit', function() {
        jQuery(this).find(':disabled').removeAttr('disabled');
    });

    });

5

ฉันใช้รหัสถัดไปสำหรับปิดการใช้งานตัวเลือกในการเลือก

<select class="sel big" id="form_code" name="code" readonly="readonly">
   <option value="user_played_game" selected="true">1 Game</option>
   <option value="coins" disabled="">2 Object</option>
   <option value="event" disabled="">3 Object</option>
   <option value="level" disabled="">4 Object</option>
   <option value="game" disabled="">5 Object</option>
</select>

// Disable selection for options
$('select option:not(:selected)').each(function(){
 $(this).attr('disabled', 'disabled');
});

4

วิธีที่ง่ายที่สุดที่ฉันพบคือการสร้างฟังก์ชั่นจาวาสคริปต์เล็ก ๆ ที่เชื่อมโยงกับแบบฟอร์มของคุณ:

function enablePath() {
    document.getElementById('select_name').disabled= "";
}

และคุณเรียกมันในแบบฟอร์มของคุณที่นี่:

<form action="act.php" method="POST" name="form_name" onSubmit="enablePath();">

หรือคุณสามารถเรียกมันในฟังก์ชั่นที่คุณใช้ตรวจสอบแบบฟอร์มของคุณ :)



2

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


2

ฉันเพิ่มปลั๊กอินด่วน (Jquery เท่านั้น) ที่บันทึกค่าในเขตข้อมูลในขณะที่อินพุตถูกปิดใช้งาน นี่หมายความว่าตราบใดที่ฟิลด์ถูกปิดใช้งานโดยทางโปรแกรมผ่าน jquery โดยใช้. prop () หรือ .attr () ... จากนั้นการเข้าถึงค่าโดย. val (), .serialize () หรือ .serializeArra () จะส่งคืนค่าเสมอ ค่าแม้ว่าจะปิดการใช้งาน :)

ปลั๊กไร้ยางอาย: https://github.com/Jezternz/jq-disabled-inputs


2

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

function changeSelectUserManipulation(obj, disable){
    var $obj = ( typeof obj === 'string' )? $('#'+obj) : obj;
    disable = disable? !!disable : !$obj.is(':disabled');

    if(disable){
        $obj.prop('disabled', true)
            .after("<input type='hidden' id='select_user_manipulation_hidden_"+$obj.attr('id')+"' name='"+$obj.attr('name')+"' value='"+$obj.val()+"'>");
    }else{
        $obj.prop('disabled', false)
            .next("#select_user_manipulation_hidden_"+$obj.attr('id')).remove();
    }
}

changeSelectUserManipulation("select_id");

พารามิเตอร์ 'obj' ต้องเป็นวัตถุ jquery
Doglas

1

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

jQuery(function($) {
    $('form').submit(function(){
        $('select option:not(:selected)', this).remove();
    });
});

0
<select id="example">
    <option value="">please select</option>
    <option value="0" >one</option>
    <option value="1">two</option>
</select>



if (condition){
    //you can't select
    $("#example").find("option").css("display","none");
}else{
   //you can select
   $("#example").find("option").css("display","block");
}

-8

ตัวเลือกอื่นคือการใช้คุณลักษณะอ่านอย่างเดียว

<select readonly="readonly">
    ....
</select>

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

แก้ไข:

อ้างถึงจากhttp://www.w3.org/TR/html401/interact/forms.html#adef-readonly :

  • องค์ประกอบแบบอ่านอย่างเดียวได้รับโฟกัส แต่ผู้ใช้ไม่สามารถแก้ไขได้
  • องค์ประกอบแบบอ่านอย่างเดียวจะรวมอยู่ในการนำทางแบบแท็บ
  • องค์ประกอบแบบอ่านอย่างเดียวอาจประสบความสำเร็จ

เมื่อมันบอกว่าองค์ประกอบอาจจะประสบความสำเร็จก็หมายความว่ามันอาจจะส่งตามที่ระบุไว้ที่นี่: http://www.w3.org/TR/html401/interact/forms.html#successful-controls


6
การควบคุมไม่เป็นสีเทาและผู้ใช้สามารถแก้ไขได้ คุณไม่สามารถอ่านส่วนทั้งหมดและฉันพูด: "องค์ประกอบต่อไปนี้สนับสนุนแอตทริบิวต์อ่านอย่างเดียว: INPUT และ TEXTAREA"
Carlos Rendon

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