เหตุใดปุ่มตัวเลือกจึงไม่สามารถ“ อ่านได้อย่างเดียว” ได้


214

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

มีเคล็ดลับแปลก ๆ ที่ฉันต้องใช้ในการอ่านอย่างเดียวเพื่อให้ทำงานได้อย่างที่คาดไว้หรือไม่? ฉันควรทำใน JavaScript แทนหรือไม่

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


5
“ นี่เป็นหนึ่งในการละเว้นที่ไม่สามารถเข้าใจได้ในข้อกำหนดของ HTML หรือไม่” คิดจากมุมมองของผู้ใช้ แสดงปุ่มที่พวกเขาไม่สามารถคลิกได้ทำไม
Paul D. Waite

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

7
นี่คือข้อมูลจำเพาะ: w3.org/TR/html401/interact/forms.html#h-17.12.2 "องค์ประกอบต่อไปนี้รองรับแอตทริบิวต์แบบอ่านอย่างเดียว: INPUT และ TEXTAREA" ซึ่งผิดอย่างเห็นได้ชัด กลับมาที่นี่แม้ว่าเราจะเห็นข้อมูลสรุปที่แม่นยำยิ่งขึ้น: w3.org/TR/WD-forms-970402#readonly "พร้อมใช้กับองค์ประกอบ INPUT ของประเภท TEXT หรือ PASSWORD และองค์ประกอบ TEXTAREA" ดูเหมือนว่าจะมีช่องว่างระหว่าง recs และ specs
graphicdivine

ยิ่งอยากรู้อยากเห็นมากขึ้น ตามเอกสารโบราณนี้ "ในช่องทำเครื่องหมายตัวอย่างเช่นคุณสามารถตรวจสอบหรือปิด (เช่นการตั้งค่าตรวจสอบสถานะ) แต่คุณไม่เปลี่ยนค่าของฟิลด์" ( htmlcodetutorial.com/forms/_INPUT_DISABLED.html ) จริงหรือไม่ การตั้งค่าแบบ READONLY บนช่องทำเครื่องหมาย / ล็อควิทยุเป็นค่าแม้ว่าผู้ใช้จะสามารถแก้ไขได้หรือไม่?
graphicdivine

ตรวจสอบการโพสต์ของฉัน [ที่นี่] [1] ให้วิธีแก้ปัญหาง่าย ๆ ที่สะอาด [1]: stackoverflow.com/a/15513256/1861389
powered4ward

คำตอบ:


149

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

ใช้ jQuery เพื่ออ่านอย่างเดียว:

$(':radio:not(:checked)').attr('disabled', true);

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


2
ขอบคุณ @Megan นี่เป็นทางออกที่ยอดเยี่ยม
Michael La Voie

9
ชุดรูปแบบนี้จะช่วยให้คุณสามารถใช้readonlyคุณสมบัติตามที่ OP คาดว่าจะใช้งานได้:$(':radio[readonly]:not(:checked)').attr('disabled', true);
wodow

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

ทำงานได้อย่างถูกต้อง ขอบคุณ
Hassan Farooq

ฉลาด! ใช้. not (.. ) ในกรณีที่คุณมีชุดข้อมูลที่เลือกไว้แล้ว: var myRadios = $ ('# specific-radios'); myRadios.not ( 'ตรวจสอบ') เสา ( 'คนพิการ' จริง). api.jquery.com/not
JoePC

207

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

<input type="radio" name="foo" value="Y" checked>
<input type="radio" name="foo" value="N" disabled>

ซอ: http://jsfiddle.net/qqVGu/


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

7
โซลูชันที่ 1 โปรด! มันเป็นสิ่งเดียวที่เข้าถึงได้อย่างถูกต้อง และถ้าคุณต้องการสคริปต์มันมีอีกหนึ่งบรรทัดที่จะตั้งค่าการเปิดใช้งานของฟิลด์ที่ซ่อนอยู่เป็นตรงกันข้ามกับการเปิดใช้งานวิทยุ
bobince

5
ฉันเพิ่งสังเกตเห็นว่าคำตอบที่ 2 และ 3 ได้เปลี่ยนสถานที่ในคำตอบของโจนาธานดังนั้นความคิดเห็นที่ดูเหมือนจะไม่สมเหตุสมผล
mcv

1
ต้องการที่จะสังเกตเห็นว่าโซลูชัน Javascript ไม่ทำงานมันเพียงแค่ยกเลิกการเลือกปุ่ม ฉันคิดว่ามันจำเป็นต้องมีonclick="return false"เพื่อป้องกันการเปลี่ยนแปลง
มิทรี

