I was wondering if someone can help guide me how I can write a event when I'm using toggleClass in jQuery?
I have a list of items and when I click on an item, it highlights it, and when someone clicks another item from the list, the previous highlighted item goes away and highlights the current click. Also, if I click the same item that has been highlighted, it goes away.
Now I'm trying to write a function to call ajax when only its been highlighted. So it won't run the ajax function again when its being pressed again (when highlight is removed).
$(".media").on('click',function(){
var $this = $(this);
// highlighting the object
$this.toggleClass('selectMedia').siblings().removeClass('selectMedia');
// saving the id
var selId1 = $this.data('id');
$.post("ajax/ajax_sessions.php", {"sel_1":selId1}, function(data) {
alert(data); // alerts 'Updated'
});
});
Thank you for help!
Just check for the existance of the class before doing your AJAX request:
if ( ! $this.hasClass('selectMedia') ) return;
// Now do your AJAX request...
Related
I am using Shopify "Streamline Theme" with quick product view and I recently added infinite scroll to products on each collection using Ajaxinate.js.
When I open a collection page it loads with some products which is supposed to do, The products already there work fine with quick view and quick add to cart and also.
The Infinite scroll works fine and it loads new product fine but the problem is raised when the new products loaded through AJAX call doesn't have work with the quick view function.
I have tried to create a callback function to activate the quick view with no success, using the theme initialisation code with no success.
function callBack(){
theme.init();
theme.initQuickShop();
};
document.addEventListener("DOMContentLoaded", function() {
var endlessClick = new Ajaxinate({
method: "scroll",
loadingText: 'Loading...',
callback: callBack
});
});
Edit -------
My problem, is that when the page is loaded only the initial loaded products quickview elements are loaded in the DOM. When the scroll more button is clicked, the newly loaded products are loaded without their respective quickview elements. Hence why the quickview does't work for them. The theme.js file comes with this initialisation code:
theme.reinitProductGridItem = function($scope) {
if (AOS) {
AOS.refreshHard();
}
if (theme.settings.currenciesEnabled) {
theme.currencySwitcher.ajaxrefresh();
}
// Reload quick shop buttons
theme.initQuickShop(true);
// Refresh reviews app
if (window.SPR) {
SPR.initDomEls();SPR.loadBadges();
}
// Re-register product templates in quick view modals.
// Will not double-register.
sections.register('product-template', theme.Product, $scope);
// Re-hook up collapsible box triggers
theme.collapsibles.init();
};
I have tried to integrate this into a callback but no success, the quickview modal doesn't seem to load for the newly loaded products:
function callBack(){
ReloadSmartWishlist();
var $container = $('#CollectionSection');
theme.reinitProductGridItem($container);
// I have tried the following init qith no success:
// theme.init();
// theme.initQuickShop(true);
// theme.initQuickShop();
// sections.register('product-template', theme.Product, $container);
// AOS.refreshHard();
};
document.addEventListener("DOMContentLoaded", function() {
var endlessClick = new Ajaxinate({
method: "click",
loadingText: 'Loading...',
offset: 0,
callback: callBack
});
});
I am missing something but what? :/
Note for other things like loading products images with the callback and the wishlist app, it works as intended...
When you load elements via AJAX and if the events are not attached to a parent element that is not removed from the DOM, those elements will not have an attached event to them.
The term used here is event delegation.
Here is an example of non-delegated event:
document.querySelectorAll('a').addEventListener('click', function(){
// Do something
})
Since you are attaching the event to the existing "a" elements if you add new 'a' via AJAX those elements will not have the event since Javascript already attached all the events and it will not reattach them if you don't specifically recall them again.
Here is an example of a delegated event:
document.querySelector('body').addEventListener('click', function(target){
let target = event.target;
if (target.tagName === 'A'){
// Do something here
}
})
Where we attach the event to the body tag ( where it's a better idea to attach it to a closer none-modified parent element of the ajax items ) and once we click we check if our target tag is an "a" and do something then.
So long story short, you will need to delegate the quick cart link so that it works after you load the items via AJAX.
Drip is correct you need to delegate your event, but for people like me it's hard to completely understand how to do that.
I'm not sure how your quickview is structured, but if you open it with a .click function and can use jquery use the [.on() function][1].
For example: I use a quickview that opens on a button click. My button is attached to my product-grid-item.liquid with this bit of code:
<div class="quick-view-button">
<a class="quick-view" data-handle="{{ product.handle }}" href="javascript:void(0);">Quick View</a>
</div>
My quickview function originally looked like this:
function quickView() {
$(".quick-view").click(function () {
//all of the quickview code
What happens is exactly like you described. The event listeners only loaded on the first product load but nothing after an AJAX load.
Using jquery's .on() binds the event listener to the element meaning when it's loaded in later it'll still have the event. Here's an example of what my code looks like after using .on()
function quickView() {
$('body').on('click','.quick-view',function(){
I really hope this helps you or someone else with this problem.
[1]: http://api.jquery.com/on/
I am trying to get jQuery to send a mousedown event to the Drupal 7 "add another item" button for a multi-value field, then wait until the ajax call has completed before filling in that new blank row with data from an element in a jQuery object (that has several elements). I need to use a loop to cycle through the elements (ingredients) in this jQuery object, but no matter what I try my page dies...
Currently, I have something like the following:
i = 0;
ingredients = newHtml.find('.recipe_ingredients > li');
ingredientsLength = ingredients.length;
$('#edit-field-ingredients-und-add-more').mousedown();
while(i < ingredientsLength) {
if ( document.readyState !== 'complete' ) {
// code to fill in the new blank row with data from 'ingredients'
$('#edit-field-ingredients-und-add-more').mousedown();
i++;
}
}
Because I don't yet know how to issue the ajax call myself using jQuery (or using Drupal) I've been trying to just check whether the call has completed by using .readyState and other hack-like methods. I'm just not sure what to try next!
Am I going about this the completely wrong way? Is there a straightforward way to make the "add another item" multi-value field ajax call using jQuery? Any help would be greatly appreciated...
I am not sure if there's a nicer way in Drupal 7, but in Drupal 6 you could use jQuery(document).ajaxComplete with the settings.url property to tell when a specific "Add another item" click had finished.
Start with:
(function($) {
$(document).ajaxComplete(function(e, xhr, settings)
{
alert(settings.url);
});
}(jQuery));
Once you've identified the right settings.url for your field, change that to:
(function($) {
$(document).ajaxComplete(function(e, xhr, settings)
{
if (settings.url == "the path from step 1") {
// Code to populate your fields here
}
});
}(jQuery));
And voila!
You might want to read the page by Jay Matwichuk where I originally learned this technique awhile back. All credit to him (and nclavaud for his comment there), really.
I have a website that pages' contents loaded by ajax. All of my pages are seperate files actually and when I need to call a page, I just passed the link to my "pageLoader" function.
pageLoader handle with content loading and re-ignite/re-define the necessary functions like close button.
Since the actual function have ~250 lines, I did re-write a short version;
var pageLoader = function(link){
var page = $(link).attr("href").replace('#','');
if(page != lastCalledURL){
// Load the page.
$.ajax({
beforeSend: function(){ /* remove previously loaded content; */ },
success: function(data){
// remove the loaded content if user clicked to close button.
$("a.close-button").live("click", function(){
$(this).parent().fadeOut().remove();
return false;
});
// load another page if user click another page's link.
$("a.content-loader-link").live("click",function(){
pageLoader(this);
});
// handle with tabs
$("a.tabs").live("click", function(){
var index = $("a.tabs").index(this);
console.log(index);
return false;
});
}
});
lastCalledURL = page;
}
return false;
OK. If I click a link in the page, It calls pageLoader. If I click one of the links just once, pageLoader called once. If I click another link, pageLoader called twice. If I click another link again, pageLoader called third times and so on.
Same things happen for the links that bind with "live" function in the code. If I click a.tabs, it write to console twite. If I clicked another .tabs link, it write to console four times and increasing double for every click.
I don't why it happens. Please let me know if you have any idea.
You can solve it by using the bind and unbind. Like this:
$("a.tabs").unbind('click').bind("click", function(){
var index = $("a.tabs").index(this);
console.log(index);
return false;
});
But i would prefer that you attach this events in your $(document).ready function instead of everytime you make an AJAX call.
$(document).ready(function() {
// Attach your events here.
});
Those live event handlers "Attach a handler to the event for all elements which match the current selector, now and in the future." so you shouldn't need them in your ajax call.
I'm trying to do an ajax post after a button is clicked, and it works in firefox but not in IE the first time the page is loaded. It does work if I refresh the page and try again second time - but not first time and this is crucial.
I've scanned over various web pages - could it be anything to do with the listener? (I've just seen this mentioned mentiond somewhere) Is there something not set correctly to do with ajax and posting when page first loads?
$(document).ready(function() {
$('#btnCont').bind('click',function () {
var itm = $("#txtItm").val();
var qty = $("#txtQty").val();
var msg = $("#txtMessage").val();
var op_id = $("#txtOp_id").val();
//if i alert these values out they alert out no prob
alert(itm+'-'+qty+'-'+msg+'-'+op_id);
$.ajax({
type: "POST",
url: "do_request.php?msg="+msg+"&itm="+itm+"&qty="+qty+"&op_id="+op_id,
success: function (msg) {
document.getElementById('div_main').style.display='none';
document.getElementById('div_success').style.display='block';
var row_id = document.getElementById('txtRow').value;
document.getElementById('row'+row_id).style.backgroundColor='#b4e8aa';
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('Error submitting request.');
}
});
});
I would start debugging the click event. I.e. if you try to put .bind into a a href tag, the tag itself has a click event that may act on an unwanted way. There exist a command that are named something like event.preventDefaults() that avoids the standard feature of click. After All, you try to manipulate the DOM last of all actions (document.load).
$('#btnCont').bind('click',function () { .. }
I would also try to debug the same functionality with adding onClientClick to the tag instead of adding bind to the document load.
I hope that bring some light.
I'm trying to do a simple update, but can't figure out somthing.
I have a table that i get from a DB with an Edit button that when i press change to a Save button so i can save with Ajax the record that the user just edit.
I'm doing the first part just fine, have one function that do all the jquery stuff on the page (that is working just fine).
Now I want to change the $('#a'+productID) line to save insted of edit. i am changing the link attribute also, so when the user presses save it will send him to a function that will make the Ajax request and update the record.
But i dont have a clue how to start that....I don't think it has any thing to do with any bind function becouse i am allready binded by calling the save function (or am i wrong and need to bind antway???) can any one help me out here?
P.S. the save function recives the productID do i have the right product when i will need it.
Don't have a code to send for the save function becouse i don't know how to start it and every thing i tried doesn't work....sorry :-(
It might be easier if you simply had both buttons on the page and toggled between them depending on the page state.
<a id="editButton" href="http://example.com/widget/edit/1">Edit</a>
<a id="saveButton" href="http://example.com/widget/update/1" style="display: none;">Save</a>
$(function(){
$('#editButton').click( function() {
// set up the form as edit...
$(this).hide();
$('#saveButton').show();
return false;
});
$('#saveButton').click( function() {
var button = $(this);
var href = button.attr('href');
$.post(href,$('form').serialize(), function() {
// change form back to readonly...
button.hide();
$('#editButton').show();
}
});
});