how to preserve all select elements selected values in jquery - javascript

Can you help me to solve this problem.
The problem is this.
I have multiple select lists with same class name but different ids. If user select same option which is already selected in other select list then there should be an alert. and after alert the current select list which is clicked or changed should be restore to the previous value. for example we have 3 select boxes name as A1, A2, A3. Each one have same values for example 1,2,3,4. A1 selected value is 1, A2 selected value is 2 and A3 selected value is 3. Now if your want to change A1 value from 1 to 2 then there should be an alert like "Already selected". After this alert A1 list should be restored back to its original value which is 1. I tried the following code. In this code I can get already existing alert but the value of the last changes select box is changed to new one.
$(document).ready(function(){
var init = true;
if(init == true){
var a = new Array();
$(".brand-list").each(function(i, obj){
var current_obj_id = $(this).attr('id');
var current_obj_value = $('#'+ current_obj_id + " option:selected").val();
a[current_obj_id] = current_obj_value;
});
init = false;
}
$(".brand-list").change(function(){
a[$(this).attr('id')] = $('#'+ $(this).attr('id') + " option:selected").val();
var current_selected_obj_id = $(this).attr('id');
var current_selected_obj_value = $('#'+ $(this).attr('id') + " option:selected").val();
$(".brand-list").each(function(i, obj){
var current_obj_id = $(this).attr('id');
var current_obj_value = $('#'+ current_obj_id + " option:selected").val();
if(current_obj_id != current_selected_obj_id){
if(current_selected_obj_value == current_obj_value){
alert("current element global value: "+ a[current_selected_obj_id]);
$('#'+ current_selected_obj_id + " option[value=" + a[current_selected_obj_id] +"]").attr('selected','selected')
alert("already selected");
}
}else{
a[current_obj_id] = current_obj_value;
}
});
});
$( ".brand-list" ).focus(function() {
var current_selected_obj_id = $(this).attr('id');
var current_selected_obj_value = $('#'+ $(this).attr('id') + " option:selected").val();
a[current_selected_obj_id] = current_selected_obj_value;
console.log(a[current_selected_obj_id]);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<select id="inputBrand-1" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1" selected="selected">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="inputBrand-2" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1">1</option>
<option value="2" selected="selected">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="inputBrand-3" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected="selected">3</option>
<option value="4">4</option>
</select>
Hopefully you can understand my question, because I'm not get to ask question which community members can understand easily. Thanks

You can save the previous value and check it then
$(document).ready(function(){
var init = true;
if(init == true){
var a = new Array();
$(".brand-list").each(function(i, obj){
var current_obj_id = $(this).attr('id');
var current_obj_value = $('#'+ current_obj_id + " option:selected").val();
a[current_obj_id] = current_obj_value;
});
init = false;
}
function hasConflict(input){
var conflict = false;
$(".brand-list").not(input).each(function(i, obj){
if($(this).val()==input.val()){
conflict = true;
return false; //break the loop
}
});
return conflict;
}
$(".brand-list").change(function(){
var $this = $(this); //recycle object
if(hasConflict($this)){
$this.val($this.data('prev'));
alert("Conflict"); //do whatever
}
});
$( ".brand-list" ).on('click focus',function() {
$(this).data('prev',$(this).val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<select id="inputBrand-1" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1" selected="selected">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="inputBrand-2" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1">1</option>
<option value="2" selected="selected">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="inputBrand-3" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected="selected">3</option>
<option value="4">4</option>
</select>

Rather than annoy user by letting them select something and be told they can't it's better UX to either disable previous selections or remove them completely.
Here's an approach that manages the filtering/removing of other selections
var $selects = $(".brand-list"),
// store a cloned set of all options
$storedOptions = $selects.first().children().clone().removeAttr('selected'),
// whether to always include "SELECT A BRAND"
alwaysShowDefault = true;
$selects.change(function() {
// create array of all the selected values
var allValues = $selects.map(function() {
return $(this).val()
}).get();
// loop through each select to create filtered options
$selects.each(function(i) {
// new set of cloned and filtered options for this select instance
var $opts = $storedOptions.clone().filter(function() {
if(+this.value === -1){
return alwaysShowDefault || +allValues[i] === -1;
}
return allValues[i] === this.value || allValues.indexOf(this.value) === -1;
});
// update filtered options and reset current value
$(this).html($opts).val(allValues[i])
})
// trigger one change on page load to filter what is already selected
}).first().change();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<select id="inputBrand-1" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1" selected="selected">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="inputBrand-2" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1">1</option>
<option value="2" selected="selected">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="inputBrand-3" class="brand-list">
<option value="-1">SELECT A BRAND</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3" >3</option>
<option value="4">4</option>
</select>

Actually you'r currently doing is manually setting the selected attribute on each option element. It is not a good approach because it doesn't remove other attributes of options of the same select element. So use following code in your source.
$(e.currentTarget).val(-1);
Replace following code with above one
$('#'+ current_selected_obj_id + " option[value=" + a[current_selected_obj_id] +"]").attr('selected','selected')

Related

How to make 2 JavaScript function's execution mutually exclusive?

I have two select elements with several options, I chain them together so that each updates automatically when the other one changes.
// ########### Linked Labour Select Boxes
$('body').on('change', '#labourList > li .labourerID', function() {
var id = $(this).val();
$(this).parent().find('.labourerName').val(id).change();
});
$('body').on('change', '#labourList > li .labourerName', function() {
var id = $(this).val();
$(this).parent().find('.labourerID').val(id).change();
});
At the moment one method will trigger the other one making my page a bit slow, how can i avoid that?
I have used a flag to communicate that the change that occurred on the select is because of user of the script.
Check this.
When the user changes one select nothing is executed in second select so the change chain is broken.
var script_triggred_change = false;
$("#one").change(function() {
console.log("Called One");
if (script_triggred_change) return;
script_triggred_change = true;
$("#two").val($("#one").val()).change();
script_triggred_change = false;
});
$("#two").change(function() {
console.log("Called Two");
if (script_triggred_change) return;
script_triggred_change = true;
$("#one").val($("#two").val()).change();
script_triggred_change = false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id="one">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select id="two">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
Try this
var once = false;
$('select').on('change', function(e) {
if(once) {
once = false;
return;
}
once = true;
$('select').not(this).val($(this).val()).change();
});
select, option {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<select class="lab-ids">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select class="lab-name">
<option value="1">Peter</option>
<option value="2">Hans</option>
<option value="3">Fritz</option>
<option value="4">Sandra</option>
<option value="5">Jessy</option>
</select>
</div>

3 dropdowns limit total to 8 via jQuery

I have 3 dropdowns every dropdown has 8 options. Now my goal is to limit the combined value of these 3 dropdowns to 8. So for example if you pick 7 in the first you can only select 1 in the next two if you select 1 in the second you can't select anything in the third.
I am trying to achieve my goal by disabling certain options, but there is a flaw in my logic. I can't change my selected option once I've selected one because I've disabled the options. Anyone knows how I can fix this problem?
Thanks in advance.
Here is a jsfiddle as example of my code:
https://jsfiddle.net/k7krx87L/4/
My jQuery code:
$(".options select").change(function() {
var value1 = $("#input_1_5").val();
var value2 = $("#input_1_6").val();
var value3 = $("#input_1_7").val();
var sum = parseInt(value1) + parseInt(value2) + parseInt(value3);
var rest = 9-sum;
$("#input_1_6 > option").slice(rest,9).each(function() {
$(this).attr("disabled", true);
});
var rest2 = rest - 9
$("#input_1_7 > option").slice(rest2,9).each(function() {
$(this).attr("disabled", true);
});
});
You need to have a variable check to see which items to be enabled like
var $selects = $(".options select").change(function() {
var sum = 0;
$selects.each(function() {
sum += +this.value;
});
var rem = 9 - sum;
$selects.each(function() {
var max = +this.value + rem;
$(this).find('option').prop('disabled', function() {
return +this.value > max;
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="options">
<select name="" id="input_1_5">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
<select name="" id="input_1_6">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
<select name="" id="input_1_7">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</div>
In your code you have to take ele from loop and it will work
$(".options select").change(function() {
var value1 = $("#input_1_5").val();
var value2 = $("#input_1_6").val();
var value3 = $("#input_1_7").val();
var sum = parseInt(value1) + parseInt(value2) + parseInt(value3);
var rest = 9-sum;
$("#input_1_6 > option").slice(rest,9).each(function(index, ele) {
$(ele).attr("disabled", true);
});
var rest2 = rest - 9
$("#input_1_7 > option").slice(rest2,9).each(function(index, ele) {
$(ele).attr("disabled", true);
});
});

jQuery select option last doesn't work

I've got a button and list of options. The idea is that when user clicks the button the default option changes from disabled to max value. And oposite - if the input is not checked, the default is again disabled.
But the value returns undefined. If I change the first and thelast to numeric values, everything works fine. What's wrong?
<input class="input" type="checkbox" value="1" name="select-pot[]">
<select id="select" name="q-count[]">
<option disabled selected> -- choose -- </option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
jQuery(function(){
jQuery(".input").click(function(){
var thefirst = jQuery(this).next('#select option:first').val();
var thelast = jQuery(this).next('#select option:last').val();
if( jQuery(this).is(':checked') )
jQuery(this).next('#select').val(thelast);
else
jQuery(this).next('#select').val(thefirst);
});
});
.next() gets the next sibling, so you need to get the select and use .find() or .children() afterwards:
var thefirst = jQuery(this).next('#select').find('option:first').val();
var thelast = jQuery(this).next('#select').find('option:last').val();
Since IDs must be unique, there's no point in doing something like:
jQuery(this).next('#select option:first')
when
jQuery('#select option:first')
would suffice, plus .next() would fail here since it evaluates the siblings of an element and filters on anything you pass, but your filter is what would cause it to not match anything.
Instead, use:
jQuery(".input").click(function () {
var thefirst = jQuery('#select option:first').val();
var thelast = jQuery('#select option:last').val();
if (jQuery(this).is(':checked')) jQuery('#select').val(thelast);
else jQuery('#select').val(thefirst);
});
jsFiddle example
The vanilla javascript alternative for future viewers
(function () {
"use strict";
var inputs = document.getElementsByClassName('input'), input;
for (var i = 0; input = inputs[i]; i++) {
input.addEventListener('click', function (e) {
e.target.nextElementSibling.lastElementChild.selected = e.target.checked;
e.target.nextElementSibling.firstElementChild.selected = !e.target.checked;
}, false);
}
})();
<input class="input" type="checkbox" value="1" name="select-pot[]">
<select id="select" name="q-count[]">
<option disabled selected>-- choose --</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>

5 select boxes, hide values on each selected item

I have select boxes, I would like to hide (delete) items from options that are already selected:
<select name="gets" class="gets">
<option value="0">SELECT</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select name="gets" class="gets">
<option value="0">SELECT</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select name="gets" class="gets">
<option value="0">SELECT</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<select name="gets" class="gets">
<option value="0">SELECT</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
So if I choosed option 1 from 1st select box, it should disappear from the rest, if I choose option 3 on select box 4, it should disappear from the rest
Thanks in advance
Say like below:
$('.gets').change(function(){
var value = $(this).val();
$('.gets').not(this).find('option[value="'+value+'"]').hide();
})
DEMO
If you want to exclude for SELECT option say like below
$('.gets').change(function(){
var value = $(this).val();
if(value!=0)
$('.gets').not(this).find('option[value="'+value+'"]').hide();
})
You'll need to find all the options with the same value in the other select's and hide them.
I would use something like this:
var selects = $('select');
selects.bind('change', function(e) {
var val = this.value;
//show all options
selects.find('option').show();
selects.each(function() {
if(!this.value) return;
//hide the selected value in the other selects
selects.find('option[value="' + this.value + '"]')
.filter(':not(:checked)')
.filter(':not([value="0"])')
.hide();
});
});
Example
You can try this:
$("select").on("change", function(){
var selectVal = $(this).val();
$("select").not($(this)).find("option[value="+ selectVal +"]").remove();
});
fiddle

jQuery/ Javascript change select options based on selected answer

I have the following code:
<table>
<tr><td>Item</td><td>Ranking</td></tr>
<tr><td>Apples</td><td><select id="apple" name="apple">
<option value="#" selected="selected">Rank...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select></td></tr>
<tr><td>Oranges</td><td><select id="oranges" name="oranges">
<option value="#" selected="selected">Rank...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select></td></tr>
<tr><td>Bananas</td><td><select id="bananas" name="bananas">
<option value="#" selected="selected">Rank...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select></td></tr>
<tr><td>Lemons</td><td><select id="lemons" name="lemons">
<option value="#" selected="selected">Rank...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select></td></tr>
<tr><td>Limes</td><td><select id="limes" name="limes">
<option value="#" selected="selected">Rank...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select></td></tr>
<tr><td>Kiwi</td><td><select id="kiwi" name="kiwi">
<option value="#" selected="selected">Rank...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select></td></tr>
And here in jsFiddle: http://jsfiddle.net/XNYU2/
I'm trying to understand if this is possible and, if so, whether jQuery or Javascript is the best solution and how I'd go about making it happen.
It's a ranking system and what I need to happen is simple. If a user selects from any dropdown any value, that value needs to be removed from the other dropdowns. Conversely, if the user then unselects that value, it needs to return to all the dropdowns.
Try this:
$(function() {
$('select').on('change', function(event){ // This binds listeners to the change event on all the select elements
var sId = this.id; // store off the changed element id
var vId = this.value; // store off the changed element value
$('select').each( function(){ // this loops across the same set of elements
if(this.id != sId && this.value == vId) { // If it is not the triggering element and the value is the same, do something
this.options.selectedIndex = 0; // reset the value to 'rank'
}
});
});
});
You can do this in either jQuery or pure js, but jQuery selectors sure make it easy to loop through the elements and apply actions on change with very little code.
Upon re-reading you question, this accomplishes the same thing but slightly differently; the user is forced to have only 1 set of ordered ranking with no overlap, but we don't have to go to the trouble of removing/adding options.
Yes, this is a task for JavaScript. jQuery isn't an alternative to JavaScript but basically a toolset on top of it that makes manipulation of browser elements easier. I recommend using it, even though you'll need to understand JavaScript basics in order to use it effectively.
The key here is to decompose your problem; one is to perform an action once a Select has been changed. See here how this is done: http://api.jquery.com/change/
The second action is to actually implement the change, which is described e.g. here
Removing an item from a select box
The jsFiddle is here and that's the code:
var SelectOptions = ['Rank...', 1, 2, 3, 4, 5];
$(document).ready(function () {
$('#TheTable').find('select').change(function () {
var TheSelectedValue = parseInt($(this).val(), 10);
var TheSelectID = $(this).prop('id');
var TheHTML = "";
for (var i = 0; i < SelectOptions.length; i++) {
if (SelectOptions[i] !== TheSelectedValue) {
TheHTML = TheHTML + '<option value="';
TheHTML = (i === 0) ? TheHTML + '#' : TheHTML + SelectOptions[i];
TheHTML = TheHTML + '">' + SelectOptions[i] + '</option>';
}
}
$('#TheTable').find('select').each(function () {
if ($(this).prop('id') !== TheSelectID) {
$(this).html(TheHTML);
}
});
});
});
That's just one way to do it: I put it together in a few minutes and I'm sure it can be improved but that should get you started.

Categories