jQuery datepicker not working on dynamically gener

2019-09-07 04:02发布

问题:

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 can't explain, the datepicker is not working.

P.S I have tried this and several others like it but they did not work in my case, hence my asking this.

回答1:

Rewrite your .datepicker() to traverse down $(document), which will find your respected 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")
        })
    });

That, or check to make sure you haven't got any JavaScript errors prior to the .datepicker() initialisation which could be 'blocking' the execution.



回答2:

You need to delegate the event.

For ease of selecting, add a class to your datepickers

 '<input type="text" class="mydatepickclass"  ....

and then you can use a listener that targets a parent that exists at dom-ready, with this child. Use a parent div, or if none, go all the way out to the body. It also doesn't need to be in the loop.

$("body .mydatepickclass").datepicker({
     //options...  and use $(this) or $this to target the selected items, not i
});

so, to re-write your entire 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>


回答3:

You have two problems in your code, #1 is you keep adding a datepicker and then later overwrite the entire innerHtml - breaking the datepickers added. The other one is related to the event handler which uses the same handler (with same i value) for all datepickers (see fix at Bug#2 below).

One way to fix bug #1 is to add all the html (and update the DOM only once for efficency and not 10 times), and then create all the datepicker

See JSFiddle: http://jsfiddle.net/byhpc73L/2/

Bug #2: You have a bug passing the parameter "i" to the onSelect handler - all handlers will use the same i which will be 11 when the loop finishes. You need a closure to bind the current i value to a 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 */
    });
}