JQuery datepicker not working with dynamically generated HTML
I have this code:
<div id="infants-data"></div>
for( var i = 1; i <= 10; i++)
{
var currInfantDataField = '' +
'<div class="field">Infant ' + i + ': ' +
'<div style="width:600px">' +
'<select id="infant-' + i + '-title" style="border:solid 1px #cccccc;">'+
'<option selected>--Title--</option>' +
'<option value="master">Master</option>' +
'<option value="miss">Miss</option>' +
'</select>' +
'<input type="text" id="infant-' + i + '-surname" placeholder="Surname" style="width:110px; border:solid 1px #cccccc;">' +
'<input type="text" id="infant-' + i + '-othernames" placeholder="Othernames" style="width:120px; border:solid 1px #cccccc;">' +
'<input type="text" id="infant-' + i + '-birthdate" placeholder="Date of Birth" style="width:120px; border:solid 1px #cccccc;" readonly>' +
'</div>' +
'</div>';
document.getElementById('infants-data').innerHTML += currInfantDataField;
jQuery( "#infant-" + i + "-birthdate").datepicker({
changeMonth: true,
changeYear: true,
yearRange:'1900:<?php echo ( date('Y') - 2 ); ?>',
onSelect: (function(){doSomethingUsefulWithField("infant-" + i + "-birthdate")})
});
}
For some reason I cannot explain, the datapick is not working.
PS I tried this one and some others liked it, but they didn't work in my case, so I ask about this. p>
source to share
You have two problems in your code, # 1 - you keep adding datepickers and then overwrite all innerHtml - break adding datepickers. The other has to do with an event handler that uses the same handler (with the same value i
) for all datepickers (see Bug # 2 fix below).
One way to fix bug # 1 is to add all the html (and update the DOM only once for efficiency, not 10 times) and then create all the datepicker parameters
See JSFiddle: http://jsfiddle.net/byhpc73L/2/
Mistake # 2: You have a bug passing the "i" parameter to the onSelect handler - all handlers will use the same one i
, which will be 11 when the loop ends. You need to close in order to bind the current value i
to the function - see below.
eg.
for (var i=1; i<=10; i++) { ... create html string ... }
.. update DOM from html string
for( var i = 1; i <= 10; i++) {
jQuery( "#infant-" + i + "-birthdate").datepicker({
changeMonth: true,
changeYear: true,
yearRange:'1900:2015',
onSelect:(function(ii) { return function(){doSomethingUsefulWithField("infant-" + ii + "-birthdate")}
})(i) /* note the function gets `i` and returns a function bound to the current value */
});
}
source to share
Rewrite yours .datepicker()
to go down $(document)
which will find your dear new 'html'
jQuery("#infant-" + i + "-birthdate", document).datepicker({
changeMonth: true,
changeYear: true,
yearRange:'1900:<?php echo ( date('Y') - 2 ); ?>',
onSelect: (function(){
doSomethingUsefulWithField("infant-" + i + "-birthdate")
})
});
This or make sure you don't have JavaScript errors before initialization .datepicker()
that might "block" execution.
source to share
You need to delegate the event.
Add a class to your dump for easier selection
'<input type="text" class="mydatepickclass" ....
and then you can use a listener that targets the parent that exists in dom-ready with that child. Use the parent div, or if there is one, go to the body. It also shouldn't be in a loop.
$("body .mydatepickclass").datepicker({
//options... and use $(this) or $this to target the selected items, not i
});
so to rewrite the whole loop,
<div class="wrapper">
<div id="infants-data"></div>
<script>
for( var i = 1; i <= 10; i++)
{
var currInfantDataField = '' +
'<div class="field">Infant ' + i + ': ' +
'<div style="width:600px">' +
'<select id="infant-' + i + '-title" style="border:solid 1px #cccccc;">'+
'<option selected>--Title--</option>' +
'<option value="master">Master</option>' +
'<option value="miss">Miss</option>' +
'</select>' +
'<input type="text" id="infant-' + i + '-surname" placeholder="Surname" style="width:110px; border:solid 1px #cccccc;">' +
'<input type="text" id="infant-' + i + '-othernames" placeholder="Othernames" style="width:120px; border:solid 1px #cccccc;">' +
'<input type="text" class="mydatepickclass" id="infant-' + i + '-birthdate" placeholder="Date of Birth" style="width:120px; border:solid 1px #cccccc;" readonly>' +
'</div>' +
'</div>';
document.getElementById('infants-data').innerHTML += currInfantDataField;
}
jQuery( ".wrapper .mydatepickclass").datepicker({
changeMonth: true,
changeYear: true,
yearRange:'1900:<?php echo ( date('Y') - 2 ); ?>',
onSelect: (function(){doSomethingUsefulWithField($(this).val())})
});
</script>
</div>
source to share