รูปแบบ HTML เลือกแท็ก / อินพุตแบบอ่านอย่างเดียว


587

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

ปัญหาเดียวคืออินพุตของฟอร์ม HTML ที่ปิดใช้งานจะไม่รวมอยู่ในข้อมูล POST / GET

วิธีที่ดีที่สุดในการเลียนแบบreadonlyคุณลักษณะของselectแท็กคืออะไรและยังคงได้รับข้อมูล POST


5
อย่าพึ่งพาสิ่งนั้นกับฝั่งเซิร์ฟเวอร์ ทุกคนสามารถสร้างหน้า HTML ของตัวเองและทำให้มันเป็น RW
Brendan Byrd

11
แต่ไม่ใช่คำถามเฉพาะ PHP
Kaleb Brasee

4
ฉันจะแนะนำไม่ใช้องค์ประกอบเลือกเลยในกรณีนี้ มีเหตุผลใดที่คุณไม่สามารถแสดงค่าเป็นข้อความธรรมดาได้หรือไม่
Big McLargeHuge

2
@ppumkin ความคิดเห็นของคุณไม่สมเหตุสมผล ฉันไม่ได้บอกว่าจะไม่มีกรณีการใช้งานที่ดีสำหรับเขตข้อมูลที่เลือกหรือซ่อนอยู่ OP มีปัญหาในการแสดงข้อความบนหน้าและฉันก็แค่สงสัยว่าจุดประสงค์ของการใช้องค์ประกอบที่เลือกในกรณีนี้คืออะไร
Big McLargeHuge

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

คำตอบ:


461

คุณควรเก็บselectองค์ประกอบไว้disabledแต่เพิ่มส่วนที่ซ่อนไว้inputด้วยชื่อและค่าเดียวกัน

หากคุณเปิดใช้งาน SELECT อีกครั้งคุณควรคัดลอกค่าไปยังอินพุตที่ซ่อนอยู่ในเหตุการณ์ onchange และปิดใช้งาน (หรือลบ) อินพุตที่ซ่อนอยู่

นี่คือตัวอย่าง:

$('#mainform').submit(function() {
    $('#formdata_container').show();
    $('#formdata').html($(this).serialize());
    return false;
});

$('#enableselect').click(function() {
    $('#mainform input[name=animal]')
        .attr("disabled", true);
    
    $('#animal-select')
        .attr('disabled', false)
    	.attr('name', 'animal');
    
    $('#enableselect').hide();
    return false;
});
#formdata_container {
    padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
    <form id="mainform">
        <select id="animal-select" disabled="true">
            <option value="cat" selected>Cat</option>
            <option value="dog">Dog</option>
            <option value="hamster">Hamster</option>
        </select>
        <input type="hidden" name="animal" value="cat"/>
        <button id="enableselect">Enable</button>
        
        <select name="color">
            <option value="blue" selected>Blue</option>
            <option value="green">Green</option>
            <option value="red">Red</option>
        </select>

        <input type="submit"/>
    </form>
</div>

<div id="formdata_container" style="display:none">
    <div>Submitted data:</div>
    <div id="formdata">
    </div>
</div>


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

1
@max Ah !. ตกลงนั่นก็ใช้ได้เช่นกัน ฉันสันนิษฐานว่าตั้งแต่ yo บอกว่าอินพุตที่ซ่อนอยู่ควรมี "ชื่อเดียวกัน" ที่ตัวเลือกมีชื่อ
Adam

2
จะเกิดอะไรขึ้นถ้าฉันใช้ตัวเลือกหลายตัว
Anyul Rivas

2
การมีสององค์ประกอบที่มีชื่อเหมือนกันจะโพสต์กลับเฉพาะอินพุต / เลือกที่เปิดใช้งานล่าสุดเท่านั้นไม่ใช่สองเท่า นอกจากนี้เฉพาะselectedค่าที่ได้รับการโพสต์กลับไม่ใช่รายการทั้งหมด ดังนั้นคุณhiddenจะนั่งต่อหน้าคุณselectและเก็บค่าที่เลือกไว้ หากการเลือกถูกปิดใช้งานสำหรับ "อ่านอย่างเดียว" การโพสต์กลับจะมีเฉพาะค่าของอินพุตที่ซ่อนอยู่ หากเปิดใช้งานการเลือกตัวเลือกที่มองเห็นได้จะ "เกินเขียน / แทนที่" ค่าที่ซ่อนอยู่และนั่นคือค่าที่จะได้รับการโพสต์กลับ
Piotr Kula

