In Jquery Chosen plugin remove selection if user selects a particular value - javascript

I have the following multi select and I am using Jquery Chosen plugin
<select multiple="multiple" class="chzn-select span3" name="requestCategory" id="requestCategory">
<option selected="selected" value="">All</option>
<option value="2">Electrical</option>
<option value="4">Emails</option>
<option value="3">Filming Permits</option>
<option value="10">test1</option>
</select>
Client wants to make sure that i do not allow user to select ALL if any other value is selected or if user selects any other value then automatically deselect/remove ALL; because ALL = all categories so having individual option does not make sense. How do i do this?

Check if more than one item is selected, or if only one item is selected that it is not the first one - in these cases disable All.
$('.chzn-select').on('change', function() {
var selectedOpts = $('option:selected', this);
if(selectedOpts.length > 1 || selectedOpts.first().index() !== 0) {
$('option', this).first().attr('disabled', 'disabled');
}
});​
http://jsfiddle.net/zCk2z/5/

at first change of option [simple] removes the All category.
but i recomand to disable the item, it looks better use .attr('disabled', 'disabled') instead of .remove();
$('#requestCategory').change(
function(){
$(this).find('option:contains("All")').remove()
})

Related

When one option is selected all others should be disabled

I have a dropdown menu that allows multiple selections. Now I want to make it when one particular option has selected all others to be disabled and enabled for selection. If that one particular is de-selected all others should be enabled again.
This is my select dropdown:
<select class="input-fields selectpicker" id="select_heigh" name="search[]" multiple>
<option value="all" selected>Search all</option>
<option value="tag">Tags</option>
<option value="username">Username</option>
<option value="email">Email</option>
<option value="full_name">Full Name</option>
</select>
And here is what I have tried for the js
$(document).ready(function() {
$('.selectpicker').selectpicker();
$('.selectpicker').on('change', function() {
if ($('option[value="all"]', this).is(':selected') && $(this).val().length > 1) {
$('option[value="all"]', this).prop('selected', false);
$('.selectpicker').selectpicker('refresh');
}
var selected = $(this).val();
if (selected.includes("tag")) {
$('option[value!="tag"]', this).prop('disabled', true);
} else {
$('option[value!="tag"]', this).prop('disabled', false);
}
if (selected.length > 3) {
$(this).selectpicker('setStyle', 'selected-count', 'btn-danger');
$(this).selectpicker('setTitle', selected.length + ' select(s)');
} else {
$(this).selectpicker('setStyle', 'selected-count', 'btn-default');
$(this).selectpicker('setTitle', 'Select');
}
});
});
I want when "Tag" is selected the other options to be disabled. When "Tag" is de-selected the others are enabled. When any other option is selected to no effect on others.
Also, the counting of selected choices doesn't work as expected. It should start showing Selected(3), Selected(4) ... after the third selection. Currently, it shows all of them not count of them.
I'm not that familiar with JS and not sure if I'm on the right path here
What the OP wants to achieve is a rather unexpected behavior of a native form control.
And in case one changes the behavior it should be based on using what form elements or elements in particular do support natively like the disabled- and the dataset-property.
An implementation then could be as simple as querying the correct select element and subscribing an event listener to any click event which occurres on the very select element. The change event can not be used since any further changes are impossible once a single option is selected but all other option are disabled. An option element's dataset gets used as lookup in order to detect whether the very element already has been selected before the current click handling.
function handleOptionClickBehavior({ target }) {
const optionNode = target.closest('option');
const nodeValue = optionNode?.value;
if (nodeValue === 'tag') {
const optionNodeList = [...optionNode.parentNode.children]
.filter(node => node !== optionNode);
const { dataset } = optionNode;
if (dataset.hasOwnProperty('selectedBefore')) {
Reflect.deleteProperty(dataset, 'selectedBefore');
optionNode.selected = false;
optionNodeList
.forEach(node => node.disabled = false);
} else {
dataset.selectedBefore = '';
optionNodeList
.forEach(node => node.disabled = true);
}
}
}
document
.querySelector('.selectpicker')
.addEventListener('click', handleOptionClickBehavior)
body { zoom: 1.2 }
<select class="input-fields selectpicker" id="select_heigh" name="search[]" size="5" multiple>
<option value="all" selected>Search all</option>
<option value="tag">Tags</option>
<option value="username">Username</option>
<option value="email">Email</option>
<option value="full_name">Full Name</option>
</select>

How to get value of deselected option?

