How to bind events to components on a modal dialog? - javascript

I am using jQuery's modal dialog for opening a dialog containing a form. What I cannot solve is how to bind events to components that is added to my modal dialog. In this case, I want to bind click or change to a checkbox that has been positioned in the dialog. There doesn't seem to be any success-method that is triggered when the dialog has been loaded. This is how I do it:
This I do in the beginning of my javascript, in the beginning of the ready-function:
$( "#dialog:ui-dialog" ).dialog( "destroy" );
$( "#dialog-modal" ).dialog({
autoOpen: false,
show: "blind",
hide: "explode",
minWidth: 400,
modal: true
});
A bit later I do this when clicking a button:
$('#dialog-modal').dialog( "option", "title", lang.localized_text.ADD_AGENT);
$('#dialog-modal').live('dialogopen', function(msg){
alert("Opens");
$("#select_all").live('click', function(msg){
alert("clicked");
});
});
$.get("https://" + hostname + "/modules/core/useradmin/adminactivities/admin_add_agent.php",function(e){
var obj = $.parseJSON(e);
$("#dialog-modal").html(obj.html);
$("#dialog-modal").dialog("open");
addAddAgentValidation();
}
});
One can clearly see that alert("Opens") is presented before the dialog is opened. Hence, dialogopen is triggered before the dialog has finished loading. But the validation handler (calls the validate function which binds the validation checks) works.
alert("clicked"); is never triggered.
How can I bind any event to a component on the modal dialog? Is there any callback function when the dialog has been created.

