Issues with jquery delegate - javascript

I'd like know how to fire unique Handler triggered by clicked element loaded dynamically in parent div (so delegate) or when is directly loaded.
Firstly, <a class="manage-lnk>Manage</a> Elements are loaded directly, but after, further there are loaded dynamically
html
<div id="viewContainer">
<a class="manage-lnk">Manage</a>
</div>
lib.js.
I have to find this tip for it to work in both cases
$(document).on('click','.manage-lnk',function(){
alert(1);
});
$('.manage-lnk').on('click',function(){
alert(1);
});
what i want is to fire alert(1) although the element is dynamically loaded or not.
(PS:Excuse me for my english i speak french)

Fire this:
$('.manage-lnk').on('click',function(){
alert(1);
});
Each time you dynamically add another one of these:
<div id="viewContainer">
<a class="manage-lnk">Manage</a>
</div>
If it's dynamically loaded after the JS has fired it will not have the event attached.
It would make sense to add it to a function you can call just after the code that dynamically adds in the HTML:
function addNewHtmlSectionFunctionName() {
//Code to add div dynamically
}
function attachClickEventToManageLnk() {
$('.manage-lnk').on('click',function(){
alert(1);
});
}
$(function() {
addNewHtmlSectionFunctionName();
attachClickEventToManageLnk();
});

Related

Running script after div added

