Hi i have following scenario of drop down list
Whenever i select cat1 options, sub cat 1 options will be populated. But if i add another category
it should only add cat1 options not along with sub cat options.But in my case both of cat 1 and sub cat options are loaded. Following are my code to clone drop down list.
<div class="new-categories">
<div class="new-category">
<select class="category-select" name="categories">
<option></option>
<option value="1">cat 1</option>
</select>
<select class='category-select-sub' style="display:none">
<!-- loaded from ajax -->
</select>
</div></div>
Add another category
$('.add-another-cat').click(function(event){
event.preventDefault();
var $orDiv = $('.new-category:last').after($('.new-category:first').clone());
});
This is how i actually supposed to look like
Thanks.
update: populate ajax result
$('div.new-categories').on('change', 'select.category-select', function () {
var $newselect = $('<select />').addClass('category-select-sub');
$(this).parent().append($newselect);
var cat_id = $(this).val();
$.ajax({
url:baseUrl+'categories/getsubcat',
data:{'id':cat_id},
dataType:'json',
async:false,
type:'POST',
success:function(data){
var subhtml = data;
$('.category-select-sub').show();
$('.category-select-sub').html(subhtml);
}
});
});
Once new cat list has been added and an option is selected, the first sub cat are changing according to new list. How to prevent this?
Your code doesn't make sense to me, but this is what I think you are trying to do. Correct me if I am wrong.
"I would like to clone the div new-category and append it to the div new-categories. I only want the first select list cloned, not anything else.
http://jsfiddle.net/HZp5M/
$('a.add-another-cat').click(function(e) {
e.preventDefault();
//clone the first div
var $newdiv = $('div.new-category:first').clone();
//remove the second select (if there is one)
$newdiv.children('select.category-select-sub').remove();
//append new div
$('div.new-categories').append($newdiv);
});
http://jsfiddle.net/SCArr
<script src="//code.jquery.com/jquery-latest.js"></script>
<div id="clone" class="new-category" style="display:none;">
<select class="category-select" name="categories">
<option></option>
<option value="1">cat 1</option>
</select>
<select class='category-select-sub' style="display:none">
<!-- loaded from ajax -->
</select>
</div>
<div class="new-categories">
</div>
Add another category
<script>
$('.add-another-cat').click(function(event){
event.preventDefault();
var $orDiv = $('.new-category:last').after($('#clone').clone().removeAttr('id').show());
});
$('.new-categories').html($('#clone').clone().removeAttr('id').show());
</script>
I would like to see how you have the second sub select menu as it might affect the solution.
Solution 1 - better creation with an empty state
the problem is in your HTML structure
<div class="new-category">
<select class="category-select"> ... </select>
<select> ... </select>
</div>
When you clone .new-categories you clone both select elements.
You need to reconstruct your HTML so you will clone only what you want.
There will be something you will need to create by yourself without a clone.
For example, something like this:
$('.new-category:last').after( $("<div/>")
.addClass("new-category").append($('.category-select:last').clone()).append($("<select/>").addClass(".category-select-sub").hide());
Solution 2 - empty the sub select after clone
a jsfiddle that shows how to empty a select
What to do about auto-populating the sub select affecting all?
This is easy, your code explicitly refer to all sub selects. see the you code saying
$('.category-select-sub').show().html(subhtml);
This code means - set this HTML to all ".category-select-sub" elements. But you want only a specific element with this class - not all..
You should only refer to the sub select you created - which is easy as you already have a reference to it - so the success function should have something like this :
$newselect.show().html(subhtml);
Related
I have am HTML code which for simplicity looks like this:
<div class="main-container">
<div class="group-area group1" id="group1">
<select class="slct" id="slct1">
<option>Group A</option>
<option>Group B</option>
<option>Group C</option>
</select>
<div class="participant-area">
<!-- empty, can be filled with "<div class='participant'></div>" elements -->
</div>
</div>
<button class="add-group">Show another group</button>
</div>
In the above inteface, the user can select the name of the group from the select drop down, and the the participants of that group will be shown in the 'participant-area'. They will be drawn from a presaved list, and will be added using jQuery append:
<script>
$(document).on('change', '.slct', function() {
var number = $(this).attr("id").charAt(4); //gets the number '1' from the id name
var key = $(this).find("option:selected").val(); //gets the value to be used later
var constructedClass = ".group" + number; //result: "group1"
presavedList.forEach(participant => {
$(constructedClass + " .participant-area") //selecting participant area that is inside group1
.append($("<div>").addClass("participant")
.append($("<h2>").text(participant.name))
);
}
})
</script>
However, user can also click on the 'add-group' button at the end of the main container, and have another area just like the first one displayed, that can be used to see participants of a different group. But this time, the classes will be group2 instead of group1, slct2 instead of slct1, and so on. This is done by having a global variable that is incremented whenever the button is clicked:
<script>
var areaNumber = 1;
$(".add-group").click(function () {
areaNumber++;
$(".main-container")
.append($("<div>").addClass( "group"+areaNumber).addClass("group-area").attr("id", "group"+ areaNumber)
.append($("<select>")) //etc... Reconstruct the same one as original
.append($("<div>")) //etc... Reconstruct the same one as original
});
</script>
My problem is related selecting the groupN class of the dynamically created elements (like group2, group3, etc). In the first function above - after a second area has been created and its select value changed - the change is being detected normally and the $(document).on('change', '.slct', function() {...}) is being fired normally. However, the 5th line in that function:
$(constructedClass + " .participant-area").append(//etc)
is not working: the constructedClass is not being detected by the function, even though it exists in the time of firing it - but I believe it's not being detected because it was not present at the time of initial parsing of javascript. Is that correct? Is there any way to solve this? (Be able to select dynamically generated elements by their uniquely generated class names?).
Thank you for reading this far and for any help you can offer.
Do not use incremental id and class attributes. It is an anti-pattern. It makes your code needlessly complex, more verbose, and difficult to maintain.
A much better solution is to group common elements by behaviour using a single class attribute. That way you can use DOM traversal to relate them to each other. It also allows you to clone() content (as it's all identical) without the need to spaghetti-fy your JS by filling it with HTML.
With that said, try this:
let presavedList = [{ name: 'Foo bar' }, { name: 'Lorem ipsum' }]
$(document).on('change', '.slct', function() {
var html = presavedList.map(item => `<div class="participant"><h2>${item.name}</h2></div>`);
$(this).next('.participant-area').html(html);
});
$(".add-group").click(function() {
var $clone = $('.group:first').clone();
$clone.find('select').val('');
$clone.find('.participant-area').empty();
$clone.appendTo('.main-container');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main-container">
<div class="group-area group">
<select class="slct">
<option value="">Please select...</option>
<option>Group A</option>
<option>Group B</option>
<option>Group C</option>
</select>
<div class="participant-area"></div>
</div>
<button class="add-group">Show another group</button>
</div>
$(document).ready(function() {
var element;
$(".form-element").on("mousedown", function(event){
element = $('<form><select name="dropdown"><option>Select...</option><option value="new-dropdown">add new...</option><option value="machine3">Machine 3</option><option value="machine4">Machine 4</option></select></form>');
$("#body-div").append(element);
});
});
The items in the list currently are just there for testing. But I need to be able to click on an add new option and add a new list item.
Working Fiddle
It looks like you were trying to dynamically add the entire form, but you only need to add additional option elements to your select section of your form.
To do this add this HTML
HTML
<input id="text-to-add" type="text" value="Machine 3">
<button id="new-item">Add to dropdown</button>
<form>
<select name="dropdown">
<option>Select...</option>
<option>Machine 1</option>
<option>Machine 2</option>
</select>
</form>
Then to dynamically add a select element use the append jQuery function.
jQuery
$(document).ready(function () {
$('#new-item').click(function() {
console.log($('#text-to-add').val());
$('select').append( '<option>' + $('#text-to-add').val() + '</option>' );
});
});
First add a new id for both the select tag and the option tag with the value "new option";
element = $('<form>
<select name="dropdown"
id="sel"><option>Select...</option>
<option value=
"new-dropdown"id="anew">add new...
</option></select></form>');
now im assuming that you already have the values for both the value and the text for that option let both of them be x and y respectively;
now add an onClick handler to #anew to append #sel with a new option with value x and text y:
z=$('<option value="'+x+'">'+y+'</option>');
$("#anew").onClick(function(){
$("#sel").append(z);
});
hope it solves your problem
I am looking for a simple .js solution. I have two dropdown buttons - code:
<select name="parent_dropdown" id="parent">
<option value="option_01">parent_option_01</option>
<option value="option_02">parent_option_02</option>
</select>
<br />
<select name="child_dropdown" id="child">
<option value="opt01">child_option_01</option>
<option value="opt02">child_option_02</option>
<option value="opt03">child_option_03</option>
<option value="opt04">child_option_04</option>
</select>
Now I need to accomplish this:
When option_01 in #parent is chosen ---> make available only child_option_01 and child_option_02 in #child dropdown
When option_02 in #parent is chosen ---> make available only child_option_03 and child_option_04 in #child dropdown
I tried some solutions I found online but so far no luck. I have a very basic .js knowledge.
Link to FIddle: http://jsfiddle.net/q5kKz/343/
Help will be appreciated.
Taking the next step with your fiddle, this will do (almost) what you want:
$('#parent').change(function() {
$("option[value='opt01']")[$(this).val() == "option_01" ? 'show' : 'hide']("fast");
}).change();
Notice the attribute selector: "option[value='opt01']" - that says "any options with value of opt01".
You should probably expand that selector to be "#child option[value='opt01']"
Using a "basic" programming method, you could do this for multiple options:
$('#parent').change(function() {
$("option[value='opt01']")[$(this).val() == "option_01" ? 'show' : 'hide']("fast");
$("option[value='opt02']")[$(this).val() == "option_01" ? 'show' : 'hide']("fast");
// Adding multiple options here. This is a bad method for maintainability
}).change();
A better way to go would be to assign some sort of other attributes to the options that should show depending on which parent is selected. One example is using a class that matches the parent value desired - which would require modifying your child list like so:
<select name="child_dropdown" id="child">
<option value="opt01" class="option_01">child_option_01</option>
<option value="opt02" class="option_01">child_option_02</option>
<option value="opt03" class="option_02">child_option_03</option>
<!-- The below option would show whenever the parent is on option 2 OR 3 -->
<option value="opt04" class="option_02 option_03">child_option_04</option>
</select>
But then your script could be much more usefully constructed like so, and wouldn't need to be changed if you added / changed options:
$('#parent').change(function() {
var val = $(this).val();
$("#child option")[$(this).hasClass(val) ? 'show' : 'hide']("fast");
}).change();
This still leaves the problem of the list option hiding, and the select can still be set to a "hidden" value. This would need to be addressed somehow. Something like the below:
$('#parent').change(function() {
var val = $(this).val();
$("#child option")[$(this).hasClass(val) ? 'show' : 'hide']("fast");
var child_val = $('#child').val();
// If the selected option is not visible...
if ($('#child').find(":selected").not(":visible")) {
// Set it to the first option that has the proper parent class
$("#child").val($("#child option." + val + ":first").val());
};
}).change();
With newer versions of jQuery you could do something like:
var group1 = $("#child").find("option[value='opt01'], option[value='opt02']");
var group2 = $("#child").find("option[value='opt03'], option[value='opt04']");
$('#parent').change(function() {
var selected = $("#parent").find(":selected").text();
if (selected == "parent_option_01") {
group1.prop("disabled", false);
group2.prop("disabled", true);
} else {
group1.prop("disabled", true);
group2.prop("disabled", false);
}
}).change();
The other people may have it right. But when you want to make changes you have to change a bunch of JS code. I think this is a better approach. In our child HTML we add a data attribute to show what values of parent will make this child option show. This way if we ever need to add more elements or change what ones make the children appear we can just change the HTML and it leaves our javascript a lot cleaner.
http://jsfiddle.net/q5kKz/348/
var parent = $("#parent");
var child = $("#child");
var val;
$('#parent').change(function() {
//Get value of parent
val = $("#parent").val();
//cycle through children and find which data show matches the parent
child.children().each(function(){
var c = $(this);
//Jquery's .data wasn't working for some reason
if(c.attr("data-show") === val){
c.show()
}else{
c.hide()
}
})
}).change();
In the HTML
<select name="parent_dropdown" id="parent">
<option value="option_01">parent_option_01</option>
<option value="option_02">parent_option_02</option>
</select>
<br />
<select name="child_dropdown" id="child">
<option value="opt01" data-show="option_01">child_option_01</option>
<option value="opt02" data-show="option_01">child_option_02</option>
<option value="opt03" data-show="option_02">child_option_03</option>
<option value="opt04" data-show="option_02">child_option_04</option>
</select>
This is for javascript and jquery.
I have in my body...
<select id="option1_select" name="courseCodeSelectName">
<option></option>
<option>Word1</option>
<option>Word2</option>
</select>
<script>
$("select").change(function () {
functionLoadOpt2() }).trigger("change" );
</script>
<select id="option2_select" name="courseNumSelectName">
<option></option>
</select>
<button onclick="changePage()">Load Textbook Page!</button>
As we see above, the web page has 2 select boxes and a button. Depending on what you select in the first select box loads what is in the second one, using the functionLoadOpt2 function locating higher up in my code.
if (result == "Word1") {
$("#option2_select").append('<option>Letter1</option>');
...
There is more but it follows the same code different values.
Result is the following, above the if statement(just a row up),
var result = (document.getElementById('option1_select').value);
now on the button click, the function changePage() runs,
and all I want is ...
var result = (document.getElementById('option1_select').value);
var result2= (document.getElementById('option2_select').value);
Assume they selected and option for both. Result2 doesnt work. I'd imagine because I'm appending it but how would I work around this. So that when I click changePage() I get the selected value of option1_select and option2_select.
functionLoadOpt2:
function functionLoadOpt2(){
var opt1Val = (document.getElementById('option1_select').value);
$("#option2_select").find('option').remove().end().append('<option></option>');
if (opt1Val == "Word1") {
$("#option2_select").append('<option>Letter1</option>');
$("#option2_select").append('<option>Letter2</option>');
$("#option2_select").append('<option>Letter3</option>');
$("#option2_select").append('<option>Letter4</option>');
$("#option2_select").append('<option>Letter5</option>');
}else if (opt1Val == "Word2") {
$("#option2_select").append('<option>Letter3</option>');//they have similar ones in some cases
$("#option2_select").append('<option>Letter6</option>');
$("#option2_select").append('<option>Letter7</option>');
$("#option2_select").append('<option>Letter8</option>');
$("#option2_select").append('<option>Letter9</option>');
$("#option2_select").append('<option>Letter10</option>');
$("#option2_select").append('<option>Letter11</option>');
$("#option2_select").append('<option>Letter12</option>');
$("#option2_select").append('<option>Letter13</option>');
$("#option2_select").append('<option>Letter14</option>');
$("#option2_select").append('<option>Letter15</option>');
$("#option2_select").append('<option>Letter16</option>');
$("#option2_select").append('<option>Letter17</option>');
//this works
}
}
use jQuery to get and set the value of <select> with .val()
Both your select elements have the same id, fix it the it should be fine
<select id="option1_select" name="courseCodeSelectName">
<option></option>
<option>Word1</option>
<option>Word2</option>
</select>
<select id="option2_select" name="courseNumSelectName">
<option></option>
</select>
<button onclick="changePage()">Load Textbook Page!</button>
Demo: Fiddle
Note: You can improve the script a lot by using proper jQuery constructs, like this
I have 2 drop down lists, which both hold the same list of teams, one to be used as the home team and one as the away team. At the moment the first drop down list works, when a team is selected from the list, it's id and name is output to the page. But when the other drop down is clicked, nothing happens. So for example the output takes the id and team name and outputs them to the textboxes.
Here is an example of each drop down list and the relevant code below, can anyone help me out?
HTML generated for home team list:
<select id="teamList" style="width: 160px;">
<option></option>
<option id="1362174068837" value="1362174068837" class="teamDropDown">Liverpool</option></select>
HTML generated for away team list:
<select id="teamList" style="width: 160px;">
<option></option>
<option id="1362174068837" value="1362174068837" class="teamDropDown">Liverpool</option>
</select>
JADE template used to generate the HTML (used for both lists):
div#teamDropDownDiv
-if(teamsList.length > 0){
select#teamList(style='width: 160px;')
option
-each team in teamsList
option.teamDropDown(id="#{team.key}",value="#{team.key}") #{team.name}
JavaScript for the page:
Team.initTeamsDD = function(){
$("#teamList").change(function(e){
e.preventDefault();
var teamId = $(this).val();
$.get('/show/team/'+teamId, function(response){
if(response.retStatus === 'success'){
var teamData = response.teamData;
$('#teamId').val(teamData.key);
$('#teamName').val(teamData.name);
} else if(response.retStatus === 'failure'){
}
});
});
The two <select> elements both have the same "id" value, which is "teamList". You should never have two elements with the same "id". Because of this, the on-change event handler is getting attached to only one of them. You should change them to "homeTeamList" and "awayTeamList", and then use:
Team.initTeamsDD = function(){
$("#homeTeamList, #awayTeamList").change(function(e){
...