Since your select will be in #dialog-modal and since #dialog-modal is present on domready (and never destroyed ?), you could use $.on()
$('#dialog-modal').on('click', '#select_all', function(e){
alert('clicked');
});
But you could also bind the click event when you include #select_all into the dom.
$.get("https://" + hostname + "/modules/core/useradmin/adminactivities/admin_add_agent.php",function(e){
var obj = $.parseJSON(e);
$("#dialog-modal").html(obj.html);
$('#select_all').click(function(e){
alert('clicked');
});
$("#dialog-modal").dialog("open");
addAddAgentValidation();
}

You can bind it with the .on method, which replaced .live in a recent jQuery release. In this case you bind it to something that you know is there when the DOM is ready (like the body). Now you only need to bind once and it will fire every time you click on a #select_all.
$("body").on('click', '#select_all', function () {
alert("clicked");
});
http://api.jquery.com/on/

Related

Why is my jquery executing on second click only?

I've written a jQuery function which updates a div upon clicking another div. However, it is only firing on the second click each time and I'm rather confused.
How can I fix this?
$(document).ready(function(){
$(".block-swatch").click(function(){
$("#refresh-feefo").load(window.location.href + " #refresh-feefo" );
});
});
You should consider using .on as it allow to bind event from a parent and if your DOM element #refresh-feefo isn't ready, it will still work.
$(document).ready(function(){
$("body").on('click', '.block-swatch', () => {
$("#refresh-feefo").load(window.location.href + " #refresh-feefo" );
});
});
I used body , but be careful:
Hierarchical selectors can often be avoided simply by attaching the handler to a more appropriate point in the document. For example, instead of $( "body" ).on( "click", "#commentForm .addNew", addComment ) use $( "#commentForm" ).on( "click", ".addNew", addComment ).
Read Event performance section here for more: https://api.jquery.com/on/

Components inserted into page using jquery's .load() function don't have a handle to javascript [duplicate]

On this page I have a jQuery popup window and thumbnail resizable images. If I mouse over on the thumbnails, the images are resizing perfectly. Also, when I click on the big yellow TV button "QuickBook TV" in the footer, the popup appears perfectly as I want it to.
However, when I click on the "Next" or "Prev" buttons, AJAX is used to load the new content and my jQuery no longer functions for the popup or thumbnail images. I have searched a number of forums looking for information on this issue, but due to having limited knowledge of jQuery I've been unable to understand what I need to do.
Following is the popup jQuery
$(document).ready(function() {
$(".iframe").colorbox({ iframe: true, width: "1000px", height: "500px" });
$(".inline").colorbox({ inline: true, width: "50%" });
$(".callbacks").colorbox({
onOpen: function() { alert('onOpen: colorbox is about to open'); },
onLoad: function() { alert('onLoad: colorbox has started to load the targeted content'); },
onComplete: function() { alert('onComplete: colorbox has displayed the loaded content'); },
onCleanup: function() { alert('onCleanup: colorbox has begun the close process'); },
onClosed: function() { alert('onClosed: colorbox has completely closed'); }
});
//Example of preserving a JavaScript event for inline calls.
$("#click").click(function() {
$('#click').css({ "background-color": "#f00", "color": "#fff", "cursor": "inherit" }).text("Open this window again and this message will still be here.");
return false;
});
});
And this is the thumbnails jQuery
$(function() {
var xwidth = ($('.image-popout img').width())/1;
var xheight = ($('.image-popout img').height())/1;
$('.image-popout img').css(
{'width': xwidth, 'height': xheight}
); //By default set the width and height of the image.
$('.image-popout img').parent().css(
{'width': xwidth, 'height': xheight}
);
$('.image-popout img').hover(
function() {
$(this).stop().animate( {
width : xwidth * 3,
height : xheight * 3,
margin : -(xwidth/3)
}, 200
); //END FUNCTION
$(this).addClass('image-popout-shadow');
}, //END HOVER IN
function() {
$(this).stop().animate( {
width : xwidth,
height : xheight,
margin : 0
}, 200, function() {
$(this).removeClass('image-popout-shadow');
}); //END FUNCTION
}
);
});
jQuery selectors select matching elements that exist in the DOM when the code is executed, and don't dynamically update. When you call a function, such as .hover() to add event handler(s), it only adds them to those elements. When you do an AJAX call, and replace a section of your page, you're removing those elements with the event handlers bound to them and replacing them with new elements. Even if those elements would now match that selector they don't get the event handler bound because the code to do that has already executed.
Event handlers
Specifically for event handlers (i.e. .click()) you can use event delegation to get around this. The basic principle is that you bind an event handler to a static (exists when the page loads, doesn't ever get replaced) element which will contain all of your dynamic (AJAX loaded) content. You can read more about event delegation in the jQuery documentation.
For your click event handler, the updated code would look like this:
$(document).on('click', "#click", function () {
$('#click').css({
"background-color": "#f00",
"color": "#fff",
"cursor": "inherit"
}).text("Open this window again and this message will still be here.");
return false;
});
That would bind an event handler to the entire document (so will never get removed until the page unloads), which will react to click events on an element with the id property of click. Ideally you'd use something closer to your dynamic elements in the DOM (perhaps a <div> on your page that is always there and contains all of your page content), since that will improve the efficiency a bit.
The issue comes when you need to handle .hover(), though. There's no actual hover event in JavaScript, jQuery just provides that function as a convenient shorthand for binding event handlers to the mouseenter and mouseleave events. You can, however, use event delegation:
$(document).on({
mouseenter: function () {
$(this).stop().animate({
width: xwidth * 3,
height: xheight * 3,
margin: -(xwidth / 3)
}, 200); //END FUNCTION
$(this).addClass('image-popout-shadow');
},
mouseleave: function () {
$(this).stop().animate({
width: xwidth,
height: xheight,
margin: 0
}, 200, function () {
$(this).removeClass('image-popout-shadow');
}); //END FUNCTION
}
}, '.image-popout img');
jQuery plugins
That covers the event handler bindings. However, that's not all you're doing. You also initialise a jQuery plugin (colorbox), and there's no way to delegate those to elements. You're going to have to simply call those lines again when you've loaded your AJAX content; the simplest way would be to move those into a separate named function that you can then call in both places (on page load and in your AJAX requests success callback):
function initialiseColorbox() {
$(".iframe").colorbox({
iframe: true,
width: "1000px",
height: "500px"
});
$(".inline").colorbox({
inline: true,
width: "50%"
});
$(".callbacks").colorbox({
onOpen: function () {
alert('onOpen: colorbox is about to open');
},
onLoad: function () {
alert('onLoad: colorbox has started to load the targeted content');
},
onComplete: function () {
alert('onComplete: colorbox has displayed the loaded content');
},
onCleanup: function () {
alert('onCleanup: colorbox has begun the close process');
},
onClosed: function () {
alert('onClosed: colorbox has completely closed');
}
});
}
Had the same problem before I was able to found the solution which worked for me.
So if anyone in future can give it a shot and let me know if it was right since all of the solutions I was able to find were a little more complicated than this.
So as said by Tamer Durgun, we will also place your code inside ajaxStop, so your code will be reinstated each time any event is completed by ajax.
$( document ).ajaxStop(function() {
//your code
}
Worked for me :)
// EXAMPLE FOR JQUERY AJAX COMPLETE FUNC.
$.ajax({
// get a form template first
url: "../FPFU/templates/yeni-workout-form.html",
type: "get",
success: function(data){
// insert this template into your container
$(".content").html(data);
},
error: function(){
alert_fail.removeClass("gizle");
alert_fail.addClass("goster");
alert_fail.html("Template getirilemedi.");
},
complete: function(){
// after all done you can manupulate here your new content
// tinymce yükleme
tinymce.init({
selector: '#workout-aciklama'
});
}
Your event handlers are being lost when you replace the content. When you set you hover events, jQuery is setting them on the events on the page currently. So when you replace them with ajax, the events are not associated with those elements because they are new.
To fix this you can either call the function that binds them again or you can instead set the event handler on the document as in this answer using $(document).on
That way the event is set on the document and any new elements will get the event called.
You Can User jQuery's delegate() method which Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.In my case it's working as expected
this $(selector).click(function(e){}
become this after Using delegate() method
$( "body" ).delegate( "selector", "click", function(e) {}
Hope this will help ;)
You can use jQuery ajax's complete function after retrieving data form somewhere, it will see updated elements after ajax complete
This worked for me,
instead of:
$(document).ready(function(){
//code
});
I did:
$(document).on('mouseenter', function(){
//code
});
I'm late to the party but I would combine two of the answers. What worked for my specific needs was to incorporate the ajaxstop within the complete
complete: function () {
$( document ).ajaxStop(function() {
//now that all have been added to the dom, you can put in some code for your needs.
console.log($(".subareafilterActive").get().length)
})
}
Just an alternative.
$(window).on('load', _ => {
// some jQuery code ..
})
This binds any delegated handler to the window. It will fire once the window is fully loaded including all graphics/includes/hooks/requests not just the DOM.
$(document).ready(_ => ... preserves events to be fired after only the DOM is ready which does not apply on dynamically loaded content by AJAX. Either you can run a function or any event when a specific element is fully loaded by defining it as #Anthony Grist explained in his answer or bind your load event to the window as shown above.
https://api.jquery.com/load-event/
https://api.jquery.com/on/#on-events-selector-data-handler

listening event after id changing

I want to modify an Id of button 'B' when button 'A' is clicked, and listen to the click event of of 'B' using Jquery but my code doesn't work,
this is an example of my code:
$(function() {
$(".nuttonA").click(
function() {
$("#buttonB").attr("id","notButtonB");
});
$("#notButtonB").click(function(){
console.log(" notButtonB is clicked "); //show nothing
});
});
i think you need event delegation. try this:
$(function() {
$(".buttonA").click(
function() {
$("#buttonB").attr("id","notButtonB");
});
$( "body" ).on( "click", "#notButtonB",function(){
console.log(" notButtonB is clicked "); //show nothing
});
});
Currently what you are using is called a "direct" binding which will only attach to element that exist on the page at the time your code makes the event binding call.
You need to use Event Delegation using delegated-events approach when manipulation properties.
General Syntax
$(document).on('event','selector',callback_function)
Example
$(document).on('click', ".nuttonA", function(){
$("#buttonB").attr("id","notButtonB");
});
$(document).on('click', "#notButtonB", function(){
//Your code
});
In place of document you should use closest static container.

Id base selector jquery click event not working in Single page application

I am working with single page application, trying simple click event, its working with first screen but not working with second or third screen...
$("#Signup").click(function() {
alert("click success");
$("#ButtonAction1").modal({
show: true
});
});
You must not use the same ID for different elements in the same page, use classes instead.
Make sure your DOM is already fully loaded.
$(function() {
$("#Signup").click(function() {
alert("click success");
$("#ButtonAction1").modal({
show: true
});
});
});
If you add an element after the click event handler has been added, the element won't inherit it.
Try using the on instead of the click since it works with dynamic elements and delegates the events.
You can check out the difference between the methods here Difference between .on('click') vs .click()
$("#Signup").on('click',function() {
alert("click success");
$("#ButtonAction1").modal({
show: true
});
});
It looks like you're buttons are dynamically loaded. You can use the following:
$('document').on('click', '#Signup',
function(){
alert("click success");
$("#ButtonAction1").modal({
show: true
});
}
);
Source:
https://stackoverflow.com/a/16898442/6671505
$('#PARENT').on('click', '#DYNAMICALLY_ADDED_CHILD', function(){ CODE HERE });

Click action doesn't work with dialog

I have problem with dialog and click action.
$("a[data-file]").click(function(e){
e.preventDefault();
getXML($(this).attr('data-file'));
});
This code works correctly with constant anchors but doesn't works with anchors in jQuery dialog. I have tried also:
$("document").on( "click", "a[data-file]", function() {
e.preventDefault();
getXML($(this).attr('data-file'));
});
But it doesn't work. How I should resolve this issue?
You have wrapped document in quotes, which looks for element with tagname document. which do not exists.
You need to use document object here while using event delegation:
$(document).on( "click", "a[data-file]", function() {
e.preventDefault();
getXML($(this).attr('data-file'));
});

Categories

Resources