Dynamically disabling <option> elements based on amount selected - javascript

I have provided a user with an interface where they can select from 30 options(hardcoded), displayed in a bootstrap dualListBox.
This works perfectly however I would like to set the max amount of options that can be selected to 10.
After which, all the options that could have been selected on the left side, become disabled.
Should the user remove a selected option, the others can then become available for selection again.
I realize that I will be using jquery to achive this, however I am unsure as to how I will count the amount selected and how I will target remaining selections to disable or make them available again.
Is there any advice on how to correctly solve this problem?
The plugin I am using for the dual listbox can be found here:
Bootstrap dualListBox

First I would bind a change event, then I would check if the number of selected items is equal or exceeds then max number of elements, if so I will disable it.
If I understand your question correct it would be something like:
$('#selector-id').on('change', function(e){
var selectedElements = $(this).val();
if(selectedElements && selectedElements.length >= 10){
$(this).prop('disabled', true);
} else {
$(this).prop('disabled', false);
}
});
(This is not tested code)

Related

Unable to deselect 'select multiple' options with selection counter and optgroups

I'm using the code from the accepted answer here
How do you limit options selected in a html select box?
to count the selected options in a 'select multiple' menu:
var last_valid_selection = null;
$("#select_options").change(function(event) {
if ($(this).val().length > 10) {
$(this).val(last_valid_selection);
} else {
last_valid_selection = $(this).val();
$("#select_options_text").text("Please select at least one, and up to ten options. You have currently selected "+$(this).val().length);
}
});
The menu is divided into six optgroups. When I hit 10 selections I can no longer make selections, as expected. But I can also no longer use CTRL+click on selected options to deselect them.
If I remove all optgroups, the menu functions correctly. It also functions correctly with one and two optgroups. It only seems to be when a third optgroup is added that the problem described above appears.
I have tested in Chrome and Firefox and the problem occurs in both.
Problem
You have duplicate options, so when try to restore the last selection by calling $(this).val(last_valid_selection), you could be selecting more than one value than you actually want (i.e. you end up selecting more than 10).
For example, you have more than one Biochemistry, so when last_valid_selection contains one instance of Biochemistry, all the duplicate Biochemistry options will be selected.
Solution
Use a different way of remembering the last valid selections.
Here I present a solution using data attribute and individually store whether or not an option has been previously selected.
function save_selected(select){
$(select).find("option").each(function(){
var t = $(this);
t.data("last-selected", t.is(":selected"));
});
};
function load_selected(select){
$(select).find("option").each(function(){
var t = $(this);
t.attr("selected", t.data("last-selected"));
});
};
$("#select_options").change(function(event) {
if ($(this).val().length > 10) {
load_selected(this);
} else {
save_selected(this);
}
});
Using this method, each individual option element has its own "last selected" state stored in its own data attribute. There would be no duplicate conflicts.
Demo: https://jsfiddle.net/alan0xd7/gzdrL5wu/12/

How to set the value of a select box when it is enabled only?

I have a top level select box that when a user makes a selection here, I want this value to be used for all the below select boxes relating to this top level box.
The problem I am having is that, if any one of the lower select boxes is disabled, I want the above process to ignore this select box as it has already been assigned a value.
Obviously, if the lower select box is enabled then I want to assign the top select value to it.
To disable the select list based on a particular value, I have used:
$("select[name=f03]").eq(index).attr('disabled', 'disabled');
Here is the jQuery that I have used but is not working:
var top_select = $("select[name=f07]").val();
$("select[name=f03]").each(function(index){
if $("select[name=f03]").eq(index).is(':enabled'){
$("select[name=f03]").eq(index).val(top_select);
}
});
From this code, it is the lower selects ([name=f03]) that I am trying to set only when it is enabled.
First I would disable select like this:
$("select[name=f03]").eq(index).prop('disabled', true);
Second, your function should be much simpler:
$("select[name=f03]").each(function(){
if ($(this).prop('disabled')) return;
$(this).val(top_select);
});
you should use jquery :enabled selector as follow
$("select[name=f03]:enabled").each(function(){
//execution
});
or
$("select[name=f03]:enabled").val("value");
here is jsfiddle example http://jsfiddle.net/kso2oqr5/1/
When you are disabling elements use .prop(property,value)
var top_select = $("select[name=f07]").val();
$('select[name="f03"]').val(function(){
if(!this.disabled){
return top_select;
}
});
DEMO