29
แม้ว่านี่จะเป็นโซลูชันที่ชัดเจน แต่ก็เป็นวิธีแก้ปัญหาเนื่องจากคุณต้องเพิ่มฟิลด์ป้อนข้อมูลอื่น
Donato

189

เราสามารถใช้สิ่งนี้ได้

ปิดใช้งานทั้งหมดยกเว้นตัวเลือกที่เลือก:

<select>
    <option disabled>1</option>
    <option selected>2</option>
    <option disabled>3</option>
</select>

วิธีนี้ดรอปดาวน์ยังคงใช้งานได้ (และส่งค่า) แต่ผู้ใช้ไม่สามารถเลือกค่าอื่นได้

การสาธิต


3
หนึ่งที่ดีสำหรับตัวเลือกแบบไดนามิก
Diego Favero

11
สมบูรณ์แบบสำหรับแท็ก SELECT แบบค่าเดียว! แต่จะไม่ทำงานสำหรับ <select multiple> ซึ่งจะยังให้ผู้ใช้สามารถยกเลิกการเลือกตัวเลือกที่เลือกไว้บางส่วนได้ดังนั้นจึงเป็นการเปลี่ยนค่า
Mikhail Bunkin

2
สนับสนุนเบราว์เซอร์สำหรับoptionแท็กdisabledแอตทริบิวต์
โจ

