0

How do you hook into javascript / popup functionality that is invoked after a user clicks?

We have javascript code that gets invoked by a user click. This javascript code renders a popup dialog that contains an choose file tag. This choose file tag is literally appended by doing something like:

output.append('<input type="file" ......'>

So the problem with this is if the user doesn't first click this tag never gets rendered in the response.

We are currently using a jQuery $() function to execute our code that looks for tags as soon as the web page loads, however our $() function does not get called when the user clicks the link rendering the popup.

Is there another hook we can use in jQuery besides $() that gets invoked when a popup gets rendered?

user1068636
  • 1,871
  • 7
  • 33
  • 57

3 Answers3

1

If I understand correctly, you want to attach an event handler at page load time to an input that will not exist until the user clicks a link. One solution is to use event delegation. You can look for "delegated events" in the documentation for the .on() function.

Basically, you call .on() on an element that already exists in the DOM that is an ancestor of the element that will be added later. You supply a selector as the second parameter that identifies the element you want the handler to execute for.

You could use:

$(document).ready(function() {
    $(document.body).on('click', 'input:file', function() {
        ...
    });
});

But it is more efficient to use a closer ancestor than the <body> element if you can, and you might have a better selector for identifying the file input element than the one I show above (since it will match all file input elements).

John S
  • 21,212
  • 8
  • 46
  • 56
  • It appears like the version of jQuery I am using does not allow for $(document.body) because I get [undefined]. However, it works correctly if I simply do $(document).click(function () {...}); But I noticed this has caused a performance hit. Is there a more clever way to do this in jQuery 1.7 ? – user1068636 Dec 25 '13 at 18:33
  • @user1068636 - I was missing a comma in the code, but that would cause a different error. The version of jQuery should not matter for using `document.body`, but the body element does not exist until the document is ready, so it should be inside a document ready handler, as I am now showing in my answer. – John S Dec 25 '13 at 18:59
  • @user1068636 - I am surprised you are seeing a performance hit. But as I say in my answer, try to use the closest ancestor of the file input element as you can. It must be an element that exists when the page is first created though. You could also put a class or an id on the file input element and use it in the selector. For example, if you gave it `id="fileChooser"`, you could use `'#fileChooser'` instead of `'input:file'`. – John S Dec 25 '13 at 19:03
0

Either create proper elements with event handlers :

var file_input = $('<input />', {
    type : 'file',
    on   : {
        change : function() {
            // do stuff
        }
    }
});

output.append(file_input);

or use a delegated event handler

output.on('change', '.file_input', function() {
    // do stuff
});

output.append('<input type="file" class="file_input" ......'>
adeneo
  • 312,895
  • 29
  • 395
  • 388
0

Of course it is possible. You have to define your function for the later rendered element after it is rendered.

HTML:

<div id="holder">
    <button id='first'>first</button>
</div> 

JQuery:

$('#first').click(function () {
    alert('first click');
    $('#holder').append("<input id='second' type='file' name='pic' accept='image/*'>");
    $('#second').click(function () {
        alert('second click');
    });
});

Here is a demo: JSFIDDLE

Airan
  • 477
  • 2
  • 13