Disabling the select tag field

I'm having trouble figuring out how to disable a select tag but keeping the selected value visible. The only solution I've found was to remove the items that should not be displayed. The use is that when a user created a new item and selects an option, the people viewing the created item should not be able to change it. Greying out text boxes has proved to be pretty simple but I don't know how to proceed with select tags.
This is how I do it right now but not exactly since this code follows a progression and gives editors different options depending on the stage they're in. However, other choice fields won't change through the process, they just need to remain what they were on creation.
//On item edit, set status to In Progress if in New
if($("option[value='New']").attr("selected") == "selected"){
//Disable New/Completed/Cancelled
$("option[value='New']").remove();
$("option[value='Completed']").remove();
$("option[value='Cancelled']").remove();
//Enable In Progress
$("option[value='In Progress']").attr("selected","selected");
//Call Claim WO Function
claimOrder();
}else if($("option[value='In Progress']").attr("selected") == "selected"){
//Remove New option
$("option[value='New']").remove();
$("option[value='In Progress']").remove();
$("option[value='Completed']").attr("selected","selected");
}else if($("option[value='Completed']").attr("selected") == "selected"){
//Remove New/In Progress option when Completed/Cancelled
$("option[value='New']").remove();
$("option[value='In Progress']").remove();
$("option[value='Cancelled']").remove();
}else if($("option[value='Cancelled']").is(':selected')){
//Remove New/In Progress option when Completed/Cancelled
$("option[value='New']").remove();
$("option[value='In Progress']").remove();
$("option[value='Completed']").remove();
}
what about disabling like this
box.attr('disabled', 'disabled')

Binding Buttons to several text boxes actived based on size of values in text box

I am building a site where people can customize the shape of their product before they order it.
Ultimately there will be several buttons bound to four text boxes. As the user inputs higher values in the text box, the button that is activated changes so we know what size sheet of material will need to be ordered for this customer's design.
How can I create a button that is enabled/disabled based on the value placed in a text box?
You can use jQuery and try something like this:
First, give your buttons an attribute disabled="disabled", and then:
//Assuming they are typing, if it's a dropdown/select, see below
$('#input-id').on('keyup', function() {
if($(this).val() >= 10 && $(this).val() <= 20) { // If the value is between 10 and 20...
$('#button-id').removeAttr('disabled'); // Remove disabled attribute
} else { // If the value is not our keyword...
if(!$('#button-id').attr('disabled')) { // And the button is not disabled...
$('#button-id').attr('disabled', 'disabled'); // Readd disabled attribute
}
}
});
If you are using a dropdown or select box, use $("select option:selected").

How to trigger an event ONLY if both dropdowns are selected?

I have a dropdown select list on my page of class="TypeFilter".
I have a jQuery event that fires when a value in that list is selected.
$(".TypeFilter").change(function()
{
// Extract value from TypeFilter and update page accordingly
));
I now have to add another list to the page, and I want to implement functionality which will prevent the .change(function() from running unless both are selected.
In both lists the first option in the list is some text instructing the user to select one of the items, so I was thinking of just writing some logic to test that both lists have a selected index greater than 0.
I think this is a touch unclean though, especially considering that other pages that have a TypeFilter use the same logic.
Is there any nifty functionality in jQuery that can do this?
edit I should specify that the user needs to be able to update the page by selecting either dropdown, so I can't put the onchange on the second element and test that the first element has a selected value, as suggested in one of the answers
If you bind the same event to all dropdowns, you can get a collection of all the dropdowns and check that all of them are selected. Example:
$('.Dropdown').change(function(){
var elements = $('.Dropdown');
if (
elements.filter(function(){
return this.selectedIndex > 0;
}).length == elements.length
) {
// all dropdowns are selected
}
});
As you partly mention, put the onchange on the second element and test that the first element has a selected value before you fire off any logic.
Use bind instead, and as the eventdata, send a function that checks that either that both are selected or that the other is selected. Untested code:
function checker() {
// test your conditions
}
$(".TypeFilter").bind('change', {test: checker}, function(event)
{
if (event.data.test && event.data.test()) {
// Extract value from TypeFilter and update page accordingly
}
));
This way the other pages that use the same function will not notice any changes.

Categories