Fancybox on click with element binding in Yii CGridView with ajax Pagination - javascript

I am using Yii CGridView with ajax Pagination and one of the column is Link for image or inline ajax content and i want to use FancyBox to the column.
When i use pagination i lose the binding on the new element.
if i try to make it on element click i always get error if the element has fancy-box already like below
$('a.fancy-img').live('click', function () {
$(this).fancybox({});
return false;
});
But I always get javascript error if i click twice on the same link.

The problem you are trying to initialize fancybox for the element twice so your javascript breaks and doesn't work.
You can add class or some attribute to the element that has already has Fancybox init so you don't initialized it again for the same element and your javascript beaks as below :
$('a.fancy-img').live('click', function () {
var El = $(this);
$(this).fancybox({});
if (!El.hasClass('fancy-box-init')) {
El.addClass('fancy-box-init');
El.trigger('click');
}
return false;
});

Try
fancybox uses $(element).data() to store its element related configuration.
So check if(!$(this).data().fancybox) --> if there is no data that means no fancybox is registered to it than register fancybox
$('a.fancy-img').live('click', function () {
if(!$(this).data().fancybox){ //or if(!$(this).data("fancybox"))
$(this).fancybox({});
}
return false;
});
.live() is deperciated use .on()
Syntax
$( elements ).on( events, selector, data, handler );

Related

jQuery removeClass on iFrame button click

I wrote some code to addClass to elements to open an iFrame imported by Shopify on WordPress and it works.
But now, I want to close the iFrame by removing the class on my website element.
I've tried a lot of things but it dosen't work
Here is my code :
jQuery(document).ready(function( $ ) {
$(document).ready(function() {
$('.cart-button').click(function() {
$('.shopify-buy-cart-wrapper').addClass('is-active is-visible');
$('.shopify-buy-cart-wrapper iframe').addClass('is-block');
return false;
});
//$("iframe").contents().find("button .shopify-buy__btn--close").click(function(){
$('.shopify-buy__btn--close').click(function() {
$('.shopify-buy-cart-wrapper').removeClass('is-active is-visible');
$('.shopify-buy-cart-wrapper iframe').removeClass('is-block');
});
});
});
Open cart is working, but now I want to close the cart
If you want to remove multiple classes with jQuery removeClass() you have to pass them as an array, not as a string.
Also, any event listener should be attached only after the element has been inserted in the DOM. If you define the event listener but the element is created afterwards, it won't work.

javascript events not working with dynamic content added with json

I'm stuck with a situation where my DOM elements are generated dynamically based on $.getJSON and Javascript functions for this elements are not working. I'll post some general idea on my code because I'm looking just an direction of what should I do in this situation.
site.js contains general features like
$(document).ready(function() {
$('.element').on('click', function() {
$(this).toggleClass('active');
});
$(".slider").slider({
// some slider UI code...
});
});
After that:
$.getJSON('json/questions.json', function (data) {
// generating some DOM elements...
});
I have also tried to wrap all site.js content into function refresh_scripts() and call it after $.getJSON() but nothing seems to be working.
Firstly you need to use a delegated event handler to catch events on dynamically appended elements. Then you can call the .slider() method again within the success handler function to instantiate the plugin on the newly appended content. Try this:
$(document).ready(function(){
$('#parentElement').on('click', '.element', function() {
$(this).toggleClass('active');
});
var sliderOptions = { /* slider options here */ };
$(".slider").slider(sliderOptions);
$.getJSON('json/questions.json', function(data) {
// generating some DOM elements...
$('#parentElement .slider').slider(sliderOptions);
});
});
Instead of calling on directly on the element, call it on a parent that isn't dynamically added and then use the optional selector parameter to narrow it to the element.
$('.parent').on('click', '.element', () => {
// do something
});
The difference between this and:
$('.element').on('click', () => {});
is with $('.element').on(), you're only applying the listener to the elements that are currently in that set. If it's added after, it won't be there.
Applying it to $(.parent), that parent is always there, and will then filter it to all of it's children, regardless when they're added.
the easiest way is to add this after you add/generate your DOM
$('script[src="site.js"]').remove();
$('head').append('<script src="site.js"></script>');
of course your js function that generates DOM needs to be on another file than your site.js

