How to use Lightbox on AJAX loaded content - javascript

I am using Boostrap 5 and this Lightbox library https://trvswgnr.github.io/bs5-lightbox/
It works fine on pages loaded normally but it will not load on AJAX loaded content.
I have tried this code to make it work with AJAX but it did not work.
$(document).on('click', '[data-toggle="lightbox"]', function(event) {
event.preventDefault();
$(this).Lightbox();
});
It returned this error:
Uncaught TypeError: $(...).Lightbox is not a function

If you're using the vanilla JS version, the script only adds event handlers to elements with the data-toggle="lightbox" attribute that are present when the script loads, hence new elements loaded via AJAX calls not working.
If you're able to use Node (or hack around not using node with a module loader like RequireJS), you can instantiate a new Lightbox when each new element loads, per the docs:
$(document).on('click', '[data-toggle="foo"]', function (event) {
event.preventDefault();
const el = $(this);
const lightbox = new Lightbox(el);
lightbox.show();
});
Note that the correct syntax here is to create a new lightbox from the element and then use lightbox.show()... $(this).Lightbox() will never work.

Related

Ajax loaded part of a page - how do I make links in the loaded content work?

I load a part of my basketpage inside an accordion div in my header. This works great and shows my basket in a nice dropdown.
The last problem I need to solve with this is to get the buttons in the loaded content to work. Is it possible to write an callback that make these works? Im not sure even what to google for this one..
This is how the buttons is setup in the loaded content:
checkout
Script Im using to load the content:
$('.dcjqg-accordion ul.sub-menu').load('/m4n?seid=etailer-basket div#centerbox.itembox.centerbox');
use the callback function of .load().
$('.dcjqg-accordion ul.sub-menu').load('/m4n?seid=etailer-basket div#centerbox.itembox.centerbox', function() {
$("#_ec_oie2").on("click", function() {
if (UI.pb_boolean(this, 'click')) { }
return false;
});
});
checkout
You need to use a child selector for the event. You can attach an event to the .sub-menu element that will fire on the content loaded in through the ajax. Something like the following could work:
$(".dcjqg-accordion ul.sub-menu").on("click", ".action.actionbasket.checkout", function() {
if( UI.pb_boolean(this, 'click') ) {}
return false;
});
Notice the second parameter to the on method. It is a selector that will be used to look at the target of the click event. I used .action.actionbasket.checkout since that is what is on your a tag.
This code may not work exactly, but this should help get you in the right direction.
Here is the link to the jQuery documentation for the on method: https://api.jquery.com/on/

jQuery slideshow plugin with .load()

I'm trying to make an auto slideshow with pics from other .php file and to achieve that i've decided i will use http://responsiveslides.com/ jQuery plugin. The problem is that this plugin doesn't want to work with my photos by "loading" them from other file.
$('.first-option').click(function(){
$('.inner-box').load('file.php .rslides');
});
$(function() {
$("file.php .rslides").responsiveSlides();
});
*CSS/HTML are exactly the same way written like the author wrote in his "Usage".
try this:
$('.first-option').click(function(){
$('.inner-box').load('file.php .rslides', function callback () {
$('.rslides').responsiveSlides();
});
});
I've not used the plugin before, but it appears that you need to apply the bootstrap method to the element that contains the slides you load into your page. So what you're doing in your code is attaching the load method to the click handler, while attaching the responsive slides to an empty selector when the DOM is ready. What I've provided above loads the content, and then using a callback function (when the content has successfully been loaded into the DOM), then calls the bootstrap method onto the original selector.
Edited the code to use the '.rslides' selector.

Why does DOM appendChild() fire on('load', ...) but jQuery append() does not?

