How to execute javascript once an update panel refreshes (Can't get Sys.WebForms.PageRequestManager.getInstance().add_endRequest(); to work) - ajax

using some date time picker plugins i am unable to rebind them after ajax update panel completion.
i used a control containing jquery plugins for date and time , inside page.
it works fine at first but when change drop down list, it's update panel rebind and don't bind jquery functionality again.

Problem is update panel refresh the dom and every child element inside update panel re-render when ajax request by update panel.
<script>
function rebindJqueryPlugins() {
jQuery('.example').datetimepicker();
}
if( typeof(Sys) != "undefined" )
{
prm = Sys.WebForms.PageRequestManager.getInstance();
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(){
//rebinding elements with jquery plugins once we get reponse from server
rebindJqueryPlugins();
});
}
else
{
//we have a problem with ScriptManager
}
//on page load calling jquery plugins to bind elements
jQuery (function(){
//console.log("najam is great");
rebindJqueryPlugins();
});
</script>

Related

Ajaxinate Endless scolling has stopped product Quick View from working

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/

How to trigger a JQuery plugin method from within a JQuery .load callback

I have written a JQuery plugin for some content which is tabbed content on desktop devices and an accordion on mobile devices. I've used the JQuery Boilerplate (https://github.com/jquery-boilerplate/jquery-boilerplate/blob/master/src/jquery.boilerplate.js) as a start point pattern for the plugin file.
I now need to use this plugin on the site within an ajax-loaded modal window. The HTML for the plugin is loading into the modal window fine but the javascript for the plugin is not running.
I believe I need to trigger the init function of my plugin from within the jQuery .load() function which loads the content of the modal window. The function for the ajax overlay looks like this:
menuOverlays = (function(){
var toggleMenuOverlay = function(){
//Toggle a class on the body which triggers styles for the overlay's appearance
$("body").toggleClass('overlay');
//Set the overlay expected to active
var $activeOverlay = $("#"+$(this).data("overlay-element"));
$activeOverlay.toggleClass('active');
//If there is a href on the link that the user clicked on, grab the URL from the link and load the content from that URL into the modal
if($(this).attr("href")){
var urlToLoad = $(this).attr("href") + " #ajaxContent";
$activeOverlay.find(".ajax-content").empty().load(urlToLoad);
}
return false;
};
return{
init: function(){
$("[data-overlay-element]").on("click", toggleMenuOverlay);
}
};
}()),
I have read the following on how to trigger JQuery Boilerplate plugin methods:
Call methods using jQuery Plugin design pattern
and thus tried this:
$activeOverlay.find(".ajax-content").empty().load(urlToLoad, function({
var $t2a = $('.tabs2accordion').tabs2Accordion().data('plugin_tabs2Accordion');
$t2a.init();
});
But I get:
Uncaught TypeError: Cannot read property 'data' of undefined
Any ideas?

Eventlisteners for jqm side panel on multiple pages

I am new to JQM and I'm using Phongeap with JQM for a new project.
My javascript is in one single js file and I'm loading the views from multiple html files.
As the transitions of the siede panel are poor, when I change pages via <a href="page2.html"> I tried to to use event listeners for the Menuitems.
function setPanelListeners(){
$('#menu_search').click(function() {
switchPageTo('search.html');
});
$('#menu_schedule').click(function() {
switchPageTo('program.html');
});
$('#menu_news').click(function() {
switchPageTo('news.html');
});
}
I call this function on the pagebeforeshoe event of each page. To fix the transitions to the way I need it, I use this function
// Close Panel then change page
function switchPageTo(url){
$('#menupanel').panel('close');
setTimeout(function() {
$.mobile.changePage( url, { transition: 'fade'} );
},200);
}
So here is the Problem. It actually works fine on the first page. But on the second page the Menuitems won't work, I guess the event listers are not listening for the new panel, because in the html the panel is loaded twice! And the Event listeners only listen for the first panel (from the first page) which is not displayed on the second page.
Any help is appreciated!
Are you adding panel dynamically on the second page? In JQM 1.3 you have to add panel separately to each page, although this restriction will be removed in future versions.
Use event delegation for dynamic panels:
$(document).on('click' ,'#menu_search' function() {
switchPageTo('search.html')
});

Loading a hidden div into an AJAX jQuery UI tab (future DOM element)

I have been trying to manipulate content that is loaded into jQuery UI tabs via AJAX.
As you can imagine, these elements are "future" DOM elements and aren't manipulated by normal $(".someClass")functions.
I've read using .live() for event handling is now deprecated using jQuery 1.7+ and is replaced by the new .on() method.
My issue is that the div I want to hide, when it loads in an AJAX tab, must be manipulated after the initial DOM load and is not bound to a click event at first.
My functions, which are currently wrapped in $() are below.
I think I have the syntax correct for links that use a click handler, but I'm not sure of the correct way to ".hide()" my "hiddenStory" div at load.
I also think that the functions themselves shouldn't be wrapped in an overall $()?
Any help or advice would be greatly appreciated.
$(function(){
// this .hiddenStory div below is what I want to hide on AJAX load
// need syntax and/or new methods for writing this function
$(".hiddenStory").hide();
// this is a function that allows me to toggle a "read more/read less" area
// on the "hiddenStory" div
$(".showMoreOrLess").on('click', (function() {
if (this.className.indexOf('clicked') != -1 ) {
$(this).removeClass('clicked');
$(this).prev().slideUp(500);
$(this).html("Read More" + "<span class='moreUiIcon'></span>");
}
else {
$(this).addClass('clicked');
$(this).prev().slideDown(500);
$(this).html("See Less" + "<span class='lessUiIcon'></span>");
}
}));
});
// prevents default link behavior
// on BBQ history stated tab panes with
// "showMoreOrLess" links
$('.showMoreOrLess').click(function (event)
{
event.preventDefault();
// here you can also do all sort of things
});
// /prevents default behavior on "showMoreOrLess" links
Could you set the display: none via CSS and override it when you wanted to show the element's content? Another option, if you have to do it this way would be to add the `$(".hiddenStory").hide() in the callback from the AJAX load that is populating the element. For example:
$(".hiddenStory").load("http://myurl.com", function(){
$(".hiddenStory").hide();
}
);
If you aren't using the .load method, you should have some sort of call back to tie into (e.g. success if using $.ajax...)

Jquery in apex 4 Click event help

I have an image that is in my apex application with the id tag of submit_button. I want to display an alert when the user tries to click this image but for some reason nothing is happening. In my header on the page I have this code
<script type="text/javascript">
$(document).ready(function() {
$('#submit_button').click(function) {
alert('hi');
}
});
</script>
Any ideas?
I don't know why that doesn't work (it doesn't work for me either, I just tried), but it is very simple to do via a dynamic action with the following properties:
Event = click
Selection Type = DOM Object
DOM Object = submit_button
"True" Action = Execute Javascript Code
Fire on page load = (unchecked)
Code = alert('hi');

Resources