How can I show a DIV by it's attribute value using Jquery

I am working with a Jquery plugin and I would like to trigger the modal (div) by calling it's value instead of calling it's ID name.
So if the attribute value is "554" meaning attrId="554" I will display the modal with the matching "554" attribute. Please keep in mind that the attribute value could be a variable.
My JSFiddle Code Example is here
;(function($) {
// DOM Ready
$(function() {
// Binding a click event
// From jQuery v.1.7.0 use .on() instead of .bind()
$('#my-button').bind('click', function(e) {
// Prevents the default action to be triggered.
e.preventDefault();
// Triggering bPopup when click event is fired
$('#element_to_pop_up').bPopup();
});
});
})(jQuery);
Any help is appreciated. Thanks so much
You can use an attribute equals selector: [attribute="value"]
If your popup div has an attribute like this:
<div id="element_to_pop_up" attrId="554">
<a class="b-close">x</a>
Content of popup
</div>
You can use the following:
var x = '554';
$('div[attrId="' + x + '"]').bPopup();
jsfiddle
Ultimately it needs a unique selector unless you are okay with triggering multiple modals. One way to do it is to use the jQuery each function, and check each div for the matching attribute.
$( "div" ).each(function() {
var criteria = 'example_criteria';
if ($( this ).attr( "attributename" ) == criteria)
{
$(this).bPopup();
}
});

bootstrap typeahead selector for dynamic page loading

When I load a page normally and use this code :
$('#clientName').typeahead({
//removed options since they are not needed for my question
});
The typeahead works fine on #clientName.
But when I load the input #clientName dynamically via AJAX then the above code doesn't work.
Is there some way to let it work?
It's equal to this problem :
$('#randomDiv').click(function() {
alert("Handler for .click() called.");
});
This one only works if the content is not dynamically loaded. But this code will work :
$(document).on('click','#randomDiv',function() {
alert("Handler for .click() called.");
});
So I would like to add the handler to the document or body, and not to the #clientName div itself.
I think you only have the choice to call $('#clientName').typeahead(...); again after inserting the input with the id clientName dynamically. If you capsules calling typehead into a function, you need only to call the function again without setting all options again.

How can I call a Jquery method on DOM elements that don't exist yet?

I'd like to use this lightbox plugin for some autocomplete links, that don't yet exist on my page.
You normally activate it using:
$(document).ready(function($) {
$('a[rel*=facebox]').facebox()
})
Since the a links aren't all on the page upon page load, I would normally look to the .live or .delegate methods to bind to an event, but in this case, what 'event' would I bind to to say "once this element is on the page, then call this method on it".
Or am I going about this totally the wrong way?
There is no such event.
You need to invoke the plugin when you add the elements to the page.
// create a new <a>, append it, and call the plugin against it.
$('<a>',{rel:"facebox"}).appendTo('body').facebox();
This example creates a new <a> element. If you're getting some elements from an AJAX response, call it against those:
var elems = $( response );
elems.filter( 'a[rel="facebox"]' ).facebox(); // if the <a> is at the top level
elems.find( 'a[rel="facebox"]' ).facebox(); // if the <a> is nested
elems.appendTo('body');
Not yet tested :
$(document).ready(function($) {
$(document).bind('change', docChanged) ;
})
function docChanged()
{
if ($('a[rel*=facebox][class!="faceboxed"]').length > 0)
{
$('a[rel*=facebox][class!="faceboxed"]').addClass("faceboxed").facebox();
}
}
This is entirely possible using the .live function. You just need to use the DOMNodeInserted event.
$(document).ready(function() {
$("a[rel*=facebox]").live("DOMNodeInserted", function() {
$(this).facebox();
});
});
You'll need to just add this call to the ajax that loads in the links.

Categories

Resources