jQuery how to achieve new classes and id's - php

I have some tabs in header and use Xajax to load big modules - almost whole page. There are some class inside that I use to call by jQuery (like anchor with some class and then click event...).
But when I load a new module and assign new content (with new classes and id's) jQuery selectors seem don't work - i.e after click anchor nothing is happen.
Quite similar situation appear when you forget $(document).ready(...) using jQuery.
Is there any solution to tell jQuery about new content, new class and id's, that wasn't available when page was loaded?

This is because you're event binding only works for DOM elements that exist when the binding is called. Since your modules are loaded after the binding ($('#sel').click(..)) is called, those DOM elements will not be bound to the event handler.
To work around this, you can use the jQuery .live() method to bind elements that will be loaded later. jQuery will keep track of all the new DOM items being created and will call the binding on the new elements as well.
http://api.jquery.com/live/
LIVE DEMO
<div class="clickme">
Click here
</div>
$('.clickme').click(function(){
alert('click event from normal binding!');
$(this).parent().append('<div class="clickme">Click here - won\'t trigger for normal bind</div>');
})
$('.clickme').live('click', function(){
alert('click event from live binding!');
})

Related

Trouble invoking AJAX to link to internal page in PHP single page app

I've looked at a lot of StackOverflow answers but can't find an answer that is working. This seems like it should be so simple.
I have a PHP single page web app. It has a nav bar that loads pages as includes. Clicking the nav bar invokes a jQuery function to load a different include and inject a class into a div. This works in the nav.
In one of the includes, I have an HTML link:
<div class="page-content">
<a class='btn-primary'>See Examples</a>
</div>
This is the jQuery I want it to execute:
$(".btn-primary").click(function() {
alert('you clicked me');
$('.page').attr('class', 'page examples');
// REPLACE THE CURRENT INCLUDE
$('.page-content').load('includes/page-examples.php');
window.scrollTo(0, 0);
});
But the link does not execute the function. Changing it to a div does not work. Clicking will not even execute the alert.
I've tried to put the link in php echo or php print, but it makes no difference. I've checked all my naming and there isn't a typo.
What is the best way to make it work?
----- EDIT -----
The jQuery is being called from a js file called from the index.php head tag, and is in the DOM ready statement. It looks like the DOM is ready before the include with the link loads. If I remove the link's js from the js file and put it in the include with the link, then the link works, but this will create a problem as other internal links are added to the site in other includes.
What is the best way to fix ?
It sounds like your javascript click binding $(".btn-primary").click(...); is executed on DOM-ready.
But at that time the .btn-primary is not yet in the DOM as it only gets inserted into the DOM after you include it (if I understood it right).
Therefore the binding never happens and after your first include gets loaded the click binding code is never executed again and therefore the .btn-primary element has no onClick event.
You need to run your javascript snippet after that .btn-primary element gets inserted in the DOM, eg. like this:
$('.page-content').load('includes/first-include.php', function(){
$(".btn-primary").click(function() {
whatever...
});
});
First step
Check if you are importing jQuery library (it seems obvious, but we
can forget to import the library sometimes or the library URL is wrong
and the browser cannot recognize it as well). And remember you need import jQuery before the function you wrote.
Second step
If you need to inject a class into some element using jQuery, the easiest way to do this is:
Instead...
$('.page').attr('class', 'page examples');
Change to...
$('.page').addClass('examples');
In this example above, you can omit the 'page' and let only 'examples', because the class ".page" is already there.
Another thing, this will only work if the element with ".page" class already exists in your HTML.
Third step:
Add a callback to .load function and see if it worked properly:
$('.page-content').load('includes/page-examples.php', function(){
alert("Nice, my content was loaded!");
// You can put this action here, so it will execute after the content is loaded
window.scrollTo(0, 0);
});

How to gather a jQuery object into the .on event using parameters rather than being in the global scope?

That was a tricky question to phrase. I will elaborate.
I have an object which is a datatable in this case, but it could be any jQuery object.
I listen for my button click with an .ON click event and call a function called checkbox with a parameter of my object:
var temporaryFilesTable;
$(document).ready(function()
{
temporaryFilesTable = $("#temporaryFilesTable").dataTable();
$("#checkboxButton").on('click', function()
{
checkbox(temporaryFilesTable);
});
});
This works fine and temporaryFilesTable passes as an object to the function checkbox.
The object "temporaryFilesTable" is the reference to the datatable - both are originally called within the document ready of an ajax triggered php / js file.
In another .js file where I store most of my reusable functions I have the function checkbox(checkboxTable).
This function creates a modal that has several buttons on. I want to use these buttons to call functions such as selectFiltered(checkboxTable).
Because the function checkbox(temporaryFilesTable) brings in the table object I need to reuse the object to trigger the next function. I am used to passing variables as parameters into functions using onclick="function(parameter)", or in this case with the modal I would have to use:
function checkbox(checkboxTable)
{
...
var content = '<a href="#" onclick="selectFiltered('+checkboxTable+') class="button>'
...
<!-- Trigger modal -->
}
This actually doesn't seem to work anyway so my syntax is probably wrong but that is not really the point. I am reluctant to use onclick as I am currently correcting my code to use jQuery .ON click instead.
Without declaring temporaryFilesTable as a global object can I somehow get this jQuery object into an .ON click listener?
If not, I suppose I could consider declaring the datatable object as a global that can be accessed across multiple .js files, rather than passing it around functions so much? The problem is this means I would have write my functions to trigger jQuery on each datatable object, even those that might not be in the DOM at the time. I guess that's not ideal.
** Additional info **
The code to check the checkboxes in the way I wanted worked fine before I started passing the table as a parameter. I wanted to do this because I have multiple pages, with different tables, where I would like to use the same checkbox ticking modal and functions. I can post the original code if it helps but I didn't want to confuse the question.
To clarify I realise I do declare my temporaryFilesTable putting it into global scope in my first section of code but I don't think this passes between the .js files. This is just to allow me to use it outside of document ready.
Thanks for reading.
I would suggest trying to attach the on click event after the html is append to the dom. The object doesn't play nice when passed into a string through a function. So I would try something like this:
$("#appedTo").append(content);
//Then select the a, and attach the on click event
$([selector to get the link]).on("click", function(){
selectFiltered(checkboxTable);
});

Unable to understand <A HREF> tag and javascript call

I have a php application in which the web page displayed to the user. The page has some links "Edit", "Rename", etc.
When the user clicks on the link a dialogbox prompts. The dialogbox is nothing but a HTML <div> form that gets instantly displayed when the user clicks on the "Rename" or "Edit" link.
When I looked at the html source code (i.e. view -> source in Internet Explorer) I found the following Javascript and HTML code
<a class="update renameButton" href="javascript:void(0);">Rename</a>
I'm unable to understand how the dialogbox gets promted with the above code.
I expected the code to be something like the following:
<a class="update" onclick='rename();' href="javascript:void(0);">Rename</a>
Can someone help me understand this?
Some JavaScript loaded from a <script> element probably binds an event handler function to the element.
The event handler is most likely bound to the element elsewhere (from an included JavaScript file perhaps). For example:
document.getElementsByClassName("update")[0].addEventListener("click", function () {
// Do something on click of the first `.update` element
}, false);
you should not setup event listeners in html anymore like with onclick.
the page registers an event listener to the Object. e.g. with a library like jQuery.
You are absolutely correct! That is very natural to expect such a thing except that there are other ways to bind an event to an object as well.
If you check the JavaScript code on the page I am sure you will find perhaps something that looks like $('a.renameButton').click(function(){}); (if the site is using jQuery) or something similar that binds the onclick event of that particular tag to perform some specific actions.

Facebook like button not displaying after refreshing a div by using load();

I'm using a simple script to reload a div
$('#mydiv').fadeOut('300').load('# #mydiv').fadeIn("300");
The problem is that the div I'm reloading has the Facebook like button inside it. After the DIV reloads, I can see it updated inside the source, but the button is hidden for some reason.
Is there any way to force the button to re-draw?
As I stated in my comment, I think the .load is misunderstood, as you stated in your question
I can see it updated inside the source, but the button is hidden for some reason
.. so with that in mind, I assume you have load functioning with the correct parameters.
You have a synchronistic problem here. Everything you use in the chain uses a timescale, and .load() for that matter is asynchronous.
So instead of just chaining everything, you have to use the callbacks in order to know when the time scale ends for a particular function.
$('#myDiv').fadeIn('300', function() {
// callback when #myDiv is faded out (display:none;)
$(this).load('url', function() {
// callback when #myDiv is loaded with new content from the given 'url'
$(this).fadeIn('300');
})
});
The facebook button won't display because it is configured normally just AFTER document.load.
If you load the div content while the document is already loaded and the Facebook javascript SDK has already initialized. It won't work.
If facebook is not required UNTIL the div loads. You may just try to load the "all.js" script inside the div.
Otherwise, if you've come to that, you'll certainly have to review the application's design.

Cannot control content added dynamically with .load

I have content that I'm loading using an AJAX call and displaying the HTML (consisting of divs, etc) inside of a ul parent.
Now I've written a series of .click and .hover functions that work perfectly on everything, right up to where my content is dynamically loaded, and then don't work at all on the dynamically-loaded content.
I've gone through all my div ids to make sure they are correct and they are. Is there a way to gain control over the AJAX-loaded material?
The problem is that your code run only with the elements that existed at that time and no the "future" elements. You have 2 choices:
1) Re-run your "onload" javascript code (that was applied on document ready) after you load your ajax content.
2) Use .live() instead of .bind():
So change
$('#selector').bind('click', function(){..
To
$('#selector').live('click',function(){..
The difference is that live uses the elements that match the selector now and in the future, versus bind uses the elements that match the selector only at the time it's called.
Hope this helps. Cheers
Your event handlers are bound to elements that exist at the time that they are set.
Either re-attach the handlers to the new, dynamically-created material, or make use of live or delegate; these "attach a handler to the event for all elements which match the current selector, now and in the future".
You should either rebind the events after the content is loaded or use
.delegate (api) to have the event attached automatically to newly loaded elements.
something like:
$("ul#container").delegate("li", "hover", function(){
doStuff();
});
$("ul#container").delegate("li", "click", function(){
doOtherStuff();
});
Change
$('a#whatever').click(function(){....
To
$('a#whatever').live('click',function(){....

Categories