Recursive read div contents and post via AJAX - javascript

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.

Related

Get Dynamic Select option in Clone Node using Javscript

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>

Change select options based on a select from within multiple iterations

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>

Add input forms dinamically trough AJAX and JQUERY

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>

How to get particular select option based on previous select tag in jQuery?

I want to get option like PCMB and PCMC in select option when I selected SCIENCE as a previous select tag and nothing when I selected Commerce.
<div class="row Time">
<div class="col-md-4 col-sm-4">
<p>Course<span class="astric">*</span></p>
<select class="Academic">
<option value="">Select</option>
<option value="" id="Science">Science</option>
<option value="" id="Commerce">Commerce</option>
<option value="" id="Arts">Arts</option>
</select>
</div>
<div class="col-md-4 col-sm-4">
<p>Branch<span class="astric">*</span></p>
<select class="Academic">
<option value="" id="Select">Select</option>
<option value="" id="PCMB">PCMB</option>
<option value="" id="PCMC">PCMC</option>
<option value="" id="PCMS">PCMS</option>
</select>
</div>
<div class="col-md-4 col-sm-4">
<p>Year<span class="astric">*</span></p>
<select class="Academic">
<option value="">Select</option>
<option value="" id="01">01</option>
<option value="" id="02">02</option>
</select>
</div>
</div>
You will have to make couple of changes to your code to achieve your desired result.
You should not include the second select box initially in DOM if you want to show it only after user select a specific value.
You will have to add values to your select Options
You Class or Id to your select boxes
Use Jquery .on('change') function to accomplish your desired result
Use the below code for further reference.
var selectLevelTwo = '<div class="col-md-4 col-sm-4 select-level-two"><p>Branch<span class="astric">*</span></p><select class="Academic"><option value="" id="Select">Select</option><option value="" id="PCMB">PCMB</option><option value="" id="PCMC">PCMC</option><option value="" id="PCMS">PCMS</option></select></div>';
$(document).on('change', '.select-level-one', function(){
var firstSelectValue = $('.select-level-one option:selected').val();
if(firstSelectValue == 'science'){
$(this).parent().after(selectLevelTwo);
} else {
$('.select-level-two').fadeOut('fast');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row Time">
<div class="col-md-4 col-sm-4">
<p>Course<span class="astric">*</span></p>
<select class="Academic select-level-one">
<option value="">Select</option>
<option value="science" id="Science">Science</option>
<option value="commerce" id="Commerce">Commerce</option>
<option value="arts" id="Arts">Arts</option>
</select>
</div>
<div class="col-md-4 col-sm-4">
<p>Year<span class="astric">*</span></p>
<select class="Academic">
<option value="">Select</option>
<option value="" id="01">01</option>
<option value="" id="02">02</option>
</select>
</div>
</div>
Hope this help

JQuery: Counter wrapped in an if statement not working?

So I have two of these select menus, and I want the counter to add 1 each time a right selection is selected in each selection. But it stays at 1.. How do I fix this?
HTML:
<div class="row"><!--first row-->
<div class="col-sm-3 col-xs-12 unit" >
<img src="img/shiny-apple.png" id="apple">
<p class="selectby">Fruit</p>
<select>
<option value="default"></option>
<option value="apple">apple</option>
<option value="banana">banana</option>
<option value="grapes">grapes</option>
<option value="carrot">carrot</option>
</select>
</div><!-- end of col-->
<div class="col-sm-3 col-xs-12 unit" >
<img src="img/carrot.png" id="carrot">
<p class="selectby">Fruit</p>
<select>
<option value="default"></option>
<option value="apple">apple</option>
<option value="banana">banana</option>
<option value="grapes">grapes</option>
<option value="carrot">carrot</option>
</select>
</div><!-- end of col-->
JS:
$("select").change(function() {
$selectedItem = $(this).val();
$imgId = $(this).siblings().attr('id');
var counter = 0;
// if the image ID string includes the selected option string
if ( $imgId.includes($selectedItem) ) {
$(this).parent().css("background-color", "lightgreen");
$(this).prop('disabled', true);
counter++;
console.log(counter);
}
});
var counter = 0;//put counter outside of change so it wont be initialize to 0 every change event
$("select").change(function() {
$selectedItem = $(this).val();
$imgId = $(this).siblings().attr('id');
// if the image ID string includes the selected option string
if ($imgId.includes($selectedItem)) {
$(this).parent().css("background-color", "lightgreen");
$(this).prop('disabled', true);
counter++;
console.log(counter);
}
alert(counter)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<!--first row-->
<div class="col-sm-3 col-xs-12 unit">
<img src="img/shiny-apple.png" id="apple">
<p class="selectby">Fruit</p>
<select>
<option value="default"></option>
<option value="apple">apple</option>
<option value="banana">banana</option>
<option value="grapes">grapes</option>
<option value="carrot">carrot</option>
</select>
</div>
<!-- end of col-->
<div class="col-sm-3 col-xs-12 unit">
<img src="img/carrot.png" id="carrot">
<p class="selectby">Fruit</p>
<select>
<option value="default"></option>
<option value="apple">apple</option>
<option value="banana">banana</option>
<option value="grapes">grapes</option>
<option value="carrot">carrot</option>
</select>
</div>
<!-- end of col-->
place the counter outside the change event. Because every change event it is initialized to 0 again

Categories

Resources