2
เมื่อฉันตั้งค่าวิทยุ "ปิดการใช้งาน" ฉันเพิ่ม "style = cursor: default" เพื่อลบ "เคอร์เซอร์ที่ปิดใช้งาน"
Joao Paulo

24

นี่คือเคล็ดลับที่คุณสามารถไปด้วย

<input type="radio" name="name" onclick="this.checked = false;" />

4
สิ่งที่ผมคิดว่าถึงแม้ว่ามันจะดีที่สุดถ้าคุณชี้แจงว่ามันควรจะเป็นonClick="this.checked = <%=value%>"ของความหลากหลายบาง :)
JustLoren

ที่ดีที่จะรู้ การตรวจสอบสามารถมีได้ทั้งค่าจริงหรือเท็จ
Sarfraz

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

3
ไม่ใช่ปัญหาสำหรับกรณีของฉัน เราใช้ jQuery และ Ajax หลายตันแล้ว
mcv

1
คุณควรทำอย่างนั้นonclick="return false;"เพื่อรักษาคุณค่าไว้เหมือนเดิมสำหรับกลุ่ม
Zach

12

ฉันมีแบบฟอร์มยาว (250+ ฟิลด์) ที่โพสต์ไปยังฐานข้อมูล มันเป็นโปรแกรมการจ้างงานออนไลน์ เมื่อผู้ดูแลระบบไปดูที่แอปพลิเคชันที่ยื่นแบบฟอร์มจะถูกเติมด้วยข้อมูลจากฐานข้อมูล ข้อความอินพุตและ textareas จะถูกแทนที่ด้วยข้อความที่พวกเขาส่ง แต่วิทยุและช่องทำเครื่องหมายมีประโยชน์ในการเก็บไว้เป็นองค์ประกอบของแบบฟอร์ม การปิดใช้งานทำให้ยากต่อการอ่าน การตั้งค่าคุณสมบัติ. checked ให้เป็นเท็จ onclick จะไม่ทำงานเพราะผู้ใช้อาจทำการตรวจสอบโดยการกรอกแอป ทั้งนี้ ...

onclick="return false;"

ทำงานเหมือนมีเสน่ห์สำหรับวิทยุ 'ปิดการใช้งาน' และช่องทำเครื่องหมาย ipso พฤตินัย


8

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

<input type="radio" name="name" onclick="javascript: return false;" />

ไม่! ในกรณีนี้ผู้ใช้สามารถแก้ไข html ในเบราว์เซอร์ทำเครื่องหมายตัวเลือกที่ต้องการตามที่เลือกและโพสต์แบบฟอร์ม
error1009

2

ฉันได้วิธีการจาวาสคริปต์อย่างหนักเพื่อให้ได้สถานะอ่านอย่างเดียวสำหรับกล่องกาเครื่องหมายและปุ่มตัวเลือก มีการทดสอบกับ Firefox เวอร์ชันปัจจุบัน Opera, Safari, Google Chrome รวมถึง IE เวอร์ชันปัจจุบันและก่อนหน้า (ลงไปที่ IE7)

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

ฉันไม่แน่ใจว่าฉันได้รับอนุญาตให้โพสต์ซอร์สโค้ดที่นี่ขณะที่ฉันพัฒนามันในขณะที่ทำงานให้กับ บริษัท แต่ฉันสามารถแบ่งปันแนวคิดได้

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

<input id="r1" type="radio" name="group1" value="r1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
<input id="r2" type="radio" name="group1" value="r2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
<input id="r3" type="radio" name="group1" value="r3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 3</input>

<input id="c1" type="checkbox" name="group2" value="c1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
<input id="c2" type="checkbox" name="group2" value="c2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
<input id="c3" type="checkbox" name="group2" value="c3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 3</input>

ส่วนจาวาสคริปต์ของสิ่งนี้จะทำงานได้เช่นนี้ (อีกแนวคิดเท่านั้น):

var selectionStore = new Object();  // keep the currently selected items' ids in a store

function storeSelectedRadiosForThisGroup(elementName) {
    // get all the elements for this group
    var radioOrSelectGroup = document.getElementsByName(elementName);

    // iterate over the group to find the selected values and store the selected ids in the selectionStore
    // ((radioOrSelectGroup[i].checked == true) tells you that)
    // remember checkbox groups can have multiple checked items, so you you might need an array for the ids
    ...
}

function setSelectedStateForEachElementOfThisGroup(elementName) {
    // iterate over the group and set the elements checked property to true/false, depending on whether their id is in the selectionStore
    ...

    // make sure you return false here
    return false;
}

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


