How to trigger unobtrusive javascript when the content is dynamic with ajax (Lightbox) - ajax

I've got some links coming in from ajax that need lightbox functionality:
<img src='...'>
Normally this is given behavior via an on page load handler, but since the content is coming from ajax, the UJS isn't getting triggered.
Any way to do this?

If the content is coming from AJAX, then din't setup the event handling during page load. Instead, let the event bubble to the topmost container that is not being changed or replaced by AJAX. Worst case, use document as the topmost node.
$('<root element selector>').on('click', 'a.lightbox', function() {
// activate lightbox on the clicked element.
});

I'm not sure how you're triggering the ajax requests, but if it's with jQuery which seems likely, you can bind the lightbox in the success callback:
$.ajax({
url: '/route',
success: function (response, status) {
$('.lightbox').lightbox();
}
});
You can pass in a context to the jQuery selector so you don't re-attached the lightbox to links that are already in the page, for example if your ajax call is adding the links to a div with id 'lightbox_links', use this selector instead:
$('.lightbox', '#lightbox_links').lightbox();

Related

jQuery Mobile: javascript breaks when after loading a page from ajax

So I've decided to use the jQuery Mobile framework to build my new mobile website. It has this feature of loading any local href link by ajax, which is great. But the new page that loads doesn't respond to any of the javascript. I've got a home page and page 2, both of which have the same html layout which a few changes in the content, I'll give an example.
I have made a navigation menu that slides in from the left and pushes the main content to the right. When I click on a page link, it loads the new page through ajax, but then on the new page, if I click the menu button, jQuery doesn't pick this up and so nothing happens (the menu doesnt slide out).
$(document).ready(function() {
$( ".menu-trigger" ).click(function() {
console.log("1")
if ($( 'nav' ).hasClass('navTransform')) {
console.log("2")
$( 'nav' ).removeClass('navTransform');
$( 'article' ).removeClass('articleTransform');
}
else {
console.log("3")
$( 'nav' ).addClass('navTransform');
$( 'article' ).addClass('articleTransform');
}
});
});
This jQuery script is in a seperate .js file thats included in the header of both the pages. I know the script works normally because when i refresh the page, the menu trigger works. Is there a known work around for this?
The workaround for this is to use appropriate jQM handler pageinit() instead of jQuery ready handler.
pageinit = DOM ready
One of the first things people learn in jQuery is to use the
$(document).ready() function for executing DOM-specific code as soon
as the DOM is ready (which often occurs long before the onload event).
However, in jQuery Mobile site and apps, pages are requested and
injected into the same DOM as the user navigates, so the DOM ready
event is not as useful, as it only executes for the first page. To
execute code whenever a new page is loaded and created in jQuery
Mobile, you can bind to the pageinit event.
So, your code might look like this:
$(document).on("pageinit", "#page1", function(){
//Your init code for page 1 goes here
});
$(document).on("pageinit", "#page2", function(){
//Your init code for page 2 goes here
});

How to get the raw markup from a jquery mobile pageload request?

How can you get the raw HTML markup from an AJAX request that loads a page in jquery mobile?
My page has a menu outside of the page container element (data-role="page") and I need to update it on each page load but jquery-mobile only gives me the page markup from the request not the entire document.
I've even tried using the global ajaxSuccess callback for jquery; apparently jquery-mobile feels the need to filter this to just the page element also.
Can't you just assign an id to the menu page and access it directly?
$('#myMenu').html(newContent);
Found the http request object in the pageload event.
$(document).bind("pageload", function (e, data) {
console.log(data.xhr.responseText);
});

Optimal way to use Ajax

i have a web page that once it loads, it sends a lot of Ajax calls to fill some parts of the page. It's a Django template, it's sending around six calls with code similar to this :
$.get("http://127.0.0.1:8000/purchase/?name="+me.username, function(data){
$("#purchase").append(data);
});
sometimes they are called when the user clicks on a button, but they are mostly called when the page is refreshed.
Im new to Ajax, and I want to know if it's the right way to use this technology in an optimal manner. Is it alright to send Ajax calls similar calls that are separate ?
Thanks
For now i think just put those $.get() scripts into a jQuery ready function if you want them to fire when page loads and not on refresh... And yes its normal for a page to behave like this. That's what AJAX is meant for.
$(document).ready(function(){
$.get("http://127.0.0.1:8000/purchase/?name="+me.username, function(data){
$("#purchase").append(data);
});
//other $.get 's
});
Also use the jQuery ready() documentation.

Using jQuery Plugins with live()

I have a page that dynamically loads content with the jQuery load() function, so I need to use live() for each of my jQuery functions on this page. However, I am unable to get live() to work with jQuery plugins. For example, I want to use jQuery accordion:
$("#accordion").accordion();
But I cannot find the right syntax to get accordion to work with live(). I have tried:
$("#accordion").live("load", accordion());
$("#accordion").live("load", $("#accordion").accordion());
$("#accordion").live("load", $(this).accordion());
I either receive the "b is undefined" error, or "accordion is not defined."
You must use anonymous function
$("#accordion").live('load',function(){
$(this).accordion();
});
Edit:
If the accordion is already in the page when you first render it, then you shouldn't call it using live(), but by page load
$(function(){
$("#accordion").accordion();
});
This could partly answer your question:
I would suggest using livequery instead to do this:
$("#accordion").livequery(
function() { $(this).accordion(); },
function() { $(this).accordion("destroy"); }
);
The first function will initialize jQuery UI's accordion functionality on any $("#accordion") element that's added to the DOM, and the second one will destroy the accordion object when that same element is removed from the DOM.

jQuery: Firing an AJAX event local to the element that is loading data

I've been playing around with subscribing elements to AJAX events in jQuery.
I have an element that I am using to load AJAX response's. This element is only displayed IF there is data pertinent to the current context of the program.
So, I thought it would be nice and easy to .show() whenever an AJAX request has completed on it and hide it when I need to. I would like to remove the need to implicitly .show() the element every time I make an AJAX request.
In jQuery there is .ajaxSuccess() and .ajaxComplete(). These however, will fire when any AJAX request completes/succeeds, so when loading data in other parts of the page, my hidden element will .show().
The solution seems to be (per. the jQuery API reference) to use the ajaxOptions parameter in your event handler function:
$('.log').ajaxComplete(function(e, xhr, settings) {
if (settings.url == 'ajax/test.html') {
$(this).text('Triggered ajaxComplete handler.');
}
});
What I don't understand is the reason for registering an event handler for all AJAX requests to a specific element, besides being able to use $(this). Am I missing something, can I register an event handler for an AJAX request specific to an element?
If not, is there any event driven alternative to using the .url? The reason I ask is that I use the page fragment extensively for tracking page state and it would be easier to have an event handler .show() my element whenever an AJAX request loads data into it.
EDIT: Post title grammar.
My thinking, is that you want something like this:
$(document).ajaxComplete(function(e, xhr, settings) {
if(settings.url == 'ajax/test.html') {
$('#foo').text('Triggered ajaxComplete handler.');
} else if(settings.url == 'ajax/another.html') {
$('#bar').text('Triggered ajaxComplete handler.');
}
});
Does that make sense, or am I completely missing the point?
Bind a global event handler to AJAX requests and then use the event target member to decide to show elements:
$(document).ajaxSuccess(function (event, xhr, settings) {
if ($(event.target).is('#main'))
$('#main').show();
});
Would be nice to be able to fire on AJAX requests that only target specific elements, but there doesn't seem to be a way.
EDIT: Syntax

Resources