I'm able to clone the #ingredient_1 div with the Add button. However, after pressing Add several times, then deleting random cloned divs with their specific X buttons, the Add button stops working.
I've replicated this problem across several browsers. Any advice would go a long way.
$('#add_more').click(function() {
var num = $('.clone').length;
var newNum = num + 1;
var newElem = $('#ingredient_1').clone().attr('id', 'ingredient' + '_' + newNum);
$('#ingredient_' + num).after(newElem);
});
$('#main').on('click', '.remove', function() {
$(this).parent().remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<div id="ingredient_1" class="clone">
<select id="1">
<option selected="selected">Please Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<input type="text" name="name" placeholder="Amount" />
<select id="2">
<option selected="selected">Units</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<select id="3">
<option selected="selected">Time</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<button class="remove">X</button>
</div>
<div id="add_button">
<input type="button" id="add_more" value="Add" />
</div>
</div>
Once you delete the first row the element you're cloning no longer exists. Clone the element outside your click function so it's not overwritten:
var newElem = $('#ingredient_1').clone().attr('id', 'ingredient' + '_' + newNum);
var num = 1;
$('#add_more').click(function() { ... });
Also, declare your ID incrementor outside the function and simply add 1 each time the click function runs with num++. I'm guessing that it doesn't really matter what the ID values are, so as long as they're unique this works.
The problem is that you're using .length to calculate newNum. If you delete DIVs in the middle, you'll end up with duplicate IDs. For instance, suppose you first add 3 DIVs, you'll have DIVs numbered 1, 2, 3, 4. Then you delete #3. The next time you click Add, $(".clone").length will be 3, so you'll set newNum = 4;. But there's still a DIV with that ID.
Instead of using $(".clone").length, get the ID of $(".clone:last"), get the number at the end of it, and add 1 to that.
You're cloning, which if you have at least one static item, is fine. I fixed up your code so your initial row is hidden, and you have an ID variable that is auto incremented. On top of which, on load, it creates clones and creates the first row. Your back end code will just have to ignore a case where the style is set to display:none.
var id = 1;
$(function () {
var first = $('.clone');
first.attr('style', 'display:none');
NewRow();
});
$('#add_more').click(function () {
NewRow();
});
function NewRow() {
console.log('num = ' + id++);
var newElem = $('.clone:last').clone().attr('id', 'ingredient' + '_' + id + '_x');
newElem.attr('style', '');
$('.clone:last').after(newElem);
}
$('#main').on('click', '.remove', function () {
$(this).parent().remove();
});
You'll notice that I changed your click event to call the function NewRow(), this was done so that you can call a function in the Document.Ready event, as well as on the button click.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main">
<div id="ingredient_1" class="clone">
<select id="1">
<option selected="selected">Please Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<input type="text" name="name" placeholder="Amount" />
<select id="2">
<option selected="selected">Units</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<select id="3">
<option selected="selected">Time</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
<option value="">Select</option>
</select>
<button class="remove">X</button>
</div>
<div id="add_button">
<input type="button" id="add_more" value="Add" />
</div>
</div>
Working JSFiddle is here
Related
Looking for a cascading dropdown i found this piece of code here, which is working almost perfect for me, but i need to keep the default option in the second select-menu after changing the value in the first one.
https://stackoverflow.com/a/28902561/10391817
function filterCity() {
var province = $("#province").find('option:selected').text(); // stores province
$("#option-container").children().appendTo("#city"); // moves <option> contained in #option-container back to their <select>
var toMove = $("#city").children("[data-province!='" + province + "']"); // selects city elements to move out
toMove.appendTo("#option-container"); // moves city elements in #option-container
$("#city").removeAttr("disabled"); // enables select
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="select" id="province" onchange="filterCity();">
<option value="1">RM</option>
<option value="2">FI</option>
</select>
<select class="select" id="city" disabled>
<option>SELECT CITY</option>
<option data-province="RM" value="1">ROMA</option>
<option data-province="RM" value="2">ANGUILLARA SABAZIA</option>
<option data-province="FI" value="3">FIRENZE</option>
<option data-province="FI" value="4">PONTASSIEVE</option>
</select>
<span id="option-container" style="visibility: hidden; position:absolute;"></span>
You can try this code.
<select class="select" id="province">
<option value="1">RM</option>
<option value="2">FI</option>
</select>
<select class="select" id="city" disabled>
<option data-province="DEF">SELECT CITY</option>
<option data-province="RM" value="1">ROMA</option>
<option data-province="RM" value="2">ANGUILLARA SABAZIA</option>
<option data-province="FI" value="3">FIRENZE</option>
<option data-province="FI" value="4">PONTASSIEVE</option>
</select>
<span id="option-container" style="visibility: hidden; position:absolute;"></span>
<script>
$('#province').on('change', function() {
var province = $("#province").find('option:selected').text();
$("#city option[data-province!='" + province + "']").hide();
$("#city option[data-province='" + province + "']").show();
$("#city option[data-province='DEF'").show().prop('selected', true);
$("#city").removeAttr("disabled");
});
</script>
https://jsfiddle.net/sg0t23bc/5/
Related JSFiddle
<form id="calendar_form">
<div class="day1">
Day 1
<table class="selector_table">
<select name="select1">
<option></option>
<option value="optionA">PersonA</option>
<option value="optionB">PersonB</option>
</select>
<select name="select2">
<option></option>
<option value="optionA">PersonA</option>
<option value="optionB">PersonB</option>
</select>
</table>
</div>
<br>
<div class="day2">
Day 2
<table class="selector_table">
<select name="select3">
<option></option>
<option value="optionA">PersonA</option>
<option value="optionB">PersonB</option>
</select>
<select name="select4">
<option></option>
<option value="optionA">PersonA</option>
<option value="optionB">PersonB</option>
</select>
</table>
</div>
</form>
<script>
$("select").change(function(){
var selectThatWasChanged = $(this).attr('id');
var valueToRemove = $(this).val();
var dayWorkingWith = $(this).closest('.selector_table');
$('option', dayWorkingWith).not('#' + selectThatWasChanged + ' option');
$('option[value="' + valueToRemove + '"]').not('#' + selectThatWasChanged + ' option').hide();
});
</script>
I've been playing with this for an hour, and I'm frustrated. sigh. What I'm trying to accomplish is this: If PersonA is selected in Day1, he should not be available to pick again anywhere in Day1. However, PersonA should still be available on Day2.
Currently if PersonA is selected, PersonA is removed from all other selects. I tried to hone in on just the relevant selects by using the closest('.selector_table').
What am I doing wrong?
Thank you so much, in advance!
Bonus basic question: would it be tremendously more work to "undo" the change. For instance, if someone selects PersonA it hides PersonA as described, but then if PersonB is selected thereafter on the same select, it undoes that change and PersonA becomes available again?
Apply change event to the select Element, get the sibling select and disable it's matching option element.
$("select").change(function() {
const selectedOptionVal = $(this).find(":selected")[0].value;
const sibSelectEle = $(this).siblings('select');
sibSelectEle.children('option').each(function(_, option) {
if (selectedOptionVal == option.value) {
$(option).attr("disabled", true);
} else {
$(option).attr("disabled", false);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="calendar_form">
<div class="day1">
Day 1
<table class="selector_table">
<select name="select1">
<option></option>
<option value="optionA">PersonA</option>
<option value="optionB">PersonB</option>
</select>
<select name="select2">
<option></option>
<option value="optionA">PersonA</option>
<option value="optionB">PersonB</option>
</select>
</table>
</div>
<br>
<div class="day2">
Day 2
<table class="selector_table">
<select name="select3">
<option></option>
<option value="optionA">PersonA</option>
<option value="optionB">PersonB</option>
</select>
<select name="select4">
<option></option>
<option value="optionA">PersonA</option>
<option value="optionB">PersonB</option>
</select>
</table>
</div>
</form>
I am using the following js and html code to display the lists.
MAIN PROBLEM is that when the sub-categories & categories become to many, the categories change but the sub-categries are not displaying from a certain cagory going downwards. Problem is on desktop/laptops. Working correctly on mobile device. Am not god at javascript
<script type="text/javascript">
$(function() {
$('#vehicle').on('change', function() {
var vehileType = $('#vehicle').val();
$('#vehicle-type option').hide();
$('#vehicle-type option[vehicle="'+vehileType+'"]').show();
});
});
</script>
<select id="vehicle" required name="brand">
<option value="">Select Make</option>
<option value="ABT">ABT</option>
<option value="AC">AC</option>
</select>
<select name="model" id="vehicle-type" class="form-control">
<option vehicle="ABT" value="ABT">ABT</option>
<option vehicle="ABT" value="ABT1">ABT1</option>
<option vehicle="AC" value="AC">AC</option>
<option vehicle="AC" value="AC1">AC1</option>
</select>
First I put vehicle options to custom variable var vehicleTypeOptions = $('#vehicle-type option[vehicle="' + vehileType + '"]');
Then after show I add this $('#vehicle-type').val(vehicleTypeOptions.first().val()); so it will set the value of first vehicle type option
I also put .trigger('change') for a #vehicle so it will set vehicle types by the vehicle make so you don't have to manually set one option
Here is a working demo:
$(function() {
$('#vehicle').on('change', function() {
var vehileType = $('#vehicle').val();
var vehicleTypeOptions = $('#vehicle-type option[vehicle="' + vehileType + '"]');
$('#vehicle-type option').not(vehicleTypeOptions).hide();
vehicleTypeOptions.show();
$('#vehicle-type').val(
vehicleTypeOptions.first().val()
);
}).trigger('change');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="vehicle" required name="brand">
<option value="">Select Make</option>
<option value="ABT">ABT</option>
<option value="AC">AC</option>
</select>
<select name="model" id="vehicle-type" class="form-control">
<option vehicle="ABT" value="ABT">ABT</option>
<option vehicle="ABT" value="ABT1">ABT1</option>
<option vehicle="AC" value="AC">AC</option>
<option vehicle="AC" value="AC1">AC1</option>
</select>
These are Dynamic dependent select controls. The sets of values of (1-3, 4-6, 7-9) determine the use hide/show divs function. The problem is the function i have only hide/show depending on the div id. How can i make the function hide/show div depended on the values(1-3, 4-6, 7-9) found in the selectbox?
Jquery
$('#select').change(function() {
$('#sub1, #sub2, #sub3').hide();
$('#sub' + $(this).find('option:selected').attr('id')).show();
});
Html Setup
<html>
<select size="6" id="category">
<option value="">categories 1-3 </option>
<option value="">----</option>
<option value="">----</option>
</select>
<div id="sub1" style="display:none">
<select name="subc1" size="6">
<option value="1">subcategories 4-6</option>
<option value="2">---</option>
<option value="3">---</option>
</select>
</div>
<div id="sub2" style="display:none">
<select name="subc2" size="6">
<option value="4">subcategories 7-9</option>
<option value="5">----</option>
<option value="6">----</option>
</select>
</div>
<div id="sub3" style="display:none">
<select name="subc3" size="6">
<option value="7">End</option>
<option value="8">----</option>
<option value="9">----</option>
</select>
</div>
</html>
select the value from drop down change function and do the operation depends on the value of drop down, following is the sample code
$(function() // Shorthand for $(document).ready(function() {
$('select').change(function() {
if($(this).val() == 1)
{
$('#sub1').hide();
$('#sub2').show();
}
});
});
You nee to change minor change in your category select
<select size="6" id="category">
<option value="1">categories 1-3 </option>
<option value="2">----</option>
<option value="3">----</option>
</select>
$('select#category').on('change', function() {
$('div[id=^sub]:visible').hide();
$('div#sub' + this.value).show();
});
can also use .change() instead of .on('change').
$('select#category').change(function() {
$('div[id=^sub]:visible').hide();
$('div#sub' + this.value).show();
});
NOTE:
$('div[id=^sub]:visible') will point to all divs that have id start with sub and visible.
You are trying with $('#select') which need to be $('#category') or $('select#category').
According to your comment:
Complete solution will look like following:
function isOnlyDashed(text) {
return text.replace(/-/g, '').length === 0;
}
$('select#category').change(function() {
var text = $('option:selected', this).text();
if (!isOnlyDashed(text)) {
$('div[id=^sub]:visible').hide();
$('div#sub' + this.value).show();
}
});
$('select[name^=subc]').change(function() {
var text = $('option:selected', this).text();
if (!isOnlyDashed(text)) {
$(this).parent() // jump to parent div
.next('div[id^=sub]:hidden') // go to next hidden div
.show();
}
});
Complete Workout
The problem with your code is that you have an incorrect selector.
$('#select')...
should be
$('select')...
Also, this part is wrong
$('#sub' + $(this).find('option:selected').attr('id')).show();
Replace it with this
$('#sub' + $(this).val()).show();
Finally, having different elements with the same name/id "sub1" is probably a bad idea, though technically not illegal. It is certainly confusing.
working demo http://jsfiddle.net/FwBb2/1/
I have made minor changes in your Jquery code as well as added value in your first select drop-down list which was missing rest hope this helps.
Please lemme know if I missed anything! B-)
code
$('select').change(function() {
$('#sub1, #sub2, #sub3').hide();
$('#sub' + $(this).val()).show();
});
HTML
<html>
<select id="category">
<option value="1">categories 1-3 </option>
<option value="2">----</option>
<option value="3">----</option>
</select>
<div id="sub1" style="display:none">
<select name="subc1" size="6">
<option value="1">subcategories 4-6</option>
<option value="2">---</option>
<option value="3">---</option>
</select>
</div>
<div id="sub2" style="display:none">
<select name="subc2" size="6">
<option value="4">subcategories 7-9</option>
<option value="5">----</option>
<option value="6">----</option>
</select>
</div>
<div id="sub3" style="display:none">
<select name="subc3" size="6">
<option value="7">End</option>
<option value="8">----</option>
<option value="9">----</option>
</select>
</div>
</html>
My code below is showing the proper city/state div's when the matching country is selected from the drop down, but it's not hiding the previous one if the user decides to select another state. Do I have to create an if/else each for each div i want to hide?
<script type="text/javascript">
$(document).ready(function() {
...
//city & state display
$("#ctry").change(function() {
$(".state").hide();
var stateSelect = $("#state_" + $(this).val());
if (stateSelect.length === 0)
$("#state_label").hide();
else {
$("#state_label").show();
stateSelect.show();
}
});
});
</script>
html code:
<label>Country/Locale:</label>
<select id="ctry" name="country">
<option value="">-- Select</option>
<option value="US">United States</option>
<option value="CA">Canada</option>
<option value="GB">United Kingdom</option>
<option value="AU">Australia</option>
</select><br />
<!-- US -->
<div id="state_US" style="display:none">
<label id="state_label" style="display:none">State:</label>
<span class="rstate">
<select name="u_state">
<option value="">-- State US</option>
<option value="AL">Alabama</option>
</select>
</span>
Zip or City:<input style="margin-left:43px;" type="text" name="locus" id="locus" size="30" />
</div>
<!-- CA -->
<div id="state_CA" style="display:none">
<label id="state_label" style="display:none">Province:</label>
<span class="rstate">
<select name="c_state">
<option value="">-- Prov CA</option>
<option value="ON">Windsor</option>
</select>
</span>
Postal or Place:<input style="margin-left:43px;" type="text" name="locca" id="locca" size="30" />
</div>
<!-- GB -->
<div id="state_GB" style="display:none">
<label id="state_label" style="display:none">City or Region:</label>
<span class="rstate">
<select name="k_state">
<option value="">-- Place</option>
<option value="AU">UK!</option>
</select>
</span>
</div>
<!-- AU -->
<div id="state_AU" style="display:none">
<label id="state_label" style="display:none">City or Region:</label>
<span class="rstate">
<select name="a_state">
<option value="">-- Place</option>
<option value="AU">UK!</option>
</select>
</span>
</div>
Remove the state_label ids..
Add the unused class state to the state_CA, state_US etc. elements..
So each state group should be
<div id="state_US" class="state" style="display:none">
<label style="display:none">State:</label>
<span class="rstate">
<select name="u_state">
<option value="">-- State US</option>
<option value="AL">Alabama</option>
</select>
</span>
Zip or City:<input style="margin-left:43px;" type="text" name="locus" id="locus" size="30" />
</div>
And change your script to be
<script type="text/javascript">
$(document).ready(function() {
...
//city & state display
$("#ctry").change(function() {
$(".state").hide();
var stateSelect = $("#state_" + $(this).val());
stateSelect.show();
});
});
</script>
Demo at http://jsfiddle.net/gaby/PYx2v/
You cannot have multiple elements with the same ID. Your label state_Label is not unique. You should change this, otherwise some browsers will not show your label.
You hide all elements having the css-class "state". But there is no element having this class. I guess that you need to add class="state" to all of your state_*-divs.
Something like this logic might work for you:
var previous;
$(document).ready(function() {
$("#ctry").change(function() {
$(".state").hide();
var stateSelect = $("#state_" + $(this).val());
if (stateSelect.length === 0) {
$("#state_label").hide();
} else {
if (previous) {
previous.hide(function() {
$("#state_label").show();
stateSelect.show();
previous = stateSelect;
});
} else {
$("#state_label").show();
stateSelect.show();
previous = stateSelect;
}
}
});
});
Though it would be easier if they all had the same CSS class, with which you could easily hide them and then show the one that was selected.