How do you properly attach events to elements in a popup?
This is how I currently do it:
HTML
<div id="userDetail">
<input id="checkbox" type="checkbox" />
<div id="button-confirm"></div>
</div>
JavaScript
var userDetail = $("#userDetail").dxPopup({
width: '550',
height: 'auto',
showTitle: true,
title: "Setup Import Template",
visible: false,
onShown: function () {
$('#checkbox').one('click', function () {
$('.template-view').toggle();
});
$("#button-confirm").dxButton({
onClick: function (e) {
e.jQueryEvent.preventDefault();
templateDataPopup.hide();
}
});
}
}).dxPopup('instance');
The problem with this is that:
Every time the popup is shown, the jQuery attaches new click event to #checkbox element, event after I use .one().
#button-confirm element's click event is NOT being attached twice. This is the behavior I want (although it's not what I expected, I think because it's a DevExpress instance).
I have tried attached events to elements in the popup before I initialized the popup, but for some reason, after the popup is shown, none of the elements' events work.
So, how do you properly attach events to elements in a popup?
Thanks!
I got answer from DevExpress support and the suggestion is to use contentTemplate. The reply:
Use the contentTemplate property to create popup content and add the
required events to it:
contentTemplate: function (contentElement) {
contentElement.append('<input id="checkbox" type="checkbox" />');
var hideButton = $("<div id='button-confirm'>").dxButton({
text: "Hide popup",
onClick: function (e) {
popupInstance.hide();
}
});
contentElement.append(hideButton);
}
So, instead of attaching the event through onShown event, it's recommended to attach in contentTemplate.
You can also load popup content from HTML tag in contentTemplate
Related
How does $(this).keyup know I want the keyup listener associated with the #searchString input, and not the parent div? Doesn't $(this) represent the parent div? I dumped out $(this) to the console, and it looks like an object for the parent div.
Long story short:
How is this working? $(this).keyup
Instead of explicitly saying: $('#searchString').keyup ??
$('<div id="msg">' + <input id="searchString" name="searchString" type="text" value="" /> + '</div>').dialog({
open: function () {
$(this).keyup(function (e) {
if (e.keyCode == $.ui.keyCode.ENTER)
$('#btnFind').click();
return false;
})
},
buttons: [
{
text: "Find",
id: "btnFind",
icon: "ui-icon-search",
click: function () {
//do stuff
}
}
]
});
Did some testing; here are my observations:
$(this) is representative of the parent <div id="msg">
$(this).keyup is targeting any (and all) extra inputs I add to <div id="msg">
I don't think this this is event bubbling/capturing (the listeners are not nested):
$('#btnFind').click(); is an action nested inside the keyup listener
the jQuery UI dialog button id: "btnFind" has a separate event listener, outside of the the parent <div id="msg">
I went ahead and explicitly indicated the target for the listener: $('#searchString').keyup
Who cares?
Well, I didn't think you could establish event listeners on inputs via the dialog open event. I'm creating my dialog on-the-fly, and my assumption was that the input may not exist while the open event was trying to establish the event listener.
We are using the Magnific library to display the PopUps in our site. Everything with this is going well except one thing.
when we add an element dynamically, popup is not working for the dynamically added elements. Can you please help me how I can bind the click event for the dynamically added element to display the popup? Here is my code is given below:
`<a id="del-vis-archive-new-{{$request->id}}" href="#delete-visitor-archive" data-id="{{$request->id}}" class="popup-form-delete-visitor-archive" style="color:red;"><i style="color:red; text-align: right;" class="hi hi-trash"></i></a>
var PopupDelVisArchive = function() {
$('.popup-form-delete-visitor-archive').magnificPopup({
type: 'inline',
preloader: false,
focus: '#name',
callbacks: {
open: function() {
var dataId = $(this.st.el).attr('data-id');
$("#btn").attr('data-id', dataId);
}
}
});
}
$(document).on( 'init.dt, draw.dt', function ( e, settings ) {
PopupDelVisArchiv();
});`
The class is responsible for displaying the pop-up
but it doesn't work for the dynamically added elements.
In other words, the click event is not getting registered in the DOM for the newly added elements.
You need to bind the popup to each new element after they are loaded in the dom. That means calling PopupDelVisArchiv(); for each new element once dom ready.
I have kendo window and im adding content dynamically to kendo window.
The content has a button and i wanted to attach click event to that button.
jQuery is able to find the button from the content, attach click event however click event never gets fired
JSFiddle
Html
<div id="example">
<div id="window">
</div>
</div>
JQuery
$(document).ready(function() {
// in reality this contnet will be returned from ajax call
var dynamicContent ="<div><button id='btn' type='button'>Click Me</button></div>"
var myWindow = $("#window")
var button = $(dynamicContent).find("#btn");
// show number of buttons found.
alert("found " + button.length + " button")
// attach click event to button
button.click(function(){
alert("this is test");
})
myWindow.kendoWindow({
width: "600px",
height:"200px",
title: "My Window"
}).data("kendoWindow").center().open().content(dynamicContent);
});
You need to change:
button.click(function(){
alert("this is test");
})
to
$('#window').on('click', 'button', function(){
alert("this is test");
})
As you mentioned the element is dynamically created, so it is not part of the browsers dom structure, and therefore can't be selected with jQuery. Using the above code, jQuery listens for any changes to the dom structure inside the #window element, so you can then select any dynamically created elements.
I need to be able to detect any click that happens within a specific container referenced by class, if the user clicks on any of the nested elements I should be able to detect the click and update a flag
<div class="container" >
<div class="x1">
<div class="x2">
<div class="">
<span class="">
<ul class="">
</div>
</div>
I tried using jquery but I prefer to do it using backbone.
//$(document).on('click','.container', function(e){
//$('.container').delegate("div", "click", function(e) {
Not sure what event I need to use when the users are clicking in some of the nested elements within the div that have the container class. Basically, I need to update a flag in case of the user clicks outside of this div, but I don't want to have a large scope on the event handler that listens to the whole body.
Since you asked for a Backbone example, here's how to listen to clicks on a div and its children.
var View = Backbone.View.extend({
className: "my-test-view",
template: '<div class="container"><div class="x1"><div class="x2">test</div></div></div>',
events: {
'click .container': 'onClick',
},
render: function() {
this.$el.empty().append(this.template);
return this;
},
onClick: function(e) {
console.log("clicked on", e.target, " triggered from ", e.currentTarget);
},
});
var view = new View();
$("body").append(view.render().el);
Clicking the test text should output:
clicked on <div class="x2">test</div> triggered from <div class="container">…</div>
With jQuery, the above is (roughly) the equivalent to:
$('.my-test-view').on('click', '.container', function(e) {
console.log("clicked on", e.target, " triggered from ", e.currentTarget);
});
But for most case, this should be enough:
$('.container').on('click', function(e) {
console.log("clicked on", e.target, " triggered from ", e.currentTarget);
});
Don't use .children().on(...) as this will create a new listener for each child and it's inefficient.
Detecting a click outside a div is quite different and there are many ways to achieve it but none is perfect.
See :
Backbone view with custom event to detect clicks outside of it
How to detect a click outside an element?
Use jQuery to hide a DIV when the user clicks outside of it
Personally, I used focus and blur events (don't forget tabindex="-1" on the element).
Maybe this?:
$(document).on('click','.container *', function(e){
console.log(e.target);
});
The great thing about jQuery is that you can use the same selectors as you would use with CSS hence I used .container * to target all elements inside the container.
I used the jquery .children() method. Check out this code pen.
var flag = 'whatever';
$(.container).children().on('click', function() {
flag = 'updated';
});
Essentially, saying for all children of whatever element is class container (div in this case) add an event handler.
I am working with jQuery dialog. I have one problem that trying to solve that is:
I have created the dialog on click of of anchor class and its working. Than after this I have created one more anchor tag with same class and on click of that new created tag dialog is not working.
Here is html:
<div id="loader_ajax"></div>
<a id="show_hide_window1" class="show_hide_window" href=""> Dialog </a>
<div class="next_tg"></div>
Here is jQuery code:
$(function(){
$(".show_hide_window").click(function(){
showDialog();
});
$('.next_tg').html('<a class="show_hide_window" href=""> Dialog Created By Jquery </a>');
});
function showDialog()
{
$("#loader_ajax").dialog({ modal: true, height: 400,width:650,title: title });
return false;
}
I have already tried with delegation(Event binding) its not working. For Dynamically created anchor it give error in console: TypeError: $(...).dialog is not a function
Please help!! Thanks
You can currently binding click event to elements that are present in the DOM when binding code executes. You need event delegation for dynamically created elements. You also need to add the newly create element to DOM, suppose you want to add to loader_ajax
Here static parent could be any html element, in your case it would be loader_ajax
You code would be
$("#loader_ajax").on("click",".show_hide_window", function(){
showDialog();
});
var newTextBoxDiv = $(document.createElement('div'));
newTextBoxDiv.html('<a class="show_hide_window" href=""> Dialog Created By Jquery </a>');
$("#loader_ajax").append(newTextBoxDiv);
Delegated events
Delegated events have the advantage that they can process events from
descendant elements that are added to the document at a later time. By
picking an element that is guaranteed to be present at the time the
delegated event handler is attached, you can use delegated events to
avoid the need to frequently attach and remove event handlers.
Use on Event. This will manage dynamically added elements.
$(function(){
$('body').on('click', '.show_hide_window', function() {
showDialog();
})
$('.next_tg').html('<a class="show_hide_window" href=""> Dialog Created By Jquery </a>');
});
Fiddle : http://jsfiddle.net/fqt0yztb/
Reference : In jQuery, how to attach events to dynamic html elements?
I have make it from my own code. Now dialog successfully working for dynamically created element.
fiddle
$(document).on('click', '.show_hide_window', function (evt) {
var dialog = $('<div></div>').append('<img src="../images/themeroller.gif"/>');
var getContentUrl = $(this).attr('href');
dialog.load(getContentUrl + ' #content').dialog({
title: $(this).attr('title'),
modal: true,
height: 400,
width:650
});
dialog.dialog('open');
return false;
});