I have the following to snippets of code:
$(document).ready(function() {
document.head.appendChild(
$('<script />').attr('src', 'source.js').on('load', function() {
...
})[0]
);
});
This will fire the load handler.
Whereas using the normal jQuery append():
$(document).ready(function() {
$('head').append(
$('<script />').attr('src', 'source.js').on('load', function() {
...
})
);
});
This will not fire the load hander.
What am I missing: why does jQuery append() not work?
Is using document.head.appendChild() a bad idea?
NOTE: I can't use $.getScript(). The code will run on a local file system and chrome throws cross site script errors.
Update
Some people had trouble reading the compact style, so I used extra line feeds to clarify which objects where calling which methods. I also made it explicit that my code is inside a $(document).ready block.
Solution
In the end I went with:
$(document).ready(function() {
$('head')[0].appendChild(
$('<script />').attr('src', 'source.js').on('load', function() {
…
})[0]
);
});
I think #istos was right in that something in domManip is breaking load.
jQuery is doing some funny business in its DOM manipulation code. If you look at jQuery's source, you'll see that it uses a method called domManip() inside the append() method.
This domManip() method creates a document fragment (it looks like the node is first appended to a "safe" fragment) and has a lot of checks and conditions regarding scripts. I'm not sure why it uses a document fragment or why all the checks about scripts exist but using the native appendChild() instead of jQuery's append() method fires the event successfully. Here is the code:
Live JSBin: http://jsbin.com/qubuyariba/1/edit
var url = 'http://d3js.org/d3.v3.min.js';
var s = document.createElement('script');
s.src = url;
s.async = true;
$(s).on('load', function(e) {
console.log(!!window.d3); // d3 exists
$(document.body).append('<h1>Load fired!</h1>');
});
$('head').get(0).appendChild(s);
Update:
appendChild() is a well supported method and there is absolutely no reason not to use it in this case.
Maybe the problem is when you choose DOM appendChild, actually you called the function is document.on('load',function(){});, however when you choose jQuery append(), your code is $('head').on('load', function(){}).
The document and head are different.
You can type the code below:
$(document).find('head').append($('<script />').attr('src', 'source.js').end().on('load', function() {
...
}));
You should probably make sure that the jquery append is fired when the document is ready. It could be that head is not actually in the dom when the append fires.
you don't have to ditch jquery completely, you could use zeptojs. Secondly, I couldn't find out how and why exactly this behavior is happening. Even though i felt answer was to be found in links below. So far i can tell that if you insert element before definig src element then load won't fire.
But for manual insertion it doesn't matter. (????)
However, what i was able to discover is that if you use appendTo it works.
Code :http://jsfiddle.net/techsin/tngxnkk7/
var $ele = $('<script />').attr('src', link).load(function(){ abc(); }) ).appendTo('head');
New Info: As is understood adding script tag to dom with src attribute on it, initiates the download process of script mentioned in src. Manual insertion causes page to load external script, using append or appendTo causes jquery to initiate downloading of external js file. But event is attached using jquery and jquery initiates download then event won't fire. But if it's the page itself initiates the download then it does. Even if event is added manually, without jquery, adding via jquery to dom won't make it fire.
Links in which i think should be the answer...
Append Vs AppendChild JQuery
http://www.blog.highub.com/javascript/decoding-jquery-dommanip-dom-manipulation/
http://www.blog.highub.com/javascript/decoding-jquery-dommanip-dom-manipulation/
https://github.com/jquery/jquery/blob/master/src/manipulation.js#L477-523
http://ejohn.org/blog/dom-documentfragments/

How to execute a function in javascript after an html element is loaded via AJAX without jQuery?

I need to execute a given javascript function after a part of the page is loaded via AJAX. I have no control over how the page loads so trigerring an event from the page is not an option, I suppose I'll need to check the body for the element I need and execute after this element is exists.
I saw that I could do this using jQuery ".on" method, but my jQuery version is from before this feature was introduced so I can't use it. What's the best way to do this using no third-party libraries?
Here's an example using jQuery:
//bind to the body a "load" handler for elements that have class names of "hello"
$('body').on('load','.hello',function(){
alert("Hello is fully loaded, proceed with your program logic");
})
PS: related question that I've read before posting this one. How to bind a function to Element loaded via Ajax
You can create a function to call when the elements are loaded, and another function to check if they are loaded at an interval. Then attach the load checking function to the body's onload attribute. For example:
<body onload="checkLoaded()">
<script type="text/javascript">
var afterLoaded = function() {
// code to execute once elements are in place
console.log("Elements loaded.");
};
var checkLoaded = function() {
var interval = setInterval(function() {
if(document.getElementsByClassName("hello").length) {
clearInterval(interval);
afterLoaded();
}
}, 1000);
};
</script>
Plunker

Ajax links inside ajax loaded content

i am having trouble getting ajax loaded links to load other ajax content.
Basically this is my ajax code:
$(function () {
var api = $("#content").jScrollPane().data('jsp');
var reinitialiseScrollPane = function()
{
api.reinitialise();
}
// attaching click handler to links
$("#contentcontainer a[href]").click(function (e) {
// cancel the default behaviour
e.preventDefault();
// get the address of the link
var href = $(this).attr('href');
// getting the desired element for working with it later
var $wrap = $('#content');
$wrap
// removing old data
api.getContentPane()
// load the remote page
.load(href, reinitialiseScrollPane , function (){
}
);
});
});
Basically the links inside the navigation work fine since they are loaded when page is loaded, but links inside the ajax content (wich are supposed to load pages in the same place the navigation links load content) dont work, my understanding is that there needs some sort of ".live" function called as the js does not rescan the code once ajax loads content.
I found some solutions but none i could relate to the code im using.
The first part of the code is not ajax but for a scrollbar plugin, i did not remove it because id like to avoid it getting voided by a solution that dosent keep it into count.
Thanks.
Try using the .on() method (see jQuery documentation) when attaching the click handler:
$(document).on('click', '#contentcontainer a[href]', function (e) {
// Rest of your code here
});

Categories