Hi,
i'm currently migrating my app to select 2 4.0 and I can't figure it out how to implement the readonly.
In the 3.*, the function
$('select').select2('readonly',true);
worked very well.
The behavior protects the user from editing the select and the form element is sent through the form posting.
The disabled property works well but it prevents the form element to be posted. (it's a normal behavior)
With the 4.0 version, the readonly is not handled at all.
$('select').prop('readonly',true);
Does nothing.
I think it will be an interesting feature to have.
I've made a fiddle of this :
http://jsfiddle.net/skxad701/2/
The behavior will be the same as the disabled one , except it can be sent.
I've made a workaround to remove the disabled property before submitting my form.
Do you think it's something that can be planned to be added in the future version ?
As mentioned in the 4.0 release notes, there is no way to make a <select> read-only and because 4.0 supports the <select> as the primary data source, this is going to be pretty difficult to implement.
Using a read-only state to prevent users from modifying data that needs to be sent to the server hints at the idea that you _might not_ be validating data on the server side. It's not a wise choice to depend on the client to not modify data that is sent, and a read-only select doesn't actually make that much sense (which is why we used to disable it).
With that in mind, I don't plan on somehow implementing this soon. As part of the ongoing attempt to cut down on the number of (soon-to-be) inactive tickets on GitHub, I'm going to close this off.
Why would it be any different from all the other form input fields? All the other readonly input fields send data but you can't edit, but no one is worrying about validating them. Why not just remove readonly from everything then?
You shouldn't worry if it's being validated, that's the developers job to do it, or not. Let them decide what makes most sense.
I thought select2 was to enhance <select> and fix the flaws it has.
How many people have to use disable select, hidden input and javascript to fix that one thing.
Just created a workaround for me. may be useful for anybody else.
https://jsfiddle.net/ujdbcy3d/14/
You can fix it by using css. This is a scss file sample that worked for me using the bootstrap theme.
select[readonly].select2 + .select2-container {
pointer-events: none;
touch-action: none;
.select2-selection {
background: #eee;
box-shadow: none;
}
.select2-selection__arrow,
.select2-selection__clear {
display: none;
}
}
I did what leonardofalk did.
One caveat: when using jquery to dynamically change readonly you'll have to use attr rather than prop, as at least some browsers ignore the readonly prop on selects.
also, the idea that because it's true for your use case that readonly is not useful/desired that therefore it ought not be useful/desired for anyone is rather prescriptivist.
I'm going to remind everyone that the native <select> doesn't support readonly. And since Select2 is designed to enhance (read: not replace) a standard <select>, we also face that same limitation.
Another option that suited my needs is to use disabled, then using JS on form submit, enable the input. The user can not interact with the input, but the values are still passed.
For me worked what leonardofalk did but a little changed. My select2 Version is 4.03
select[readonly].select2-hidden-accessible + .select2-container {
pointer-events: none;
touch-action: none;
.select2-selection {
background: #eee;
box-shadow: none;
}
.select2-selection__arrow,
.select2-selection__clear {
display: none;
}
}
I also used what transputec did to make a working example here
I think the fix provided by leonardofalk and updated by nikitul should be pushed into the Select2 main branch. I think this would be a good enhancement to the standard
It seems to me that the idea behind Select2 v4+ is to _enhance_ a standard <select> element, not be identical to it. There are a lot of things that Select2 does, like search and AJAX support, that a standard <select> does not do.
I believe the guiding principle in deciding whether to add a feature should be graceful degradation. That is, the question we should always be asking ourselves should be:
If I use a particular feature of Select2, would my UI still function adequately if Select2 were not initialized on the element?
In the case of multiple-select, for example, an element with the multiple property will still allow for multiple selections, even though it won't render as the attractive "pills" that Select2 implements.
In the case of something like readonly, it's a little more difficult to say. Functionally, the idea is to lock the control on a particular value, but still send that value to the server. There is a suggested implementation for this in a native select element. Perhaps Select2 could detect when all non-selected items are disabled, and automatically make the entire field locked when this condition is detected (this could even be configurable). As @rain01 correctly points out, that is something for the server-side developer to worry about, not the Select2 plugin.
Reading this issue, and a lot of other issues as well, I'm wondering what Select2's mission is and whether it is distinct from other similar search/typeahead plugins out there. Is the goal to provide as graceful a degradation down to a native <select> as possible? Or should the focus be more on adding features, even if they might not gracefully degrade? Either way, this should be documented so that people know what they are getting up front.
Another possibility is to keep Select2 as "pure" as possible, but then encourage the development of third-party adapters/decorators that implement these non-compliant features. Yet another possibility is to create a wrapper around Select2 that implements some of these common hacks/workarounds.
It's also worth noting that the HTML specs themselves change over time, and native controls like datalist didn't exist when Select2 first came out. Perhaps a future version of Select2 can use one of these new features to satisfy the graceful degradation requirement.
This issue (like many) cuts to the heart of Select2's identity. I disagree with @kevin-brown that this discussion should have anything to do with whether or not the submitted data is being properly validated on the server side. There are many uses for readonly that have nothing to do with data validation or preventing the user from submitting a particular value.
I'm going to reopen this issue for now, because the issues surrounding progressive enhancement/graceful degradation clearly haven't been resolved yet.
@alexweissman said:
I disagree with @kevin-brown that this discussion should have anything to do with whether or not the submitted data is being properly validated on the server side. There are many uses for readonly that have nothing to do with data validation or preventing the user from submitting a particular value.
Agreed with you, select2 shuld not worry about backend validation in context of readonly state. After all, developer should know what he does, don't take developers for fools.
@transputec @nikitul Can your code be adapted such that only one select2 form is set to readonly at a time? Struggling to figure this out!
when will the readonly settings be made?
@thadeu doesn't seem to be high on their priorities list. Looks like we will have to use a hack workaround until they get around to it:
$('#yourId option:not(:selected)').prop('disabled', true);
Nevermind that doesn't work either. I'm going to settle for disabling the field and then enabling it before form submission. Not very elegant, but what can ya do.
@moebaca a slight fix to your original approach should make it work. My original approach to address this shortcoming was the same:
$("#yourId").val('yourOptionVal'); // selection of a value is optional and depends on your use case
$('#yourId option:not(:selected)').attr('disabled', 'disabled'); // you may also want to stuff in .prop('disabled', 'disabled') in there somewhere if you need (I can't think of why!)
$("#yourId").trigger('change'); // inform select2 of attribute changes
Anyway, I have moved to the CSS workaround suggested above. All I have to do is toggle the readonly attribute on original <select> element when needed.
We don't have immediate plans to provide this. We are focused to fix some major UI bugs (that are majority of issues and PR's). But if you open a PR with unit tests, I will be glad to review and approve if everything is ok :+1:
This worked well for me:
function controlSelectOpening(){
$("form select").on("select2:opening", function (e) {
if($(this).attr('readonly') || $(this).is(':hidden')){
e.preventDefault();
}
});
}
$(window).bind('load', function(e){
controlSelectOpening();
});
$(document).on('shown.bs.modal', '.modal', function (e) {
controlSelectOpening();
});
Based on Jhonatan299030's solution, I push a bit forward and assume the select2 is wrapped by form-group class div. No color decoration due to readonly should not looks like disabled item. And it works for multiple selection as well
$("form select").on("select2:opening", function (e) {
if($(this).attr('readonly') || $(this).is(':hidden')){
e.preventDefault();
}
});
$(document).ready(function(){
$('select').each(function(){
if($(this).is('[readonly]')){
$(this).closest('.form-group').find('span.select2-selection__choice__remove').first().remove();
$(this).closest('.form-group').find('li.select2-search').first().remove();
$(this).closest('.form-group').find('span.select2-selection__clear').first().remove();
}
});
});
I use this solution:
<style>#SELECTID { pointer-events:none; touch-action:none; }</style>
<script>$(document).ready(function() { $("#SELECTID").select2("readonly", true); });</script>
Here's another simple hack, this time it's JS and CSS free. The typical use for readonly is "I want to show that it's there and the information should be submitted, but it should not be changable". We can achieve this by adding two fields to the form, the first being disabled (thus visible but not editable nor submitted), and the second being hidden (thus submitted but not visible nor editable).
In simple_form and HAML:
- form_for ... do |f|
= f.hidden_field :tree_id
= f.select2 :tree, disabled: true
Most helpful comment
Why would it be any different from all the other form input fields? All the other
readonlyinput fields send data but you can't edit, but no one is worrying about validating them. Why not just removereadonlyfrom everything then?You shouldn't worry if it's being validated, that's the developers job to do it, or not. Let them decide what makes most sense.
I thought select2 was to enhance
<select>and fix the flaws it has.How many people have to use disable select, hidden input and javascript to fix that one thing.