Search code examples
javascriptjqueryevent-delegation

Javascript Event Delegtion -- Adding a timepicker to a popup form


I am attempting to create a timepicker inside of a popup form. I am struggling with event delegation -- I am capable of getting the timepicker to work outside of the form, but not inside.

My current code, which does not have the timepicker popup:

 $(document).ready(function() {
   $('#timepick').timepicker({
     showPeriod: true,
     showLeadingZero: true
   });
 });

$(function() {
    $( "#dialog-form" ).dialog({
        autoOpen: false,
        height: 300,
        width: 350,
        modal: true,
        buttons: {
            "Add Time": function() {
                    $( "#time-table tbody" ).append( "<tr>" +
                        "<td>" + time.value + "</td>" + 
                    "</tr>" ); 
                    $( this ).dialog( "close" );
            },
            Cancel: function() {
                $( this ).dialog( "close" );
            }
        },
    });

    $("#add-time").button().click(function() {
            $( "#dialog-form" ).dialog( "open" );
    });
});

This does not work inside of the popup box, only for #timepick outside of it. I know I somehow need to utilize the .on() jquery function.

        $(document).ready(function() {
            $('#timepick').on("click", function(){
                timepicker({
                showPeriod: true,
                showLeadingZero: true
            });
        });

Did not work either.

A pastebin of the current tryout:

http://pastebin.com/gta7TD47

EDIT:

So this MOSTLY works:

        $(document).ready(function() {
          $('#dialog-form').on('click','#time',function() {
            $('#time').timepicker({
                showPeriod: true,
                showLeadingZero: true
            });
          });
        });

The only problem is, it currently requires you to click on the box, which then adds the event handler, and then click off and click back on -- so it requires a click before working. How do I get it to fire immediately? Somehow using .trigger()?


Solution

  • You're not delegating anything. You're merely binding the event directly on the timepick element.
    If you want to delegate an event, you'll need an aditional selector:

    $('body').on('click','.allElementsYouNeedSelector',function(){});
    

    The code above will apply the anonymous callback function as an event handler for all click events that are triggered on any element that has the allElementsYouNeedSelector class, anywhere in the $('body') tag.
    So if you want to delegate from, say your dialog-form element:

    $('#dialog-form').on('click','*',function()
    {//will be called when any child of the #dialog-form is clicked
    });
    

    Mind you, if you use the on method like this, it's translated to the delegate method internally.

    Update:
    In light of your update, I must say: it makes no sense at all to delegate an event for an element that has a unique ID. Perhaps you could try this:

    $('#time').on('click',{showPeriod: true,showLeadingZero: true},timepicker);
    

    This binds a click listener to the #time element, and applies the timepicker method as an event handler, passing the object literal {showPeriod: true,showLeadingZero: true} as an argument, just like you're doing. Of course, you can do the same thing using delegation:

    $('#dialog-form').on('click','*',function()
    {//regardles of which child was clicked, apply the timepicker method to #time
        $.timepicker.apply($('#time'),[{showPeriod: true,showLeadingZero: true}]);
    });
    

    As ever, to avoid having to scan the DOM on each call, you can add a closure

    $('#dialog-form').on('click','*',(function(time)
    {
        return function()
        {
            time = time || $('#time');//in case $('#time') didn't exist when function was created
            $.timepicker.apply(time,[{showPeriod: true,showLeadingZero: true}]);
        };
    }($('#time')));