Search code examples
javascriptjquerydatetimepicker

dynamic datetimepicker issue


What I did

I have created page where am adding datetime picker dynamically but now getting some problem here:

    for(i=0;i<5;i++){
             counter=i;
             var appendTxt = "<div style='display:none' class='divRow5 HideSchedule'><div class='divCellouter4'><div class='divCell2 rowwidth13 brdrStl4'><input name='NEW_STARTdatetime[]' class='dtpkr' type='textbox' readonly='readonly' id='NEW_STARTdatetime["+counter+"]' value='' autocomplete='off' size='10' /></div><div class='divCell2 rowwidth13  brdrSt14'><input name='NEW_ENDdatetime[]' readonly='readonly' autocomplete='off' class='dtpkr' type='textbox' id='NEW_ENDdatetime["+counter+"]' value='' size='10' /></div><div class='divCell2 rowwidth13  brdrSt14'><input name='NEW_START_TIME[]' type='textbox' class='tmpkr' id='NEW_START_TIME["+counter+"]' value='' size='10' /></div><div class='divCell2 rowwidth13  brdrSt14'><input name='NEW_END_TIME[]' type='textbox' class='tmpkr' id='NEW_END_TIME["+counter+"]' value='' size='10' /></div><div class='divCell2 rowwidth8   brdrSt14'><input type='checkbox' name='new_promo_chk[]' id='new_promo_chk["+counter+"]' class='checkbox regular-checkbox big-checkbox' checked /><label for='new_promo_chk["+counter+"]'></label></span> </div></div><div class='divCell2 handcursor'> <img class='del' src='images/delete.png' /></div></div>";
             $('[id$="NEW_STARTdatetime\\['+counter+'\\]"]').datetimepicker({
                   // minDate:'-1970/01/02',
                    format:'Y/m/d',                
                    onShow:function( ct ){                                
                        this.setOptions({
                         maxDate:$('#NEW_ENDdatetime\\['+counter+'\\]').val()?$('#NEW_ENDdatetime\\['+counter+'\\]').val():false
                        })
                    },
                    timepicker:false     
            });
            $('[id$="NEW_ENDdatetime\\['+counter+'\\]"]').datetimepicker({
                    //minDate:'-1970/01/02',
                    format:'Y/m/d',                
                    onShow:function( ct ){
                        console.log('#NEW_STARTdatetime\\['+counter+'\\]');
                        console.log($('#NEW_STARTdatetime\\['+counter+'\\]').val());
                              this.setOptions({
                               minDate:$('#NEW_STARTdatetime\\['+counter+'\\]').val()?$('#NEW_STARTdatetime\\['+counter+'\\]').val():false
                              })
                          },
                    timepicker:false          
            }); 
    }

so here now at the time of onshow it takes latest value of counter so my logic get fail,so how to fix that?


Solution

  • This is a simple case of closure surprises. Just move the functionality to a method and call it from the loop passing it counter in each turn. Like so:

    var myMethod = function myMethod (counter){
      var appendTxt = "<div style='display:none' class='divRow5 HideSchedule'><div class='divCellouter4'><div class='divCell2 rowwidth13 brdrStl4'><input name='NEW_STARTdatetime[]' class='dtpkr' type='textbox' readonly='readonly' id='NEW_STARTdatetime["+counter+"]' value='' autocomplete='off' size='10' /></div><div class='divCell2 rowwidth13  brdrSt14'><input name='NEW_ENDdatetime[]' readonly='readonly' autocomplete='off' class='dtpkr' type='textbox' id='NEW_ENDdatetime["+counter+"]' value='' size='10' /></div><div class='divCell2 rowwidth13  brdrSt14'><input name='NEW_START_TIME[]' type='textbox' class='tmpkr' id='NEW_START_TIME["+counter+"]' value='' size='10' /></div><div class='divCell2 rowwidth13  brdrSt14'><input name='NEW_END_TIME[]' type='textbox' class='tmpkr' id='NEW_END_TIME["+counter+"]' value='' size='10' /></div><div class='divCell2 rowwidth8   brdrSt14'><input type='checkbox' name='new_promo_chk[]' id='new_promo_chk["+counter+"]' class='checkbox regular-checkbox big-checkbox' checked /><label for='new_promo_chk["+counter+"]'></label></span> </div></div><div class='divCell2 handcursor'> <img class='del' src='images/delete.png' /></div></div>";
      $('[id$="NEW_STARTdatetime\\['+counter+'\\]"]').datetimepicker({
        // minDate:'-1970/01/02',
        format:'Y/m/d',                
        onShow:function( ct ){                                
        this.setOptions({
         maxDate:$('#NEW_ENDdatetime\\['+counter+'\\]').val()?$('#NEW_ENDdatetime\\['+counter+'\\]').val():false
        })
        },
        timepicker:false     
        });
      $('[id$="NEW_ENDdatetime\\['+counter+'\\]"]').datetimepicker({
        //minDate:'-1970/01/02',
        format:'Y/m/d',                
        onShow:function( ct ){
          console.log('#NEW_STARTdatetime\\['+counter+'\\]');
          console.log($('#NEW_STARTdatetime\\['+counter+'\\]').val());
          this.setOptions({
           minDate:$('#NEW_STARTdatetime\\['+counter+'\\]').val()?$('#NEW_STARTdatetime\\['+counter+'\\]').val():false
         })
        },
        timepicker:false          
      }); 
    }
    
    for(i=0;i<5;i++){
     myMethod(i);
    }
    

    Now for the explanation. The onshow will be activated asynchronously, most probably AFTER your loop has finished. Therefore it gets only last value of counter. By moving it into a method, you create a new scope each time you call it. Thus, the passed value is preserved.

    PS: I didn't check for any syntax errors.