Suppose I have a select like this:
<select id="cars" multiple>
<option value="1">Ferrari</option>
<option value="2">Lamborghini</option>
</select>
Imagine now that both values are selected, I deselect Ferrari, how can I retrieve the value of the deselected option, so in this case Ferrari?
I tried with:
$('#cars option').on('click', function(){
console.log($(this).val());
});
but the event is never fired, I also tried with change, this is fired, but I get only the selected values not the deselected one.
You could incorporate the usage of a class to track on change which elements are selected, and inversely which ones are no longer selected.
var $cars = $('#cars').on('change', function(){
// find the options that were selected, but are not now
var $deselected = $cars.find('option.selected:not(:checked)');
// add the selected class to the selected options for tracking
$cars.find('option:checked').addClass('selected');
// remove the selected class to untrack them
$deselected.removeClass('selected');
// report which options were deselected
console.log($deselected.get());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="cars" multiple>
<option value="1">Ferrari</option>
<option value="2">Lamborghini</option>
</select>

how to make sure that selected options are different before submit the form?

<select class="distinctrank" name="rank[]" required>
<option value="">Select</option>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>
<select class="distinctrank" name="rank[]" required>
<option value="">Select</option>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>
<select class="distinctrank" name="rank[]" required>
<option value="">Select</option>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>
I am trying to prevent the user to select the same option twice
EX:
value 1 -> B
value 2 -> C
value 3 -> A
But not allow
value 1 -> B
value 2 -> B
value 3 -> A
I can't use this: answer
because I have 8 <select> with 8 <option>and the user is allow to change his/her option.
Unfortunately, I can't use a single select set to "multiple".
I found this answer just now, but since I don't jquery or Javascript well, I can't make it work without the select tag inside a table:
Here is the answer
UPDATE:
I found a better way to do it, but I am having some problems.
I tried to modify this code: with input tags to make it work with select tags. The problem that I am facing now is that every time you select the same option twice, the error "Please enter a Unique Value" show up (I do want to see it, when the user select the same value twice or more) and when you change the value the "Please enter a Unique Value" does go away. But, It keep a "this field is required" warning behind (when a click a new select tag). So, "this field is required" doesn't go away until the user pick an option for all select tag.
Here is the Jquery code:
jQuery.e
jQuery.validator.addMethod("notEqualToGroup", function(value, element, options) {
// get all the elements passed here with the same class
var elems = $(element).parents('form').find(options[0]);
// the value of the current element
var valueToCompare = value;
// count
var matchesFound = 0;
// loop each element and compare its value with the current value
// and increase the count every time we find one
jQuery.each(elems, function() {
thisVal = $(this).val();
if (thisVal === valueToCompare) {
matchesFound++;
}
});
// count should be either 0 or 1 max
if (this.optional(element) || matchesFound <= 1) {
//elems.removeClass('error');
return true;
} else {
//elems.addClass('error');
}
}, jQuery.validator.format("Please enter a Unique Value."))
// validate form
$("#signupform").validate({
rules: {
'rank[]': {
required: true,
notEqualToGroup: ['.distinctrank']
},
},
});
I wonder if you could simply use a single select set to "multiple"...
<select multiple class="form-control" name="rank[]">
<option value="">Select</option>
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
</select>
It seems appropriate :-)
Your code...
rules: {
'rank[]': { // <-- will only match one of your three
required: true, ....
You cannot have three different select element all share the same name, in your case, rank[].
The jQuery Validate plugin requires that every form data input element contain a unique name. It's how the plugin keeps track of the form inputs, and there is no workaround for this. You'll have to include an index or change the name.
rules: {
'rank[1]': {
// rules
},
'rank[2]': {
// rules
},
'rank[3]': {
// rules
}
}
If the same rules are used on all three, then you can use the .rules() method to apply them all at once...
$("#signupform").validate({ // plugin initialization
// other rules & options
});
$('[name^="rank"]').each(function() {
$(this).rules('add', {
required: true,
notEqualToGroup: ['.distinctrank']
});
});
$('[name^="rank"]') matches all elements that have a name that "starts with" rank. Then .each() applies the rule to every instance matched by the selector.
You can try something like this:
$(document).ready(function() {
$('select').change(function() {
self = $(this);
choosen = $(this).val();
$('select').not(self).each(function() {
if ($(this).val() == choosen) {
// $(this).prop('disabled', true);
alert('Option is already selected');
$(self).val($(this).find("option:first").val());
}
});
});
});
This is actually partial implementation of code you found in another answer. Commented line would disable already selected options, but... then users can't change their minds... However i would probably use that commented line (edit:probably not, it causes other problems), rather than annoying alerts -> because, with alerts - if user tries to change his mind - user experience is not so great, again...
DEMO: http://jsfiddle.net/dq9j4s32/2

Hierarchical Select List using jQuery

I have two select list,
Select list 1 contains the Mobile phone brands names
<select name="mobile-phone" class="mobile-phone">
<option value="Select">Select</option>
<option value="Nokia">Nokia</option>
<option value="Samsung">Samsung</option>
<option value="HTC">HTC</option>
<option value="Apple">Apple</option>
</select>
Select list 2 contains the phone type like
<select name="mobile-model" class="mobile-model">
<option value="Select">Select</option>
<option value="Nokia--Lumia-520">Lumia 520</option>
<option value="Nokia--Lumia-620">Lumia 620</option>
<option value="Samsung--Galaxy-s3">Galaxy S3</option>
<option value="Samsung--Galaxy-s4">Galaxy S4</option>
<option value="HTC--hero">Hero</option>
<option value="HTC--one">One</option>
<option value="Apple--iphone4">iPhone 4</option>
<option value="Apple--iphone5">iPhone 5</option>
</select>
My quest is I want to display Select list 2 according to the value users select in Select List 1.
If a user selects Nokia in first selection, then only Lumia phones should be shown in second select list. Like so, for other phones.
When None is selected in First select list, then second select list should not show anything, but still visible without any option (like disabled button).
How can I accomplish this using jQuery?
The JSFiddle I have made from above select list.
I'd suggest:
/* select the select element whose name is "mobile-phone",
assign an event-handler for the 'change' event:
*/
$('select[name="mobile-phone"]').change(function () {
// get the relevant/selected brand-name:
var brand = this.value;
/* find the option elements inside of the select element with
name="mobile-model", enable them all:
*/
$('select[name="mobile-model"] option').prop('disabled', false)
// show them all:
.show()
// filter the collection, to find only those whose value does not start with the brand-name:
.filter(function () {
return !(this.value.indexOf(brand) === 0);
})
// disable those elements:
.prop('disabled', true)
// hide them:
.hide();
});
JS Fiddle demo.
References:
Attribute-starts-with ([attribute^="value"]) selector.
filter().
hide().
prop().
show().
I think you are looking for:
$("#sel2").prop("disabled", true);
$( "#sel1" ).change(function() {
var value = $(this).val();
$("#sel2").prop("disabled", false);
$("#sel2 > option").hide();
$("#sel2 > option[value*='" + value +"']").show();
});
Only I put to selects Id for do the selection by Jquery more easy. Before I disabled the control wating for any selection, and when the first select change only I keep the option that macth with option[value*='" + value +"']".
Live demo here
There is a jQuery plugin that handles this exact case very nicely: http://www.appelsiini.net/projects/chained .
You should consider having two MySQL tables: brand, model. The brand table would just be a list of brands with IDs. The model table would contain a brand column where you input those IDs.
Then you should do a JSON query for the brand selected, and return a select list accordingly.
By doing it this way, you'll have an in depth database that you can call and manipulate in numerous ways.
Alternatively, you could do something like:
$(".mobile-phone").on("change", function(){
var brand = $(this).val();
$("[data-brand]").hide();
$("[data-brand="+brand+"]").show();
});
And do this:
<option data-brand="Nokia" value="...

Set selected value in multiple select list

I have this multi select list:
<select id="vendors" name="vendors" multiple="multiple">
<option value="1">A</option>
<option value="2">B</option>
<option value="3">C</option>
<option value="4">D</option>
<option value="5">E</option>
</select>
When the page loads, I'm loading a list of ids that need to be selected in my select list. Here's how I'm trying to do it:
var vendors = GetVendorArray(); // list of vendor ids I want selected
$.each(vendors, function(index, item) {
$("#vendors").filter(function() {
return $(this).val() == item;
}).attr('selected', true);
});
But this doesn't work, none of the items are being selected. Anyone know what I'm doing wrong?
Simplest approach is just pass the whole array as value to the select using val(). With mulitple select value is an array
$('#vendors').val( GetVendorArray())
DEMO:http://jsfiddle.net/sPKAY/
The problem with approach you took was not looping over option tags
filter reduces the set of matched elements to match the additional selector/callback fn. output. You need to target the <option> elements, not the drop-down list itself, since you're trying to select the option based on whether its value matches your array contents.
var vendors = GetVendorArray(); // list of vendor ids I want selected
$.each(vendors, function(index, item) {
//you're filtering options, not the list itself
$("#vendors > option").filter( function() {
return $(this).val() == item;
}).prop('selected', true); //use .prop, not .attr
});

Categories