I have some JS that dynamically creates a new div (inputs inside of a form). It works great. I separately have some jquery that checks a dropdown input, and shows a separate div if a specific selection is clicked. It works great.
If I try to use the jquery to show a separate div inside one of the dynamically created ones, it does not work. The first instance of it does work, but none of the dynamically created ones. After searching around, it looks like I need a delegation, but I can't seem to figure it out for my specific situation.
The JSFiddle: / (change the "CPI" dropdown in the first field, for the event to go off). The fiddle includes the other JS for dynamically creating the divs.
Any pointers would be appreciated.
<div style="float:left">
<div id='dynamicInput'>Pension 1: Amount: $<input type='text' name='adjustmentInputs[]' value='0' size='13' maxlength='20'>Start Year:
<input type='text' name='adjustmentInputs[]' value='2032' size='5' maxlength='6'>
<input type='hidden' name='adjustmentInputs[]' value='2100'>
<select name='adjustmentInputs[]'>
<option value='InflationAdjusted'>Inflation Adjusted</option>
<option value='NotInflationAdjusted'>Not Inflation Adjusted</option>
</select>by
<select name='adjustmentInputs[]' class='pensionAdjustment1'>
<option value='CPI'>CPI</option>
<option value='constantPercentage'>Constant %</option>
</select>
<div id='constantPercentageText1' style='display: none'>@ <input type='text' name='adjustmentInputs[]' value='3' size='5' maxlength='6'>%</div>
</div>
<input type="button" value="Add another Portfolio Adjustment" onClick="addInput('dynamicInput');">
</div>
<script>
$("[class*=pensionAdjustment]").change(function() {
var n = $(this).attr('class').replace('pensionAdjustment', '');
var newId = "constantPercentageText" + n;
var selectedItem = $(this).children('option:selected');
if ($(this).val() == 'constantPercentage') {
$("#constantPercentageText" + n).css('display', 'inline');
$("#constantPercentageText" + n).show();
} else {
$("#constantPercentageText" + n).css('display', 'none');
}
});
</script>
I have some JS that dynamically creates a new div (inputs inside of a form). It works great. I separately have some jquery that checks a dropdown input, and shows a separate div if a specific selection is clicked. It works great.
If I try to use the jquery to show a separate div inside one of the dynamically created ones, it does not work. The first instance of it does work, but none of the dynamically created ones. After searching around, it looks like I need a delegation, but I can't seem to figure it out for my specific situation.
The JSFiddle: http://jsfiddle/Xyzeg/ (change the "CPI" dropdown in the first field, for the event to go off). The fiddle includes the other JS for dynamically creating the divs.
Any pointers would be appreciated.
<div style="float:left">
<div id='dynamicInput'>Pension 1: Amount: $<input type='text' name='adjustmentInputs[]' value='0' size='13' maxlength='20'>Start Year:
<input type='text' name='adjustmentInputs[]' value='2032' size='5' maxlength='6'>
<input type='hidden' name='adjustmentInputs[]' value='2100'>
<select name='adjustmentInputs[]'>
<option value='InflationAdjusted'>Inflation Adjusted</option>
<option value='NotInflationAdjusted'>Not Inflation Adjusted</option>
</select>by
<select name='adjustmentInputs[]' class='pensionAdjustment1'>
<option value='CPI'>CPI</option>
<option value='constantPercentage'>Constant %</option>
</select>
<div id='constantPercentageText1' style='display: none'>@ <input type='text' name='adjustmentInputs[]' value='3' size='5' maxlength='6'>%</div>
</div>
<input type="button" value="Add another Portfolio Adjustment" onClick="addInput('dynamicInput');">
</div>
<script>
$("[class*=pensionAdjustment]").change(function() {
var n = $(this).attr('class').replace('pensionAdjustment', '');
var newId = "constantPercentageText" + n;
var selectedItem = $(this).children('option:selected');
if ($(this).val() == 'constantPercentage') {
$("#constantPercentageText" + n).css('display', 'inline');
$("#constantPercentageText" + n).show();
} else {
$("#constantPercentageText" + n).css('display', 'none');
}
});
</script>
Share
Improve this question
asked Jul 16, 2013 at 18:19
bo_knowsbo_knows
8562 gold badges9 silver badges21 bronze badges
3
- You must delegate events to an element which exists at the time the events are bound. – Evan Davis Commented Jul 16, 2013 at 18:21
-
To expand on @Mathletics ment, check out jQuery.on.
$(document).on('change', "[class*=pensionAdjustment]", function() {...
– dinjas Commented Jul 16, 2013 at 18:22 - So, you're saying that because the dynamically created divs don't exist before the search occurs, I can't bind the events like I am? What's the solution then? – bo_knows Commented Jul 16, 2013 at 18:23
3 Answers
Reset to default 3You need to delegate with newly created elements!
Change this line
$("[class*=pensionAdjustment]").change(function() {
to
$(document).on('change',"[class*=pensionAdjustment]", function() {
You can use
$(document).on('change', '[class*=pensionAdjustment]', function(){
// your code
});
It would be better if you use a parent div, instead of document
.
Update : The elements you are injection dynamically to the DOM
were not present when the event was registered, so new elements are not firing the event. Using event delegation
, (registering the event
on a parent element) this could be solved because when any element fires an event, the event bubbles up to the last element (upwards) it can find and this way the parent element is being triggered but behind the scene, something like following is happening
e = e || window.event;
var el = e.target || e.srcElement;
You may check this.
You have to bind the event to a parent element, then filter down to the one you want. This way it doesn't matter when the element is added, it will always work. This is called delegation. You delegate the task of handling the event to another element.
$(document).on('change', "[class*=pensionAdjustment]", function(){
var n = $(this).attr('class').replace('pensionAdjustment', '');
var newId = "constantPercentageText" + n;
var selectedItem = $(this).children('option:selected');
if ($(this).val() == 'constantPercentage') {
$("#constantPercentageText" + n).css('display', 'inline');
$("#constantPercentageText" + n).show();
} else {
$("#constantPercentageText" + n).css('display', 'none');
}
});