4
นี่เป็นทางออกที่ดี ฉันจะเพิ่มว่าคุณสามารถบรรลุได้อย่างง่ายดายด้วย jQuery เช่นนี้: $("#yourSelectId option:not(:selected)).attr("disabled", "disabled")
Onkel-j

105

คุณสามารถเปิดใช้งานวัตถุที่เลือกเมื่อส่ง

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

ตัวอย่างด้วย jQuery:

  • หากต้องการปิดใช้งาน:

    $('#yourSelect').prop('disabled', true);
  • หากต้องการเปิดใช้งานใหม่ก่อนส่งเพื่อให้มีข้อมูล GET / POST รวมอยู่:

    $('#yourForm').on('submit', function() {
        $('#yourSelect').prop('disabled', false);
    });

นอกจากนี้คุณสามารถเปิดใช้งานอินพุตที่ปิดใช้งานใหม่ทั้งหมดหรือเลือก:

$('#yourForm').on('submit', function() {
    $('input, select').prop('disabled', false);
});

4
ใช้ .prop ('ปิดใช้งาน', จริง / เท็จ) เพื่อตั้งค่าคุณสมบัติที่ปิดใช้งาน แอตทริบิวต์จะไม่เปลี่ยนสถานะจริง
ปารีส Char

ฉันคิดว่าโซลูชันนี้ฉลาดกว่าโซลูชัน@bezmax เพราะถ้าเราเพิ่มอินพุตที่ซ่อนอยู่เราต้องพิจารณาว่ามีเพียงหนึ่งอินพุตเท่านั้น (ชื่อเดียวกัน) เปิดใช้งานได้ทุกเมื่อ ไม่เช่นนั้นถ้าทั้งสองอินพุตถูกเปิดใช้งานในฝั่งเซิร์ฟเวอร์โปรแกรมจะใช้อาร์เรย์ของอินพุตที่อาจทำให้เกิดข้อยกเว้น (ตัวอย่างเช่นหากเราไม่ได้จัดการกับสถานการณ์นี้และเราคาดว่าจะมีหนึ่งสตริงและใช้ 'Request.Form [FieldName] 'command)
MiT

@Kevin ใช้งานได้> 90% ราย นอกจากนี้คุณต้อง jQuery ในเข็มขัดของคุณ ... เอ๊ะ
sitilge

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

51

อีกวิธีในการทำreadOnlyแอตทริบิวต์ให้กับselectองค์ประกอบคือการใช้css

คุณสามารถทำเช่น:

$('#selection').css('pointer-events','none');

การสาธิต


8
ทางออกที่ดี แต่คุณยังสามารถเปลี่ยนค่าด้วยคีย์บอร์ด
Mario Werner

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

นอกรีตค่อนข้าง !! หากการเลือกจะต้องถูกบล็อกจากการแสดงผลหน้า... .on('mouseover', function(){ ... });
Fr0zenFyr

pointer-events: noneป้องกันไม่ให้โฟกัสจากเคอร์เซอร์ของเมาส์ เพื่อป้องกันไม่ให้โฟกัสจากแป้นพิมพ์คุณสามารถเสริมโดยการเบลอทันทีเมื่อมีเหตุการณ์โฟกัสทั้งหมด:$('select').css('pointer-events', 'none').on('focus', function () {$(this).blur();});
Quinn Comendant

39
<select id="countries" onfocus="this.defaultIndex=this.selectedIndex;" onchange="this.selectedIndex=this.defaultIndex;">
<option value="1">Country1</option>
<option value="2">Country2</option>
<option value="3">Country3</option>
<option value="4">Country4</option>
<option value="5">Country5</option>
<option value="6">Country6</option>
<option value="7" selected="selected">Country7</option>
<option value="8">Country8</option>
<option value="9">Country9</option>
</select>

ผ่านการทดสอบและทำงานใน IE 6, 7 & 8b2, Firefox 2 & 3, Opera 9.62, Safari 3.2.1 สำหรับ Windows และ Google Chrome


15
ปัญหาเกี่ยวกับสิ่งนี้คือการดร็อปดาวน์ถูกแสดงผลราวกับว่ามันไม่ได้ถูกอ่านอย่างเดียว ผู้ใช้จะคิดว่ามันใช้งานไม่ได้ ...
ลูคัสอีเดอร์

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

11
ฉันมีปัญหาที่คล้ายกันและแก้ไขได้โดยแสดงตัวเลือกที่เลือกเท่านั้น ไม่ต้องใช้ JS, สับสนน้อยกว่าสำหรับผู้ใช้ ... <select id="countries"> <option value="7" selected="selected">Country7</option> </select>
Potherca

1
@ppumkin @dana @LukasEder No .. ไม่ถ้าคุณสามารถแก้ไข UX นี้ได้ ตัวอย่างเช่นคุณสามารถทำบางสิ่งเช่นonchange = 'this.selectedIndex=this.defaultIndex; alert("You should not change this..");'แทนที่จะเปลี่ยนดัชนีที่เลือกไว้เงียบ ๆ
Fr0zenFyr

1
@LukasEder สำหรับทุกคนที่สงสัยเกี่ยวกับประสบการณ์ของผู้ตอบคำถามพวกเขาสามารถเพิ่ม CSS เพื่อเน้นว่าไม่ควรเปลี่ยนหล่นลง ตั้งเคอร์เซอร์ไปและสีพื้นหลังเพื่อnot-allowed #CCC
Alexander Dixon

36

วิธีแก้ปัญหา jQuery อย่างง่าย

ใช้สิ่งนี้หากสิ่งที่คุณเลือกมีreadonlyคลาส

jQuery('select.readonly option:not(:selected)').attr('disabled',true);

หรือสิ่งนี้หากการเลือกของคุณมีreadonly="readonly"แอตทริบิวต์

$('select[readonly="readonly"] option:not(:selected)').attr('disabled',true);

7
กรุณาอธิบายรหัสของคุณเล็กน้อย เราต้องเพิ่มคลาส 'อ่านอย่างเดียว' ให้กับองค์ประกอบที่เลือกหรือไม่ เราจะต้องเรียกรหัสนี้เมื่อใด: เฉพาะใน document.ready หรือทุกครั้งที่มีการเปิด / ปิดการเลือก รหัสของคุณปลอดภัยหรือไม่?
anar khalilov

$(document).ready(function(){$('select option:not(:selected)').attr('disabled',true);});ทำงานได้ดีในการเลือกเพียงครั้งเดียว ไม่ต้องการคลาส "อ่านอย่างเดียว" การเลือกหลายรายการเป็นปัญหาในกรณีที่มีมากกว่าหนึ่งตัวเลือกที่เลือกไว้แล้วดังนั้นจึงไม่ปิดใช้งานและผู้ใช้เลือกหนึ่งในตัวเลือกที่ไม่ได้ปิดการใช้งานตัวเลือกอื่น ๆ ที่เลือกไว้ก่อนหน้านี้จะไม่ถูกเลือก
gordon

ไม่เข้าใจสิ่งนี้
Piotr Kula

มันปิดการใช้งานตัวเลือกอื่นที่ไม่ใช่ตัวเลือกที่เลือกสำหรับกล่องที่เลือกด้วยคลาส "อ่านได้อย่างเดียว" หากคุณมีองค์ประกอบเลือกในมือคุณสามารถเขียน:$select.find('option').not(':selected').attr('disabled', 'disabled');
Semra

1
ฉันชอบวิธีนี้ ฉันจะเปลี่ยนตัวเลือกเป็นselect[readonly]เพื่อให้คุณเพิ่มแอ็ตทริบิวต์ readonly ให้กับอิลิเมนต์ด้วยวิธีนี้คุณไม่จำเป็นต้องเลือกตัวเลือกที่แตกต่างจากประเภทอื่น ๆ จาวาสคริปต์แล้วเพิ่มผลอย่างต่อเนื่อง โปรดทราบว่าโซลูชันนี้ (และส่วนใหญ่อื่น ๆ ) จะช่วยให้ตัวแทนผู้ใช้มอบประสบการณ์การใช้งานที่ดีที่สุดเท่านั้น - ไม่ได้บังคับใช้สิ่งใด (จริง ๆ แล้วต้องทำฝั่งเซิร์ฟเวอร์หากจำเป็น)
jgivoni

21

โซลูชัน CSS อย่างง่าย:

select[readonly]{
    background: #eee;
    cursor:no-drop;
}

select[readonly] option{
    display:none;
}

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


1
หากคุณมีการตรวจสอบ CSRF (เช่นใน symfony และกรอบงานอื่น ๆ ) มันจะไม่ทำงาน
ThEBiShOp

12

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

โปรดทราบว่านี่เป็นคุณลักษณะ HTML 4.0 และนั่นคือ 6,7,8 beta 1 ดูเหมือนจะไม่เคารพสิ่งนี้

http://www.gtalbot.org/BrowserBugsSection/MSIE7Bugs/OptionDisabledSupport.html


11

นี่เป็นทางออกที่ดีที่สุดที่ฉันได้พบ:

$("#YourSELECTIdHere option:not(:selected)").prop("disabled", true);

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


11

ฉันรู้ว่ามันสายเกินไป แต่ก็สามารถทำได้ด้วย CSS ง่าย:

select[readonly] option, select[readonly] optgroup {
    display: none;
}

สไตล์จะซ่อนตัวเลือกและกลุ่มทั้งหมดเมื่อการเลือกอยู่ในreadonlyสถานะดังนั้นผู้ใช้จะไม่สามารถเปลี่ยนการเลือกได้

ไม่ต้องการแฮ็ค JavaScript


ดีและเรียบง่าย ฉันชอบมัน.
Jonathan Parent Lévesque

นี่เป็นวิธีแก้ปัญหาที่ดีมาก ขอบคุณ!
OderWat

10

ยังง่ายกว่า: เพิ่มแอตทริบิวต์สไตล์ให้กับแท็กที่คุณเลือก :

style="pointer-events: none;"

มันทำงานได้สำหรับฉัน แต่เหตุการณ์ของตัวชี้จะทำให้เบราว์เซอร์ข้ามสนับสนุน?
Abhijit Jagtap

3
มันไม่ทำงาน ผู้ใช้สามารถเปลี่ยนอินพุตโดยใช้คีย์บอร์ด
Sandhu

6

นี่คือทางออกที่ง่ายที่สุดและดีที่สุด คุณจะตั้งค่า readolny attr บนตัวเลือกของคุณหรือ attr อื่น ๆ เช่น data-readonly และทำดังต่อไปนี้

$("select[readonly]").live("focus mousedown mouseup click",function(e){
    e.preventDefault();
    e.stopPropagation();
});

1
คุณควรเพิ่ม keyup ad keydown ad ที่นี่รวมถึง dropdown ที่ยังมีอยู่โดย "tabbing" ลงไปและใช้ปุ่มลูกศรเพื่อเปลี่ยนค่า
apfz

5

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

// global variable to store original event/handler for save button
var form_save_button_func = null;

// function to get jQuery object for save button
function get_form_button_by_id(button_id) {
    return jQuery("input[type=button]#"+button_id);
}

// alter value of disabled element
function set_disabled_elem_value(elem_id, value)  {
    jQuery("#"+elem_id).removeAttr("disabled");
    jQuery("#"+elem_id).val(value);
    jQuery("#"+elem_id).attr('disabled','disabled');
}

function set_form_bottom_button_save_custom_code_generic(msg) {
    // save original event/handler that was either declared
    // through javascript or html onclick attribute
    // in a global variable
    form_save_button_func = get_form_button_by_id('BtnSave').prop('onclick'); // jQuery 1.6
    //form_save_button_func = get_form_button_by_id('BtnSave').prop('onclick'); // jQuery 1.7

    // unbind original event/handler (can use any of following statements below)
    get_form_button_by_value('BtnSave').unbind('click');
    get_form_button_by_value('BtnSave').removeAttr('onclick');

    // alternate save code which also calls original event/handler stored in global variable
    get_form_button_by_value('BtnSave').click(function(event){
        event.preventDefault();
        var confirm_result = confirm(msg);
        if (confirm_result) {
            if (jQuery("form.anyForm").find('input[type=text], textarea, select').filter(".disabled-form-elem").length > 0) {
                jQuery("form.anyForm").find('input[type=text], textarea, select').filter(".disabled-form-elem").removeAttr("disabled");
            }

            // disallow further editing of fields once save operation is underway
            // by making them readonly
            // you can also disallow form editing by showing a large transparent
            // div over form such as loading animation with "Saving" message text
            jQuery("form.anyForm").find('input[type=text], textarea, select').attr('ReadOnly','True');

            // now execute original event/handler
            form_save_button_func();
        }
    });
}

$(document).ready(function() {
    // if you want to define save button code in javascript then define it now

    // code below for record update
    set_form_bottom_button_save_custom_code_generic("Do you really want to update this record?");
    // code below for new record
    //set_form_bottom_button_save_custom_code_generic("Do you really want to create this new record?");

    // start disabling elements on form load by also adding a class to identify disabled elements
    jQuery("input[type=text]#phone").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("input[type=text]#fax").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("select#country").addClass('disabled-form-elem').attr('disabled','disabled');
    jQuery("textarea#address").addClass('disabled-form-elem').attr('disabled','disabled');

    set_disabled_elem_value('phone', '123121231');
    set_disabled_elem_value('fax', '123123123');
    set_disabled_elem_value('country', 'Pakistan');
    set_disabled_elem_value('address', 'address');

}); // end of $(document).ready function

นั่นฟังดูเหมือนสภาพการแข่งขันรอให้เกิดขึ้น
Brendan Byrd

5

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

$("select[readonly]").find("option:not(:selected)").hide().attr("disabled",true);

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

เป็นสิ่งสำคัญที่จะต้องแยกเคียวรี jquery เป็น 2 เพื่อเหตุผลด้านประสิทธิภาพเนื่องจาก jquery อ่านจากขวาไปซ้ายโค้ด:

$("select[readonly] option:not(:selected)")

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


บางที.prop("disabled", true)แทน
sam

4

วิธีฝั่งเซิร์ฟเวอร์อย่างง่ายวิธีหนึ่งคือการลบตัวเลือกทั้งหมดยกเว้นตัวเลือกที่คุณต้องการเลือก ดังนั้นใน Zend Framework 1.12 ถ้า $ element เป็น Zend_Form_Element_Select:

 $value =  $element->getValue();
 $options = $element->getAttrib('options');
 $sole_option = array($value => $options[$value]);
 $element->setAttrib('options', $sole_option);

4

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

หลังจากการเปลี่ยนแปลงใด ๆ ในคุณสมบัติแบบอ่านอย่างเดียวขององค์ประกอบ

$('select.readonly option:not(:selected)').attr('disabled',true);

$('select:not([readonly]) option').removeAttr('disabled');

4

วิธีแก้ปัญหาด้วย tabindex ทำงานร่วมกับการเลือก แต่ยังป้อนข้อความ

เพียงใช้คลาสที่ปิดใช้งาน

CSS:

.disabled {
    pointer-events:none; /* No cursor */
    background-color: #eee; /* Gray background */
}

JS:

$(".disabled").attr("tabindex", "-1");

HTML:

<select class="disabled">
    <option value="0">0</option>
</select>

<input type="text" class="disabled" />

แก้ไข: ด้วย Internet Explorer คุณต้องมี JS นี้:

$(document).on("mousedown", ".disabled", function (e) {
    e.preventDefault();
});

2

ติดตามจากคำแนะนำของ Grant Wagners; นี่คือข้อมูลโค้ด jQuery ที่ใช้กับฟังก์ชั่นตัวจัดการแทนแอททริบิวต์ onXXX โดยตรง:

var readonlySelect = function(selector, makeReadonly) {

    $(selector).filter("select").each(function(i){
        var select = $(this);

        //remove any existing readonly handler
        if(this.readonlyFn) select.unbind("change", this.readonlyFn);
        if(this.readonlyIndex) this.readonlyIndex = null;

        if(makeReadonly) {
            this.readonlyIndex = this.selectedIndex;
            this.readonlyFn = function(){
                this.selectedIndex = this.readonlyIndex;
            };
            select.bind("change", this.readonlyFn);
        }
    });

};

2

ฉันแก้ไขด้วย jquery:

      $("select.myselect").bind("focus", function(){
        if($(this).hasClass('readonly'))
        {
          $(this).blur();   
          return;
        }
      });

สิ่งนี้ทำงานได้ดีมากแม้ว่าภาพเคลื่อนไหว mouseover จะยังคงแสดงลูกศรแบบเลื่อนลงที่ดูเป็นแบบคลิกได้
Johncl

สิ่งนี้ไม่ทำงานสำหรับฉันใน Chrome 26: การเลือกยังคงทำงานได้อย่างสมบูรณ์
Andy

แต่มันยังคงแสดงรายการเมื่อคุณดับเบิลคลิกบน IE อย่างไรก็ตามเพื่อป้องกันไม่ให้?
user1995781

2

หากคุณกำลังใช้การตรวจสอบ jquery คุณสามารถทำสิ่งต่อไปนี้ได้ฉันใช้แอททริบิวต์ที่ปิดใช้งานโดยไม่มีปัญหา:

$(function(){
    $('#myform').validate({
        submitHandler:function(form){
            $('select').removeAttr('disabled');
            form.submit();
        }
    });
});

2

สิ่งที่ฉันพบว่าใช้งานได้ดีด้วยจาวาสคริปต์ธรรมดา (เช่น: ไม่จำเป็นต้องใช้ไลบรารี JQuery) คือการเปลี่ยน innerHTML ของ<select>แท็กให้เป็นค่าที่เหลือเพียงอย่างเดียวที่ต้องการ

ก่อน:

<select name='day' id='day'>
  <option>SUN</option>
  <option>MON</option>
  <option>TUE</option>
  <option>WED</option>
  <option>THU</option>
  <option>FRI</option>
  <option>SAT</option>
</select>

ตัวอย่าง Javascript:

document.getElementById('day').innerHTML = '<option>FRI</option>';

หลังจาก:

<select name='day' id='day'>
  <option>FRI</option>
</select>

วิธีนี้จะไม่มีการเปลี่ยนแปลงมีผล visiual และนี้จะโพสต์ / GET <FORM>ภายใน


1

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


3
ในทางทฤษฎีเป็นแนวคิดที่ดี - แต่ไม่มีการสนับสนุนตัวเลือกที่ถูกปิดใช้งานใน IE ก่อน IE8 tinyurl.com/yle4bto
scunliffe

1

โซลูชัน html:

<select onfocus="this.blur();">

คนจาวาสคริปต์:

selectElement.addEventListener("focus", selectElement.blur, true); selectElement.attachEvent("focus", selectElement.blur); //thanks, IE

เพื่อลบ:

selectElement.removeEventListener("focus", selectElement.blur, true); selectElement.detachEvent("focus", selectElement.blur); //thanks, IE

แก้ไข: เพิ่มวิธีลบ


@ButtleButkus javascript ใช้งานได้หรือไม่ ฉันเดาว่าอาจเป็นปัญหาที่เกี่ยวข้องกับเบราว์เซอร์คุณพยายามเพิ่ม tabindex ให้กับองค์ประกอบ
Kadmillos

1

เพียงแค่ลบแอตทริบิวต์ปิดการใช้งานก่อนที่จะส่งแบบฟอร์ม

    $('form').submit(function () {
        $("#Id_Unidade").attr("disabled", false);
    });

1
<select id="case_reason" name="case_reason" disabled="disabled">

disabled="disabled" ->จะได้รับค่าของคุณจากฐานข้อมูลและแสดงในแบบฟอร์ม readonly="readonly" ->คุณสามารถเปลี่ยนค่าของคุณใน selectbox แต่ค่าของคุณไม่สามารถบันทึกในฐานข้อมูลของคุณ


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

0

หากดร็อปดาวน์เลือกเป็นแบบอ่านอย่างเดียวตั้งแต่เกิดและไม่จำเป็นต้องเปลี่ยนเลยบางทีคุณควรใช้การควบคุมอื่นแทน? ชอบแบบง่าย<div>(รวมถึงเขตข้อมูลฟอร์มที่ซ่อนอยู่) หรือ<input type="text">?

เพิ่ม:หากดรอปดาวน์ไม่ได้เป็นแบบอ่านอย่างเดียวตลอดเวลาและมีการใช้ JavaScript เพื่อเปิดใช้งาน / ปิดใช้งานนี่เป็นวิธีการแก้ปัญหา - เพียงแค่ปรับเปลี่ยน DOM on-the-fly


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

ถ้าอย่างนั้นคุณสามารถแทนที่ดรอปดาวน์นี้ด้วย textbox on-the-fly?
Vilx-

ใช่ แต่การป้อนข้อมูลที่ซ่อนอยู่เสมอมีความสง่างามในความคิดของฉัน
Jrgns

0

ทำงานด้านล่างสำหรับฉัน:

$('select[name=country]').attr("disabled", "disabled"); 

11
FYI: ฟิลด์ฟอร์มที่ปิดใช้งานจะไม่รวมอยู่ในการส่ง
mz_01

0

ฉันจัดการโดยซ่อนกล่องเลือกและแสดง a spanแทนที่ด้วยค่าข้อมูลเท่านั้น เกี่ยวกับกรณีที่มีการปิดการใช้งานที่.readonlyระดับเราต้องยังจะเอา.toVanishองค์ประกอบและแสดง.toShowคน

 $( '.readonly' ).live( 'focus', function(e) {
                $( this ).attr( 'readonly', 'readonly' )
                if( $( this ).get(0).tagName == 'SELECT' ) {
                    $( this ).before( '<span class="toVanish readonly" style="border:1px solid; padding:5px">' 
                            + $( this ).find( 'option:selected' ).html() + '</span>' )
                    $( this ).addClass( 'toShow' )
                    $( this ).hide()
            }
    });

0

ใน IE ฉันสามารถเอาชนะ onfocus => onblur approach ได้โดยดับเบิลคลิก แต่การจดจำค่าแล้วคืนค่าในเหตุการณ์ onchange ดูเหมือนว่าจะจัดการกับปัญหานั้นได้

<select onfocus="this.oldvalue=this.value;this.blur();" onchange="this.value=this.oldvalue;">
....
</select>

คุณสามารถทำสิ่งที่คล้ายกันได้โดยไม่มีคุณสมบัติ expando โดยใช้ตัวแปร javascript


0

นี่คือความพยายามในการใช้ฟังก์ชัน jQuery ที่กำหนดเองเพื่อให้สามารถใช้งานได้

$(function(){

 $.prototype.toggleDisable = function(flag) {
    // prepare some values
    var selectId = $(this).attr('id');
    var hiddenId = selectId + 'hidden';
    if (flag) {
      // disable the select - however this will not submit the value of the select
      // a new hidden form element will be created below to compensate for the 
      // non-submitted select value 
      $(this).attr('disabled', true);

      // gather attributes
      var selectVal = $(this).val();
      var selectName = $(this).attr('name');

      // creates a hidden form element to submit the value of the disabled select
      $(this).parents('form').append($('<input></input>').
        attr('type', 'hidden').
        attr('id', hiddenId).
        attr('name', selectName).
        val(selectVal) );
    } else {
      // remove the newly-created hidden form element
      $(this).parents('form').remove(hiddenId);
      // enable back the element
      $(this).removeAttr('disabled');
    }
  }

  // Usage
  // $('#some_select_element').toggleDisable(true);
  // $('#some_select_element').toggleDisable(false);

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