Im using a plugin (Event Organiser Pro) that dynamically creates a div based on the input of a number field - basically it creates a duplicates the form fields depending on the number you enter in the input field.
I need to run some jQuery which is based on those form fields, but obviously cant run it until the div has been created.
How can i run the script once the div has been created? Is it possible to run script when div id has been created? Or something similar?
Yes, you can delegate the DOMNodeInserted event to the body.
function createDiv() {
$('<div />').addClass('test').appendTo($('body'));
}
$('body').on('DOMNodeInserted', '.test',function() {
alert('Created element .test');
})
$("button").on('click', function() {
createDiv();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Create</button>
In the example above the click on the button simulates your other script creating the div.
To rewrite the code to work with your setup you can strip the click part out and delegate the event listener to your id:
$('body').on('DOMNodeInserted', '#your_element',function() {
yourFunction();
// call a function here or add your code here directly
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Note: This example won't work here because the element with that ID does not exist and neither does the yourFunction() function.

Issue with jQuery .on() function on DOM created elements

In my web application I use .on() from jQuery to bind click event to a specific li elements in a dynamic multilevel menu created by an AJAX call and passed to the DOM.
$(".dl-menu li:not(:has(li)):not(.dl-back)").on("click", function(){
// My Code...
});
Obviously I put this code behind all the dependencies (jQuery in this case), but I does not work, the code is not being executed.
Only works if I open Firebug and paste the code in it.
I also have tried this:
$(document).ready(function() {
$(".dl-menu li:not(:has(li)):not(.dl-back)").on("click", function(){
// My Code...
});
});
But it does not work too.
What I'm doing wrong?
EDIT: To add more details:
HTML structure:
<div id='tab2' class='col s12'>
<div class='section no-pad-bot' id='index-banner'>
<br><br>
<h2 class='header center green-text'>MENU</h2>
<div id='prodcontainer'>
<div id='dl-menu' class='dl-menuwrapper'></div>
</div>
</div>
</div>
AJAX: (the important parte - the code inside success
$(".dl-menuwrapper").html("<button class='dl-trigger' style='visibility:hidden;'></button>"+json.html.replace('dl-submenu', 'dl-menu dl-menuopen'));
$('#dl-menu').dlmenu();
The json.html contains the string with the HTML to being added to the DOM. Like this:
json.html='<ul class="dl-submenu"><li data-id="17">A<ul class="dl-submenu"><li data-id="18">B<ul class="dl-submenu"><li data-id="20">C</li><li data-id="21">D</li></ul></li><li data-id="19">E</li></ul></li></ul>'
Using .on() this way only binds elements that are currently in the DOM.
Because you load the menu through AJAX, it is not available when this code is executed.
The best workaround is to select a wrapper and specify a selector:
$(".dl-menu").on("click", "li:not(:has(li)):not(.dl-back)", function(){
});
Providing .dl-menu exists in the HTML that you do not create once the document is loaded.
EDIT - Alternative
Place the code setting up the event listener after the menu is loaded.
You should use .on('click'....) on an element that's already present. So you will need to use the code like:
$(document).ready(function() {
$(".dl-menuwrapper").on("click", ".dl-menu li:not(:has(li)):not(.dl-back)", function(){
// My Code...
});
});
Or alternatively,
$(document).on("click", ".dl-menu li:not(:has(li)):not(.dl-back)", function(){
// My Code...
});

Change loaded div from another page with another one on the same page

I have an index.php page that holds and loads all the content so it wont be neccessary to load to other pages and everything happens dynamically. So lets say i have a div in the index.php:
<div id="content"></div>
and i have a full content.php file that holds most of the divs/pages:
<div id="cont1">something :
<div id="innercont1">Dynamic click
</div>
</div>
<div id="changeinnercont1">
<img src="images/pic.jpg" />
</div>
so far so good but the jQuery\Ajax script isnt working in index.php where it should manipulate the divs from content.php. This is the script that loads onclick event the divs in #content from index.php and its working perfectly:
$("#content").fadeOut("slow",function(){
$("#content").load("content.php #cont1");
$("#content").fadeIn();
});
But when it loads this content from the content.php and when i click the link text nothing happens because of the another script in index.php that isnt working properly:
$(function () {
$("#innercont1").click(function (e) {
e.preventDefault();
$("#innercont1").load("content.php #changeinnercont1");
});
});
I think the browser isnt holding the loaded div from another page but only the #content from its own(index.php)
When the ("#innercont1").click event listener is created, there is no element in the DOM with the id innercont1, since that element is dynamically loaded from elsewhere. What you need for this instance is an event listener that will catch any element with that id at any time. You can bind the listener to the body element instead, like so:
$(document.body).on('click', '#innercont1', function(){
//code
});
It could be that your click event listener is being bound before #innercont1 exists. What happens if you load and bind the listener all in one block, e.g.
$("#content").fadeOut("slow",function(){
$("#content").load("content.php #cont1");
$("#innercont1").click(function (e) {
e.preventDefault();
$("#innercont1").load("content.php #changeinnercont1");
});
$("#content").fadeIn();
});

Loading several .php file into one div

Hello i have this code to load php file into div. Its working but i need load next file into this div.
<script type="text/javascript">
$(function() {
$("a.load").on("click", function(load) {
load.preventDefault();
$("#zaw").hide().load(this.href).fadeToggle(1000);
});
});
</script>
<li><a class="load" href="zzz.php">zzz</a></li>
If i click "zzz" link loading file into my div (file table with images) i need hide this page and load next by click image.
UPDATE
Now working
<script type="text/javascript">
$(function() {
$("a.load").on("click", function(load) {
load.preventDefault();
$("#zaw").hide().empty().load(this.href).fadeToggle(1000);
});
});
</script>
You just simply need to bind another click event to an image (or table body) that you load through load() function. However, you may experience some issue with your click not working, and heres why:
If you attach two click handlers, one for a.load and second for, let's say, .image than only the first event will actually get bind to its element, and the socond one won't be attached because, well, .image doesn't exist yet - not untill you load it.
You could expect, that once you php file content will get loaded (with .image elements in it), then clicking them will fire an action you have declared, but it won't - those .image's are new DOM elements and they missed an event binding procedure which was done only once when the DOM was created (or DOM was ready if you use $.(document).ready()).
So, in order to get those clicks to work you need to either attatch them on load() function callback, like so:
$("a.load").on("click", function(load) {
load.preventDefault();
$("#zaw").hide().load(this.href, function(){
$(".image").on("click", function(e) {
$("#zaw").hide().load(/* load what you want */);
});
})
.fadeToggle(1000);
});
or insert .image click event binding inside php file you are loading or use some sort of delegation, for example:
$(document).on('click', '.image', function(){
/* do what you want */
});
which will make sure that even new, dynamically created DOM element will fire an action you want.

Running Master page scripts on imported page lines

I'm importing some php into a div block using a link like this
<a class="ajax-link" href="login.php">Login/Register</a>
and such script (that uses jquery load to fill the div block).
$(function() {
$("a.ajax-link").on("click", function(e) {
e.preventDefault();
$("#body-element").load(this.href);
});
});
Now let's say the loaded php file after running the php portion also contains a link with "ajax-link" class and I want that link too to change the contents of that div block
<?php
...
?>
<a class="ajax-link" href="view.php">View content</a>
But rather than running the above mentioned function on it, it seems to ignore it completely and opens a new page instead.
So basically... how can I run that script on imported parts of the page?
This is where event delegation comes in handy.
$(document.body).on("click", "a.ajax-link", function(e) {
// ...
});
This code needs to be re-run ... dynamically added objects are not included in previous on clicks.
$("a.ajax-link").on("click", function(e) {
e.preventDefault();
$("#body-element").load(this.href);
});
... you could also ... turn off the old watcher.
$("a.ajax-link").off("click");
UPDATE:
Try ...
$("a.ajax-link")
.off("click")
.on("click", function(e) {
e.preventDefault();
$("#body-element").load(this.href);
});
You have to apply the click listener on the newly added link as well, as the element has to be loaded into the DOM when applying the click listener in order for it to be applied. However, if you just re-run the same code you'll like run into the problem of having two event listeners on the first ajax-link.
Try this:
// We still use on doc ready to be sure the
// first link is present before applying listener
$(function()
{
// Reset all listeners on ajax-links and
// then apply listeners via function
resetAjaxLinks();
});
// This function will remove any ajaxlink
// listeners and then apply them correctly
function resetAjaxLinks()
{
// Remove event listeners and then on click....
$("a.ajax-link").off('click').on("click", function(e)
{
// Prevent default link action...
e.preventDefault();
// Load in your content...
$("#body-element").load(this.href);
// Once content is loaded in, reset event listeners!
resetAjaxLinks();
});
}
EDIT: This is not the best method for this. Instead, use event delegation as specified by this answer.

Categories

Resources