How to target outside $(this) in jQuery - javascript

I'm trying to use $('.selector').on('change', function(){}) then inside of it, I added each. What I want is to target the current .selector, if the current item is already selected then make it empty so you can select other item; there are multiple <select class='selector'> elements in the DOM. Please see my code below.
$(document).ready(function(){
$('.selector').on('change', function(){
var currentSelect = $(this).val();
if(currentSelect == ''){
$('.selector').each(function(){
if(currentSelect == $(this).val()){
alert("Sorry, you cannot select that item again.");
$(this).val('');
}
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<select class="selector">
<option></option>
<option value="Apple">Apple</option>
<option value="Mango">Mango</option>
<option value="Banana">Banana</option>
<option value="Watermelon">Watermelon</option>
</select>
<br><br>
<select class="selector">
<option></option>
<option value="Apple">Apple</option>
<option value="Mango">Mango</option>
<option value="Banana">Banana</option>
<option value="Watermelon">Watermelon</option>
</select>
<br><br>
<select class="selector">
<option></option>
<option value="Apple">Apple</option>
<option value="Mango">Mango</option>
<option value="Banana">Banana</option>
<option value="Watermelon">Watermelon</option>
</select>
<br><br>
<select class="selector">
<option></option>
<option value="Apple">Apple</option>
<option value="Mango">Mango</option>
<option value="Banana">Banana</option>
<option value="Watermelon">Watermelon</option>
</select>

You need 2 loops at each change events here.
to get all selected values.
to hide all values already selected from the other <select> elements.
Simple as that.
$(document).ready(function(){
var selected = []; // Global scope array.
$('.selector').on('change', function(){
var currentSelect = $(this).val();
var selected = []; // Array reset
$('.selector').each(function(){
var val = $(this).val();
if(val!=""){
selected.push($(this).val()); // Array fill
}
});
console.log(selected);
$('.selector option').each(function(){
if($.inArray($(this).val(),selected)!=-1){ // If not in array: hide
$(this).hide();
}else{
$(this).show();
}
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<select class="selector">
<option></option>
<option value="Apple">Apple</option>
<option value="Mango">Mango</option>
<option value="Banana">Banana</option>
<option value="Watermelon">Watermelon</option>
</select>
<br><br>
<select class="selector">
<option></option>
<option value="Apple">Apple</option>
<option value="Mango">Mango</option>
<option value="Banana">Banana</option>
<option value="Watermelon">Watermelon</option>
</select>
<br><br>
<select class="selector">
<option></option>
<option value="Apple">Apple</option>
<option value="Mango">Mango</option>
<option value="Banana">Banana</option>
<option value="Watermelon">Watermelon</option>
</select>
<br><br>
<select class="selector">
<option></option>
<option value="Apple">Apple</option>
<option value="Mango">Mango</option>
<option value="Banana">Banana</option>
<option value="Watermelon">Watermelon</option>
</select>

If I understood your question correctly, this would be the answer. By using $(this), you are applying whatever change to all select elements on the page. You want to do it just for the one that was clicked. For that reason, you should be very careful with $(this) and use $(event.target) instead. Read more about the differences here:
Difference between $(this) and event.target?
$(document).ready(function(){
$('.selector').on('change', function(e){
var currentSelect = $(e.target).val(); // if you need to pass/submit the value somewhere later
$(e.target).attr('disabled', 'disabled');
});
});
Why not simply disable the target element? You can still see what was selected and the user cannot click it again.

This solution is a little bit messy, but it works
$(document).ready(function(){
$(".selector").on("change", function(){
var currentSelect = $(this).val();
$(this).siblings().on("change", function(event){
if(currentSelect == $(this).val()){
$(this).val('')
alert("Sorry, you cannot select that item again.");
}
});
});
});

There isn't really a reason to loop through .each here.
What you can do, is .on('change') create an array of all values of elements with the .selector class. Then once you have that array, check how many instances there are of the element that was just selected. If that number > 1, then that selection has already been made in a different .selector element.
Working Pen:
https://codepen.io/anon/pen/WLvzMM
$(document).ready(function(){
$('.selector').on('change', function(){
// Put the value of all elements with the class of `.selector` into an array
var all = $.map($('.selector'), function (el) { return el.value; });
// Get value of the change that was just made
var currentSelect = $(this).val();
// Get the number of occurences of the value that was just selected
var occurences = $.grep(all, function (elem) {
return elem === currentSelect;
}).length;
// If there is more than one occurence (the one that was just selected), then prevent the selection.
if(occurences > 1){
alert("Sorry, you cannot select that item again.");
$(this).val('');
}
});
});

Related

javascript - Hide Options from Multiple Selection Box when an option from another select is selected

I need your help. So what I want to do is when a user select an option from one select, automatically hide an option from another multiple select.
Example:
if a user choose Car from select A, I want the car option from the select B to be automatically removed or hidden.
select A:
<select name="my_option_one" required id="id_my_option_one">
<option value="" selected>Choose..</option>
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
Select B:
<select name="my_option_two" id="id_my_option_two" multiple="multiple">
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
This is what I have tried but none of it worked.
$(document).ready(function() {
$("#id_my_option_one").change(function() {
if ($(this).val() === 'C') {
$("#id_my_option_two option[value='C']").options[0].remove();
$('select[name=my_option_two] option:eq(1)').hide();
$("#id_my_option_two option[value=" + 'C' + "]").hide();
$("#id_my_option_two option[value='C']").attr('disabled','disabled').hide();
}
});
});
function my_optionsChange() {
$("#id_my_options_two option").show(); //.css("display", "block");
$("#id_my_options_two option[value='" + $("#id_my_options").val() + "']").hide();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<select name="my_options" required id="id_my_options" onchange="my_optionsChange()">
<option value="" selected>Choose..</option>
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
<select name="my_options_two" id="id_my_options_two" multiple="multiple">
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
I made an example which is longer because it's split into parts so you understand better what is going on.
I tried to name the variables so that it's clear what they are, but if you have any questions, please ask in the comments.
Let me know if this works for you.
const firstSelect = $('#id_my_options')
const secondSelect = $('#id_my_options_two')
firstSelect.on('change',function() {
const selected = $(this).find('option:selected');
const selectedValue = selected.val()
const secondOptions = secondSelect.children();
secondOptions.each(function() {
const secondValue = $(this).val()
secondValue === selectedValue ? $(this).hide() : $(this).show()
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="my_options" required id="id_my_options">
<option value="Choose" selected>Choose..</option>
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
<select name="my_options_two" id="id_my_options_two" multiple="multiple">
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
<select name="my_options" id="firstblock" onchange="disable(2,this.value);">
<option value="" selected>Choose..</option>
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
<select name="my_options" id="secondblock" onchange="disable(1,this.value);">
<option value="" selected>Choose..</option>
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
<script>
function disable(needtoblock,val){
console.log(needtoblock+" "+val);
if(val != ""){
if(needtoblock == 1){
$("#firstblock option[value='"+val+"']").prop('disabled', true);
}else if(needtoblock == 2){
$("#secondblock option[value='"+val+"']").prop('disabled', true);
}else{
}
}else{
$("#secondblock option").prop('disabled', false);
$("#firstblock option").prop('disabled', false);
}
}
</script>
This is how code could look, definetly you need to update and make it suitable for you.
I know, this is a bit late, but maybe it is of interest to someone out there. I understood the demand of OP so, that the hiding of options was to be done in any direction, or potentially spanning over multiple selector boxes. The following script will do exactly that: if you select an option in one selector it will go through the other selectors of the defined group $grp (by doing $grp.not(this).each((i,trg)=> ...)) and will hide/show all options there, depending of whether thay have been selected elsewhere already.
The $(to).toggle(...) method sets the visibility of each option (to) within trg, based on the existence of selected options with the same value in the sibling selectors of trg (again, limited to the current group $grp).
Maybe the script is a little too condensed for easy reading but it shows how much you can achieve with very little code when you use the power of jQuery.
const $grp=$('select[id^=id_my_options]') // define the selector group
$grp.on('change',function(ev){ // bind the change event ...
$grp.not(this).each((i,trg)=> // work on each sibling-selector (trg) of clicked
// selector (this), but only within jquery
// selection $grp
$('option[value!=""]',trg).each((j,to)=> // for all options of sibling-selectors of
// trg (within jquery selection $grp):
$(to).toggle($grp.not(trg).find('option[value='+to.value+']:selected').length==0))
// toggle the visibiltiy of that option
)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="my_options" required id="id_my_options">
<option value="" selected>Choose..</option>
<option value="C">Car</option>
<option value="H">House</option>
<option value="A">Airplane</option>
</select>
<select name="my_options_two" id="id_my_options_two" multiple="multiple">
<option value="C">Car2</option>
<option value="H">House2</option>
<option value="A">Airplane2</option>
</select>
<select name="my_options_three" id="id_my_options_three" multiple="multiple">
<option value="O">yet another option</option>
<option value="C">Car3</option>
<option value="H">House3</option>
<option value="A">Airplane3</option>
</select>
<br><br>
<select name="my_options_four" id="id_your_options_four" multiple="multiple">
<option value="O">and some unrelated options</option>
<option value="C">Car3</option>
<option value="H">House3</option>
<option value="A">Airplane3</option>
</select>

Change value of select list with value of another select list jquery

How can I change the value of a select list with the value of another select list
<select class="main-filter" id="Test1" name="Test1"><option value="">Select Option</option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
Need to replace #ReplaceThisText# with value selected from above select box
<select id="selectfilter" name="selectfilter" class="form-control main-filter">
<option value="">Sort Products</option>
<option value="/?id=na&selectfilter=hl&Type=#ReplaceThisText#">Chnage Value</option>
</select>
I have tried code from this link Change the Text of a Option with jQuery
and jquery how to find and replace a selected option that has a certain value
but cannot seem to get it to work
My code is
$('#Test1').change(function () {
sessionStorage.setItem("Test1", $(this).val());
$('.main-filter :selected:contains("#ReplaceThisText#")').val($(this).val());
location.href = $(this).val();
});
:contains will look at the .text() value - but your #ReplaceThisText# is not in the .text() value - so you'll need to use .filter() to find it instead:
Adding some console.logs so you can see what's happening and updated the .val(newval) code to make the replacement.
$('#Test1').change(function() {
var newval = $(this).val();
console.log("before", $(".main-filter :contains('Change Value')").val())
var opt = $('.main-filter option').filter(function() {
return $(this).val().indexOf("#ReplaceThisText#") >= 0;
});
console.log("opt length", opt.length);
opt.each(function() {
$(this).val($(this).val().replace(/#ReplaceThisText#/gi, newval));
});
console.log("after", $(".main-filter :contains('Change Value')").val())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="main-filter" id="Test1" name="Test1">
<option value="">Select Option</option>
<option value="1">One</option>
<option value="2">Two</option>
</select>
<select id="selectfilter" name="selectfilter" class="form-control main-filter">
<option value="">Sort Products</option>
<option value="/?id=na&selectfilter=hl&Type=#ReplaceThisText#">Change Value</option>
</select>

Two HTML selects with differing selected values

I got following HTML code:
<select id="first">
<option value="0" selected="selected"> default </option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<select id="second">
<option value="0" selected="selected"> default </option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
So both of them have same data. I need to secure, that user can't select same value in both of them.
I hoped, that JQuery has some nice feature like:
$("#first").getOptions()
or even
$("#first").setOptions()
but unfortunately, it doesn't. This makes it very complicated for me, because I don't know JQuery very well ...
So, what is the best approach to solve my problem?
You can get the value of the currently selected option by doing:
$('#first option:selected').text();
$('#second option:selected').text();
Assuming I understand your question, you don't want the user to be able to enter the same value in each box. So, something similar to:
$first = $('#first');
$second = $('#second');
$first.on('change', function() {
$second.find('option').attr('disabled', false);
var firstVal = $first.find('option:selected').text();
$second.find('option:contains("'+ firstVal +'")').attr('disabled', true);
});
$second.on('change', function() {
$first.find('option').attr('disabled', false);
var secondVal = $second.find('option:selected').text();
$first.find('option:contains("'+ secondVal +'")').attr('disabled', true);
});
I should probably note that there are ways for you to achieve your getOptions() and setOptions() ideas, you can do $select.find('option') to get the options. For setting them, define some options in html and set the select element's innerHTML to those elements:
var options = '<option value="0" selected="selected"> default </option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>';
$select.html(options);
JSFiddle demo
You can disable single options in your select
<select id="second">
<option value="0" selected="selected"> default </option>
<option value="1">One</option>
<option value="2" disabled>Two</option>
<option value="3">Three</option>
</select>
Handle event onSelect on first select and based on it disable proper <option> in second select
When one is changed, if the other is the same, you could change it back to default, like this.
$(document).on('change', '#first', function() {
var firstVal = $('#first').val();
var secondVal = $('#second').val();
if (firstVal == secondVal) {
$('#second').val(0);
}
});
$(document).on('change', '#second', function() {
var firstVal = $('#first').val();
var secondVal = $('#second').val();
if (firstVal == secondVal) {
$('#first').val(0);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="first">
<option value="0" selected="selected"> default </option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<select id="second">
<option value="0" selected="selected"> default </option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
Try this(codepen):
HTML:
<select id="first">
<option value="0" selected="selected"> default </option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<select id="second">
<option value="0" selected="selected"> default </option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
Javascript/jQuery:
var strUser;
var strUser2;
$(function() {
$("#first").change(function() {
var e = document.getElementById("first");
strUser = e.options[e.selectedIndex].text;
if (strUser == strUser2) {
alert("Dropdowns contain the same value. Change one.")
document.getElementById("first").disabled=true;
} else {
document.getElementById("second").disabled=false;
}
});
});
$(function() {
$("#second").change(function() {
var e = document.getElementById("second");
strUser2 = e.options[e.selectedIndex].text;
if (strUser2 == strUser) {
alert("Dropdowns contain the same value. Change one.")
document.getElementById("second").disabled=true;
} else {
document.getElementById("first").disabled=false;
}
});
});
Essentially, this code will retrieve selected values from the dropdowns on change, and then a comparison will be made. If the values are equal, the recently selected dropdown will be disabled. You then will have to select a different value in the other dropdown to re-enable the disabled dropdown. Here's the codepen that displays the working functionality. This will not allow a user to select two of the same values without a dropdown being disable and turned off.

Compare select values and show alert if they match

I have 4 dropdowns from which you have to select an option.
What I am trying to do is show an alert if you chose the same option more than once. Its purpose is to keep the score for a game so a person shouldn't be able to play as 2.
At the moment the dropdown looks like this:
<select id="users_1" aria-labelledby="dropdownMenu1">
<option>Select player</option>
<?php foreach($users as $user) : ?>
<option value="<?=$user['id_user']?>"><?=$user['nume']?></option>
<?php endforeach; ?>
</select>
And what I've tried to do in JQuery is this:
$("#users_2").change(function() {
var a=$(this).val("#users_1");
var b=$(this).val("#users_2");
if(a == b) {
alert($(this).val());
}
});
And I also tried to compare them like this:
$("#users_2").change(function() {
if($(this).val() == $("#users_1").val()) {
alert($(this).val());
}
});
None seems to work and I have no clue why. I've checked and the actual values are taken from the view but the if clause cannot compare them apparently.
Thank you for any help! Much appreciated!
Get your values, don't set them
Change this…
$("#users_2").change(function() {
var a=$(this).val("#users_1");
var b=$(this).val("#users_2");
if(a == b) {
alert($(this).val());
}
});
…to this…
$("#users_2").change(function() {
var a = $("#users_1").val();
var b = $(this).val(); // equivalent to $("#users_2").val()
if(a === b) { // Use strict comparison operator as a best practice
alert(a + ' matches ' + b);
}
});
Make it dynamic
You can take it a step farther by listening to a set of elements and making your handler dynamic:
// Listen to set of all select elements.
$('select').on('change', function(e) {
// Serialize form values.
var vals = $('#select_player').serializeArray();
// Convert to simple array of just values.
vals = $.map(vals, function (val, i) {
return val.value;
});
// Remove current selection from array…
vals.splice(vals.indexOf($(this).val()), 1);
// …then check to see if it's value was already there.
if(vals.indexOf($(this).val()) !== -1) { // If value is found,
// …reset current select element to default option,
$(this).val('default');
// …and alert user with a relevant message.
alert('You cannot select this player more than once.');
};
});
label {
display: block;
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="select_player" name="select_player">
<label>Player 1:
<select id="users_1" name="users_1">
<option value="default" selected="selected" disabled>Select player</option>
<option value="uid001">John Doe</option>
<option value="uid002">Jane Doe</option>
<option value="uid003">Jerome Smith</option>
<option value="uid004">Janet O'Public</option>
</select>
</label>
<label>Player 2:
<select id="users_2" name="users_2">
<option value="default" selected="selected" disabled>Select player</option>
<option value="uid001">John Doe</option>
<option value="uid002">Jane Doe</option>
<option value="uid003">Jerome Smith</option>
<option value="uid004">Janet O'Public</option>
</select>
</label>
<label>Player 3:
<select id="users_3" name="users_3">
<option value="default" selected="selected" disabled>Select player</option>
<option value="uid001">John Doe</option>
<option value="uid002">Jane Doe</option>
<option value="uid003">Jerome Smith</option>
<option value="uid004">Janet O'Public</option>
</select>
</label>
<label>Player 4:
<select id="users_4" name="users_4">
<option value="default" selected="selected" disabled>Select player</option>
<option value="uid001">John Doe</option>
<option value="uid002">Jane Doe</option>
<option value="uid003">Jerome Smith</option>
<option value="uid004">Janet O'Public</option>
</select>
</label>
</form>
I used the same class on all the dropdowns and then use only one event handler.
$('.dropdown').on('change', function (event) {
var selectedValue = $(event.currentTarget).val();
var matchedDropdowns = $('.dropdown').filter(function (index) {
return $(this).val() === selectedValue;
});
if (matchedDropdowns.length > 1) {
alert("Alert Alert!")
}
})
In the event handlers I can get the selected value, filter all the dropdowns that match that value and if I get more than 1 dropdown I will just show the alert.
You can check it on fiddle.

the first dropdown is selected it would remove the selected item from the next dropdown

i have 7 dropdown boxes in html. They will all get populated the same data. What I am trying to do is when the first dropdown is selected it would remove the selected item from the next dropdown. So, if you Have data: A,B,C,D,E,F,G,H,I in one dropdown if I select B in the first drop down then in the next dropdown it should only show A,C,D,E,F,G,H,I and so on up to 7 dropdowns. I dont know what would be the best way to approach this in JavaScript. Thanks for your help in advance
Sample Code:
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
You could use attribute targeting. I'll assume jQuery, because why not.
$("select").change(function() {
$(this)
.next("select")
.find("option").removeAttr("disabled")
.end()
.find("option[value=" + $(this).val() + "]").attr("disabled", "disabled");
})​
Again, this is just an approach so if you post code we can make better guesses.
Updated
Here's the JSFiddle: http://jsfiddle.net/FaVdu/1/
How about something like this jsFiddle example? The selected options of each drop down is disabled in every other one. This allows you to change an options without removing it.
$('select').change(function() {
var ary = new Array();
$('select option:selected').each(function() {
if ($(this).val().length > 0) {
ary.push($(this).val());
}
});
$('select option').each(function() {
if ($.inArray($(this).val(), ary) > -1) {
$(this).attr('disabled', 'disabled');
} else {
$(this).removeAttr('disabled');
}
});
});​
Hi here the solution for above question check it
<script type="text/javascript">
function cleanOptions(selectedOption) {
var val = selectedOption.options[selectedOption.selectedIndex].value;
if(val!="select"){
//Clear all items
$("#drop2 > option").remove();
//Add all options from dropdown 1
$("#" + selectedOption.id + "> option").each(function () {
var opt = document.createElement("option");
opt.text = this.text;
opt.value = this.value;
document.getElementById("drop2").options.add(opt);
});
//Remove selected
$("#drop2 option[value='" + val + "']").remove();
}
}
</script>
<select id="drop1" onchange="cleanOptions(this)">
<option value="select" selected>---select---</option>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="vw">VW</option>
<option value="audi" >Audi</option>
</select>
<select id="drop2">
<option value="select" selected>---select---</option>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="vw">VW</option>
<option value="audi" >Audi</option>
</select>

Categories

Resources