2

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

<input type="radio" name="var" checked="yes" value="Yes"></input>
<input type="radio" name="var" disabled="yes" value="No"></input>

4
checked="yes"? สเป็คคืออะไร? อาจใช้checked="checked"หรือเพียงแค่แอตทริบิวต์ที่checkedไม่มีค่า disabledสำหรับเดียวกัน
Robin van Baalen

2

วิธี JavaScript - มันใช้งานได้สำหรับฉัน

<script>
$(document).ready(function() {
   $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); });
});
</script>

เหตุผล:

  1. $('#YourTableId').find('*') -> สิ่งนี้จะคืนค่าแท็กทั้งหมด

  2. $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); }); วนซ้ำวัตถุทั้งหมดที่ถูกจับในส่วนนี้และปิดใช้งานแท็กอินพุต

การวิเคราะห์ (การดีบัก):

  1. form:radiobutton ถูกพิจารณาเป็นการภายในว่าเป็นแท็ก "อินพุต"

  2. เช่นเดียวกับในฟังก์ชั่นด้านบน () หากคุณลองพิมพ์ document.write(this.tagName);

  3. ไม่ว่าที่ไหนในแท็กจะพบปุ่มตัวเลือกมันจะส่งคืนแท็กอินพุต

ดังนั้นรหัสบรรทัดด้านบนสามารถปรับให้เหมาะสมยิ่งขึ้นสำหรับแท็กปุ่มตัวเลือกโดยแทนที่ * ด้วยอินพุต: $('#YourTableId').find('input').each(function () { $(this).attr("disabled", true); });


1

ตัวเลือกที่ค่อนข้างง่ายคือการสร้างฟังก์ชั่นจาวาสคริปต์ที่เรียกในเหตุการณ์ "onsubmit" ของฟอร์มเพื่อเปิดใช้งานเรดิโอปุ่มย้อนกลับเพื่อให้ค่าของมันถูกโพสต์พร้อมกับส่วนที่เหลือของฟอร์ม
ดูเหมือนจะไม่เป็นการละเว้นในข้อกำหนดของ HTML แต่ตัวเลือกการออกแบบ (ตรรกะหนึ่ง IMHO), radiobutton ไม่สามารถอ่านได้อย่างเดียวเนื่องจากปุ่มไม่สามารถทำได้ถ้าคุณไม่ต้องการใช้มัน ปิดการใช้งาน


1

ฉันพบว่าการใช้onclick='this.checked = false;'งานได้ผลในระดับหนึ่ง ปุ่มตัวเลือกที่ถูกคลิกจะไม่ถูกเลือก อย่างไรก็ตามหากมีปุ่มตัวเลือกที่เลือกไว้แล้ว (เช่นค่าเริ่มต้น) ปุ่มตัวเลือกนั้นจะไม่ถูกเลือก

<!-- didn't completely work -->
<input type="radio" name="r1" id="r1" value="N" checked="checked" onclick='this.checked = false;'>N</input>
<input type="radio" name="r1" id="r1" value="Y" onclick='this.checked = false;'>Y</input>

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

<!-- preserves pre-selected value -->
<input type="radio" name="r1" id="r1" value="N" checked="checked">N</input>
<input type="radio" name="r1" id="r1" value="Y" disabled>Y</input>

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


1

ลองใช้แอตทริบิวต์disabledแต่ฉันคิดว่าคุณจะไม่ได้รับค่าของปุ่มตัวเลือก หรือตั้งค่ารูปภาพแทนเช่น:

<img src="itischecked.gif" alt="[x]" />radio button option

ขอแสดงความนับถืออย่างสูง.


1
โอ้รหัส html ของฉันถูกปลดออก: img src = "itIsChecked.gif" alt = "[x]" OptionChecked
ทิม

0

ฉันใช้ปลั๊กอิน JS ที่มีรูปแบบช่องทำเครื่องหมาย / องค์ประกอบสัญญาณวิทยุและใช้ jQuery ต่อไปนี้เพื่อสร้าง 'สถานะแบบอ่านอย่างเดียว' ซึ่งค่าพื้นฐานยังคงโพสต์ แต่องค์ประกอบอินพุตนั้นไม่สามารถเข้าถึงผู้ใช้ได้ซึ่งฉันเชื่อว่าเหตุผลที่ตั้งใจ เราจะใช้คุณลักษณะอินพุตแบบอ่านอย่างเดียว ...

if ($(node).prop('readonly')) {
    $(node).parent('div').addClass('disabled'); // just styling, appears greyed out
    $(node).on('click', function (e) {
        e.preventDefault();
    });
}

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