I had a select which, depending on the selected option, affected the options from two other selects (which also affected each other between themselves). So far, this was working fine. Here is the code I had:
HTML
<div id="sel" class="sel-val">
<div class="row">
<div class="col">
<select class="tipo" name="tipo">
<option selected>Select an option</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<div class="col">
<select class="num-a" name="num-a">
<option value="0" selected>0</option>
</select>
</div>
<div class="col">
<select class="custom-select num-n" name="num-n">
<option value="0" selected>0</option>
</select>
</div>
</div>
</div>
JS
$('.tipo').on("change", function() {
var val = $(this).val();
$(".num-a").html(options1[val]);
$(".num-n").html(options2[val]);
if (val == 1) {
$('.num-a').on("change", function() {
var vara = $(this).val();
$(".num-n").html(optionsIn[vara]);
});
$('.num-n').on("change", function() {
var varn = $(this).val();
$(".num-a").html(optionsIn[varn]);
});
}
if (val == 2) {
// same with different arrays
}
if (val == 3) {
// same with different arrays
}
if (val == 4) {
// same with different arrays
}
});
var options1 = [
array with options 1
];
var options2 = [
array with options 2
];
etc ...
I had to change it, so that instead of only one time, I will have this same code repeated X number of times (depending on an input set by the user), all of which will have the same three selects inside, which will have the same options. So it now looks something like this:
<div id="sel-1" class="sel-val">
<div class="row">
<div class="col">
<select class="tipo" name="tipo-1">
options...
</select>
</div>
<div class="col">
<select class="num-a" name="num-a-1">
<option value="0" selected>0</option>
</select>
</div>
<div class="col">
<select class="custom-select num-n" name="num-n-1">
<option value="0" selected>0</option>
</select>
</div>
</div>
</div>
...
<div id="sel-X" class="sel-val">
<div class="row">
<div class="col">
<select class="tipo" name="tipo-X">
options...
</select>
</div>
<div class="col">
<select class="num-a" name="num-a-X">
<option value="0" selected>0</option>
</select>
</div>
<div class="col">
<select class="custom-select num-n" name="num-n-X">
<option value="0" selected>0</option>
</select>
</div>
</div>
</div>
The problem is that with the code I have, whenever I set any of the .tipo options, it affects all of the X .num-a and .num-n selects (also changing any of the .num-a affects all of the .num-n and viceversa), when it should only affect the options of the corresponding nth selects.
I had to chang the first on("change") to $(document).on('change') for the selects to be recognized (found it on another user answer), so the first line of the script is now:
$(document).on('change','.tipo-habitacion-sel', function() {
I'm not very good with js, so this may be something obvious, but I tried several things and can't make it work.
As there mutiple selects in your html code so to refer only the required selects you can use .closest() this will get the closest div eg : sel-val and then use .find method to find select-box where you need append new options
Demo Code :
$(document).on('change', '.tipo', function() {
var val = $(this).val();
//get closest div with class sel-val
var selector = $(this).closest(".sel-val")
//then use find to get required select refernce
selector.find(".num-a").html("<option>0</option><option value='1' >1</option>");
selector.find(".num-n").html(" <option>0</option><option value='1' >1</option>");
//other codes.
});
$(document).on('change', '.num-a', function() {
var vara = $(this).val();
var selector = $(this).closest(".sel-val")
// $(".num-n").html(optionsIn[vara]);
selector.find(".num-n").html("<option>0</option><option value='2'>2</option>");
});
$(document).on('change', '.num-n', function() {
var varn = $(this).val();
var selector = $(this).closest(".sel-val")
//$(".num-a").html(optionsIn[varn]);
selector.find(".num-a").html("<option>0</option><option value='3'>3</option>");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sel-1" class="sel-val">
<div class="row">
<div class="col">
<select class="tipo" name="tipo-1">
<option value="0">0</option>
<option value="4">4</option>
</select>
</div>
<div class="col">
<select class="num-a" name="num-a-1">
<option value="0" selected>0</option>
</select>
</div>
<div class="col">
<select class="custom-select num-n" name="num-n-1">
<option value="0" selected>0</option>
</select>
</div>
</div>
</div>
<hr>
<div id="sel-X" class="sel-val">
<div class="row">
<div class="col">
<select class="tipo" name="tipo-X">
<option value="0">0</option>
<option value="4">4</option>
</select>
</div>
<div class="col">
<select class="num-a" name="num-a-X">
<option value="0" selected>0</option>
</select>
</div>
<div class="col">
<select class="custom-select num-n" name="num-n-X">
<option value="0" selected>0</option>
</select>
</div>
</div>
</div>
Related
I'm trying to create a form where I'm giving dynamic select option i.e one select option will depend on another select option, as you can see in the Image below, if Gender is male and Child the age group is between 1-18 similarly for Adult its greater than 18.
And By clicking Add member I'm cloning the whole Person div, but the script is not working for the cloned node and I'm only getting AgeGroup of the 1st div whose clone is created.
I'm trying to build this form in Django if that helps.
My code:
## html code
<button class="btn" id="addMember">Add Member</button>
<div class="form-group col-md-4">
<label>Optimise for:</label>
<div class="input-group mb-3">
<select class="custom-select" id="type" required>
<option value="" disabled="disabled" selected="selected">Choose option</option>
<option value="Child">Child</option>
<option value="Adult">Adult</option>
</select>
</div>
</div>
<div class="form-group">
<label>Gender: </label>
<div class="input-group mb-3">
<select name="h_gender" class="custom-select" id="gender" required>
<option value="" disabled="disabled" selected="selected">Choose option</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
</div>
<div class="form-group col-md-4">
<label>Age Group:</label>
<div class="input-group mb-3">
<div id="selectList">
</div>
</div>
</div>
document.getElementById('addMember').onclick = function() {
var addOnDiv = document.getElementById('addon');
var clonedNode = addOnDiv.querySelector('.memberBody').cloneNode(true);
addOnDiv.appendChild( clonedNode );
}
## for select
$("select").change(function() {
var selectedVal = $('#type').val();
var selectedGender = $('#gender').val();
console.log(selectedGender);
console.log(selectedVal);
if('Child' === selectedVal){
var childGroup = '<select name="h_ageGroup" class="custom-select"> <option value="" disabled="disabled" selected="selected">Choose option</option>........</select>';
$('#selectList').html(childGroup);
}
if('Adult' === selectedVal ){
var childGroup = '<select name="h_ageGroup" class="custom-select"> <option value="" disabled="disabled" selected="selected">Choose option</option> <option value=">18 Years"> >18 Years </option></select>';
$('#selectList').html(childGroup);
}
});
How can I get dynamic select on my cloned node too. Is there any other way through which I can achieve this ?
As your html are dynamcially created you need to bind it to some static element i.e : any div , document ..etc . Then , in your code you have use same ids for mutliple elements instead use class selector and then get required values using $(this).closest('.memberBody') this will get closest div from select and then use .find to get required values
Demo Code :
document.getElementById('addMember').onclick = function() {
var addOnDiv = document.getElementById('addon');
var clonedNode = addOnDiv.querySelector('.memberBody').cloneNode(true);
$(clonedNode).find('.selectList').html('') //empty age group div
addOnDiv.appendChild(clonedNode);
}
//just specify select when this event should get called..
$(document).on('change', '.type , .gender', function() {
//use closest and find to get only value where slect has been change
var selectedVal = $(this).closest('.memberBody').find('.type').val();
var selectedGender = $(this).closest('.memberBody').find('.gender').val();
if ('Child' === selectedVal) {
var childGroup = '<select name="h_ageGroup" class="custom-select"> <option value="" disabled="disabled" selected="selected">Choose option</option>........</select>';
$(this).closest('.memberBody').find('.selectList').html(childGroup);
}
if ('Adult' === selectedVal) {
var childGroup = '<select name="h_ageGroup" class="custom-select"> <option value="" disabled="disabled" selected="selected">Choose option</option> <option value=">18 Years"> >18 Years </option></select>';
$(this).closest('.memberBody').find('.selectList').html(childGroup);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btn" id="addMember">Add Member</button>
<div id="addon">
<div class="memberBody">
<div class="form-group col-md-4">
<label>Optimise for:</label>
<div class="input-group mb-3">
<!--aded class-->
<select class="custom-select type" required>
<option value="" disabled="disabled" selected="selected">Choose option</option>
<option value="Child">Child</option>
<option value="Adult">Adult</option>
</select>
</div>
</div>
<div class="form-group">
<label>Gender: </label>
<div class="input-group mb-3">
<!--aded class-->
<select name="h_gender" class="custom-select gender" required>
<option value="" disabled="disabled" selected="selected">Choose option</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
</div>
<div class="form-group col-md-4">
<label>Age Group:</label>
<div class="input-group mb-3">
<!--aded class-->
<div class="selectList">
</div>
</div>
</div>
</div>
</div>
I'm trying to figure out how to show hidden div but I'm a little rusty on jQuery.
So when a user selects "Yes" from Menu1 dropdown, I want the Menu2 dropdown to show up. l'm using style="visibility: hidden; to hide Menu2.
<div class="form-row">
<div class="form-group col-md-4">
<label for="inputEmail4">Menu1</label>
<select class="form-control" name="name" id="Menu1">
<option value="">--Please choose an option--</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
**<div class="form-group col-md-4" style="visibility: hidden;">**
<label for="inputPassword4">Menu2</label>
<select class="form-control" name="pets" id="Menu2">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
</select>
</div>
You can do it very easily in jQuery using the show and hide functions:
$("#Menu2Container").hide();
$("#Menu1").on("change", function(){
if ($(this).val()=="Yes")
$("#Menu2Container").show();
else
$("#Menu2Container").hide();
});
How this works:
First give a class or id to #Menu2's container so you can target it in your jQuery, e.g. <div id="Menu2Container">
Hide your Menu2 container in the jQuery when the page loads
Add an event handler for change events on #Menu1 to detect when an option is selected.
In the handler, get the value of the selected option using val()
If "Yes" is selected, show() the #Menu2Container, otherwise hide() it
Working Example:
$("#Menu2Container").hide();
$("#Menu1").on("change", function(){
if ($(this).val()=="Yes")
$("#Menu2Container").show();
else
$("#Menu2Container").hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-row">
<div class="form-group col-md-4">
<label for="inputEmail4">Menu1</label>
<select class="form-control" name="name" id="Menu1">
<option value="">--Please choose an option--</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
<div class="form-group col-md-4" id="Menu2Container">
<label for="inputPassword4">Menu2</label>
<select class="form-control" name="pets" id="Menu2">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
</select>
</div>
Note: I would suggest considering if the grid col is the best container to hide for the menu - this obviously depends on your layout, but showing and hiding the col will affect the grid layout and could affect the overall appearance.
You can use this siple javascript code for that.
No need to go for jQuery here.
just give a id to hidden div so we can access it.
document.getElementById('Menu1').onchange = e => {
let hiddenElement = document.getElementById('hiddenDiv')
e.target.value == 'Yes' ?
hiddenElement.style.visibility = 'visible' :
hiddenElement.style.visibility = 'hidden'
}
<div class="form-group col-md-4">
<label for="inputEmail4">Menu1</label>
<select class="form-control" name="name" id="Menu1">
<option value="">--Please choose an option--</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
**<div class="form-group col-md-4" id='hiddenDiv' style="visibility: hidden;">**
<label for="inputPassword4">Menu2</label>
<select class="form-control" name="pets" id="Menu2">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
</select>
</div>
Vanilla Javascript:
You can use an event listener to change the visibility to visible.
Set a conditional in your event handler and set the handler to change, check to see if the value of the target of your event listener is set to the desired value Yes, if it is, then set the div to visible...
I did add an ID to your DIV to target it directly...
let showMe = document.getElementById("showMe");
let menu1 = document.getElementById("Menu1");
menu1.addEventListener("change", function(e){
if(this.value === 'Yes'){
showMe.style.visibility = 'visible';
}
});
<div class="form-row">
<div class="form-group col-md-4">
<label for="inputEmail4">Menu1</label>
<select class="form-control" name="name" id="Menu1">
<option value="">--Please choose an option--</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
**
<div id="showMe" class="form-group col-md-4" style="visibility: hidden;">**
<label for="inputPassword4">Menu2</label>
<select class="form-control" name="pets" id="Menu2">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
</select>
</div>
You can simply use ternary operator (short form of if and else)
Along with jQuery functions like => show() and hide() function to display your second menu2 when you select Yes
Just add this code in jQuery:
const $Menu2 = $("#Menu2Container") //element
$Menu2.hide(); //Initially hide
//Change function
$("#Menu1").on("change", function() {
$(this).val() == "Yes" ? $Menu2.show() : $Menu2.hide();
});
Live working demo:
const $Menu2 = $("#Menu2Container") //element
//Initially hide
$Menu2.hide();
//Chage function
$("#Menu1").on("change", function() {
$(this).val() == "Yes" ? $Menu2.show() : $Menu2.hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<div class="form-row">
<div class="form-group col-md-4">
<label for="inputEmail4">Menu1</label>
<select class="form-control" name="name" id="Menu1">
<option value="">--Please choose an option--</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
<div class="form-group col-md-4" id="Menu2Container">
<label for="inputPassword4">Menu2</label>
<select class="form-control" name="pets" id="Menu2">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat">Cat</option>
</select>
</div>
The problem I'm having right now is that the content I want to append now is too to just creating it inside the main JavaScript file.
Is there a way that I can put this content inside some other HTML file and then call it with AJAX in the JavaScript file and append this content maybe in a loop to append it the number of times chosen from a select input tag?
Here is the select input code:
<label for="beneficiarios">Cantidad de beneficiarios</label>
<select name="beneficiarios" id="beneficiarios">
<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>
<option value="9">9</option>
<option value="10">10</option>
</select>
Here is the content I want to append:
<div class="row beneficiario-info">
<div class="col-md-6">
<div class="form-group w-75">
<label for="bene-nombreyapellido">Nombre y Apellido</label>
<input type="text" name="bene-nombreyapellido" id="bene-nombreyapellido" class="form-control">
</div>
<!-- form group -->
<div class="form-group w-75">
<label for="bene-ci-numero">Cedula de identidad</label>
<div class="input-group">
<div class="input-group-prepend">
<select name="bene-ci-tipo" id="bene-ci-tipo" class="custom-select">
<option value="VE">V</option>
<option value="EX">E</option>
</select>
</div>
<!-- cedula tipo prepend -->
<input type="text" name="bene-ci-numero" id="bene-ci-numero" class="form-control" maxlength="8">
</div>
<!-- input group -->
</div>
<!-- form group -->
</div>
<!-- col -->
<div class="col-md-6">
<div class="form-group w-75">
<label for="parentezco">Parentezco</label>
<select name="parentezco" id="parentezco" class="custom-select">
<option value="">---------</option>
<option value="hijo">Hijo</option>
<option value="padre">Padre</option>
<option value="hermano">Hermano o Hermana</option>
<option value="conyugue">Conyugue</option>
</select>
</div>
<div class="form-group">
<label for="servicioadicional">Servicios Adicionales</label>
<select name="servicios_beneficiario" class="custom-select" id="servicios_beneficiario" multiple="multiple">
<option value="medico">Médico</option>
<option value="odontologico">Odontológico</option>
<option value="funerario">Funerario</option>
<option value="vial">Víal</option>
</select>
</div>
</div>
<!-- col -->
</div>
<!-- row beneficiario -->
Here is the JavaScript code:
var number = 0;
$('#ctd-beneficiarios').on('change', function() {
numero = $(this).val();
beneficiarios_wrapper.html('');
for (var i = 0; i < numero; i++) {
}
});
beneficiarios_wrapper is the div where I want to append the content to.
Rather than storing it in a separate file and retrieving it via AJAX, use a
hidden template like so:
$main = $('#main');
for(var i=0;i<5;i++){
var $template = $('.template').clone();
$template.removeClass('template');
$template.find('.mainText').text("Template "+i);
$main.append($template);
$template.show();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<div class="template" style="display:none;">
<span class ="mainText"></span>
</div>
</div>
Or, as J. Titus has suggested:
$main = $('#main');
for(var i=0;i<5;i++){
var template = document.getElementById('template').innerHTML;
var $template = $(template)
$template.find('.mainText').text('Template '+i)
$main.append($template);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script id="template" type="text/template">
<div>
<div class="test">
<span class="mainText">test</span>
</div>
</div>
</script>
<div id="main">
</div>
I created a function that reads the content of some divs and puts them into an array. My divs are organized as such:
<div class="row clearfix" id="moltiplicandum1">
<div class="column third">
<select id="test_set" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="set1">set1</option>
<option value="set2">set2</option>
</select>
</div>
<div class="column third">
<select id="avail_cat" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="cat1">cat1</option>
<option value="cat2">cat2</option>
</select>
</div>
<div class="column third">
<select id="avail_class" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="class1">class1</option>
<option value="class2">class2</option>
</select>
</div>
</div>
<div class="row clearfix" id="moltiplicandum#">...</div>
From moltiplicandum1 to an arbitrary montiplicandum# (all created via js using a button). So, the function that is going to read the contents of all "select" for each "moltiplicandum" returns an error:
TypeError: div is null
on the line var divs = div.getElementsByTagName('select');. Here the function:
var divArray = [];
for(var i = 1; i < 10; i++) {
var div = document.getElementById("moltiplicandum"+i);
var divs = div.getElementsByTagName('select');
for (var j = 0; j < divs.length; j += 1) {
divArray.push($(divs[j]).val());
}
}
If I comment the external for, defining var i = 1, it works (only for "moltiplicandum1").
Could someone help me to figure out the problem? Thank you1
if you are using jquery why don't you simply use the selector? like this:
selectArray = Array.prototype.map.call($(".moltiplicandum select"),(function(el){
return el.value;
});
I'm not sure what any of the code you've shown has to do with either recursion or AJAX, however given your goal of building an array of all the values from the select elements you can simply use jQuery's map() method.
You can also add a common class to the moltiplicandumN elements so that you can genericise the logic. Try this:
$('.moltiplicandum select').change(function() {
var selectArray = $('.moltiplicandum select').map(function() {
return this.value;
}).get();
console.log(selectArray)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row clearfix moltiplicandum" id="moltiplicandum1">
<div class="column third">
<select id="test_set1" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="set1">set1</option>
<option value="set2">set2</option>
</select>
</div>
<div class="column third">
<select id="avail_cat1" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="cat1">cat1</option>
<option value="cat2">cat2</option>
</select>
</div>
<div class="column third">
<select id="avail_class1" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="class1">class1</option>
<option value="class2">class2</option>
</select>
</div>
</div>
<div class="row clearfix moltiplicandum" id="moltiplicandum2">
<div class="column third">
<select id="test_set2" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="set1">set1</option>
<option value="set2">set2</option>
</select>
</div>
<div class="column third">
<select id="avail_cat2" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="cat1">cat1</option>
<option value="cat2">cat2</option>
</select>
</div>
<div class="column third">
<select id="avail_class2" type="text" style="width:100%">
<option selected disabled value="">Select...</option>
<option value="class1">class1</option>
<option value="class2">class2</option>
</select>
</div>
</div>
Also, be careful of duplicating id attributes. I added a numerical value to the id of the repeated select controls in the HTML above.
I'm trying to change a select list to a text input (an example is amazon cart) based on a value of 10. What I have works for 1 row but I want to add multiple rows. I need some help changing the jquery to only change 1 row at a time.
$(function() {
$('.dropdown-change').on('change', function() {
var dropdownValue = $(this).val();
if (dropdownValue == 10) {
$('.dropdown-control').hide();
$('.input-control').show();
} else {
$('.dropdown-control').show();
$('.input-control').hide();
}
return false;
});
});
.input-control {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="row dropdown-row">
<div class="col-xs-2 col sm-2 col-md-2">
<label for="quantity">Qty</label>
</div>
<div class="col-xs-8 col-sm-8 col-md-8">
<div class="dropdown-control">
<div class="col-xs-12 col-sm-12 col-md-6 no-pad-left">
<select name="quantity" class="form-control dropdown-change">
<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>
<option value="9">9</option>
<option value="10">10+</option>
</select>
</div>
</div>
<div class="input-control">
<div class="col-md-6 no-pad-left">
<input type="text" value="10" size="10" name="quantity" id="quantity" class="form-control" />
</div>
<div class="col-md-6 no-pad-left">
<button class="btn btn-primary btn-xs">update</button>
</div>
</div>
</div>
</div>
I fixed this by changing my HTML around and using $(this).closest() and $(this).next()