fire one set of functions first, then callback to a final function - javascript

I have an jquery ajax success function which uses a template to put json information in a div, then a modal plugin to fade in a modal. The problem is, the modal is firing before all the content is completely written to the div. Is there a way that I can make this collection of template actions complete before I call the modal fires?
success: function (data) {
//run generic order header through template
$('#order_detail_header').vkTemplate('scripts/templates/header_template.tmpl?<?=time()?>', data);
//run header 2 information through template
$('#order_detail_header_2').vkTemplate('http://scripts/templates/detail_header_2_template.tmpl?<?=time()?>', data);
//run shipment information through template
$('#order_detail_shipment_information').vkTemplate('scripts/templates/detail_shipment_information_template.tmpl?<?=time()?>', data, function(){ $(".tracking_box").hide();});
//run line item information through template
$('#order_detail_line_item_information').vkTemplate('http://www.isco.net/dev/webtrack/scripts/templates/order_detail_line_item_information_template.tmpl?<?=time()?>', data, function(){ $(".tracking_box").hide();});
//run pricing information through template
$('#order_detail_pricing_information').vkTemplate('http://www.isco.net/dev/webtrack/scripts/templates/order_detail_pricing_information_template.tmpl?<?=time()?>', data['order']);
$('#order_detail_modal').reveal({ // The item which will be opened with reveal
animation: 'fade', // fade, fadeAndPop, none
animationspeed: 600, // how fast animtions are
closeonbackgroundclick: true, // if you click background will modal close?
dismissmodalclass: 'close_modal' // the class of a button or element that will close an open modal
});
}
I tried wrapping the whole thing in an function and putting the .reveal function in a callback, but i must have the wrong syntax or idea. Any suggestions are appreciated. Thank you!

I presume that vkTemplate dose a ajax call. If so then you have 2 options:
use sync ajax
add a callback param to vkTemplate so you can order the requests
div1.vkTemplate(url1,data1,function(){
// the cbk function, when vkTemplate is done getting data from url and added the html
div2.vkTemplate(url2,data2,function(){
// all data loaded? yes? then call your function
modal.reveal()
})
})

This is a simplistic answer as I'm not familiar with the plugins you are using, but it will work....
success: function (data) {
var counter = 5;
//run generic order header through template
$('#order_detail_header').vkTemplate('scripts/templates/header_template.tmpl?<?=time()?>', data, function() { doReveal(); });
//run header 2 information through template
$('#order_detail_header_2').vkTemplate('http://scripts/templates/detail_header_2_template.tmpl?<?=time()?>', data, function() { doReveal(); });
//run shipment information through template
$('#order_detail_shipment_information').vkTemplate('scripts/templates/detail_shipment_information_template.tmpl?<?=time()?>', data, function(){ $(".tracking_box").hide(); doReveal(); });
//run line item information through template
$('#order_detail_line_item_information').vkTemplate('http://www.isco.net/dev/webtrack/scripts/templates/order_detail_line_item_information_template.tmpl?<?=time()?>', data, function(){ $(".tracking_box").hide(); doReveal(); });
//run pricing information through template
$('#order_detail_pricing_information').vkTemplate('http://www.isco.net/dev/webtrack/scripts/templates/order_detail_pricing_information_template.tmpl?<?=time()?>', data['order'], function() { doReveal(); });
function doReveal() {
counter--;
if (counter > 0) return;
$('#order_detail_modal').reveal({ // The item which will be opened with reveal
animation: 'fade', // fade, fadeAndPop, none
animationspeed: 600, // how fast animtions are
closeonbackgroundclick: true, // if you click background will modal close?
dismissmodalclass: 'close_modal' // the class of a button or element that will close an open modal
});
}
}
It just applies a counter that specifies how many functions need to complete before doing the reveal, and then checks each time a call to vkTemplate is complete.

Related

youtube spf is not working after loading with ajax

On my web page, everything is okay.
My js is working very well but clicking on any page, page is loading with ajax but some function is not working for example my bootstrap carousel or my parallax.js plugin..
How do I do event management ?
I'm using youtube spf plugin
some js example on my page
if (!$(".scene").length) return false;
var q = document.getElementsByClassName("scene")[0];
var r = new Parallax(q, {
calibrateX: false,
calibrateY: true,
invertX: false,
invertY: true,
limitX: false,
frictionX: .2,
frictionY: 4,
originX: 0,
originY: 1
});
$('.img-area').cycle({
fx: 'fadeout',
speed: 950,
timeout: 100
}).cycle("pause");
$(".otel-history-list").on("click",function(){
var historyName = $(this).find(".history-current-name").text();
var historyDateIn = $(this).find(".history-current-datein").text();
var historyDateOut = $(this).find(".history-current-dateout").text();
var historyKisi = $(this).find(".history-current-kisi").text();
$(".input-form-ara input").val(historyName);
$(".otel-giris-cikis #checkin").val(historyDateIn);
$(".otel-giris-cikis #checkout").val(historyDateOut);
$(".kisi-sayi-otel-sec .kisi-count").text(historyKisi);
});
or something like these code
and my ajax code
$(function () {
spf.init();
NProgress.configure({ showSpinner: false });
$(document).on('spfrequest', function (event) {
NProgress.set(0.4);
});
$(document).on('spfprocess', function (event) {
NProgress.set(0.6);
NProgress.set(0.8);
});
$(document).on('spfdone', function (event) {
NProgress.set(1.0);
NProgress.done();
});
$(document).on('spfhistory', function (event) {
NProgress.set(0.7);
NProgress.set(0.9);
NProgress.set(1.0);
NProgress.done();
});
});
and I'm using bootstrap,parallax.js,cycle2.js,select2 plugin
I've answered a similar question in the past, so I'm restating it below:
I'm not sure what your full code set is, but based on what you posted, I'm guessing that several of your html elements (that have JQuery event handlers attached to them) are generated and re-generated using your ajax functions-- probably several times, after your original DOM is loaded.
This is the most likely reason why some of your events don't fire after your Ajax codes fire. The event handlers attached to your html elements (such as divs) get "detached" when these elements are programmatically (re)generated using Ajax.
As such, what you would want to do is to "attach" the event handler to a higher level in the DOM tree (highest being your html) that you are sure won't get 'programmatically' regenerated, then you'd want to check if the element in question, which is inside the DOM, exists. You then run your function when this element is found.
So as an example, you have this onclick function in your code:
$(".otel-history-list").on("click",function(){
//your actions
});
The element with the class "otel-history-list" is likely being generated or regenerated by your Ajax call after page load, and as such would get detached from your onclick event listener (See #1-#2 above).
So to rewrite your code following #3 above, you'd want to attach the event listener to something that won't be regenerated by your Ajax, then just look for the specific element inside it, which contains your class of interest:
$(document).on("click",".otel-history-list", function(){
//your actions
});
Hope this helps!

Tooltipster not working properly in the beginning

I am using the tooltipster plugin tool where I got gantt chart drawn with some td given id.
So, which ever id is defined and the mouse over it will get ajax data and show accordingly.
Below is snippet of my codes. Issue here is that the tool tip only appear after few times I mouse the td. Thereafter, it works fine.
I can see, in my debug window, that ajax page is called and following error:
Tooltipster: one or more tooltips are already attached to this element: ignoring. Use the "multiple" option to attach more tooltips. jquery.tooltipster.min.js:1
$(document).ready(function () {
$('td[id]').tooltipster({
// content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
// We'll make this function asynchronous and allow the tooltip to go ahead and show the loading notification while fetching our data
continueTooltip();
var idval=0;
// Next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'GET',
url: 'getDetails.php',
data:idval,
success: function(data) {
// Update our tooltip content with our returned data and cache it
//alert("Data is : "+data);
var finalData = 'Total Data : 300 <br> Total Completed : 200';
//alert("DATA");
//origin.tooltipster: $('<span>testst<strong>This text is in bold case !</strong></span>')
origin.tooltipster({
content: finalData,
multiple: true,
contentAsHTML: true
});
//origin.tooltipster({content: data,contentAsHTML: true}).data('ajax', 'cached');
}
});
//}
}
});
});
The Tooltipster plugin really should be initialised before all of this. Using the mouseenter enter to trigger it's initialisation every time a user hover's over a <td> element is not great practice and is the root problem to your issue. Ideally you would want to break it down into the following:
Find your <td> elements with id's defined.
Apply tooltipster to these elements.
Let tooltipster handle everything from there.
1. Finding your <td> elements
With the magic of jQuery you can fetch these with a clever use of selectors rather than querying a larger set with your initial implementation, gathered from the answers within the StackOverflow thread here, jquery get only all html elements with ids, we get:
$('td[id]')
This will fetch you all <td> elements with an id defined, be warned this could be a bit slow if you have an extensive table. Alternatively you can select, then apply a filter to narrow down your set:
$('td').filter(function(){
return $(this).attr('id') !== undefined;
});
Both will essentially do the same!
2. Applying tooltipster to these elements
I've not done much here since you had a lot of commented out code, so I've kept it the same, with some minor tweaks, here is my version of the "working code":
$('td[id]').tooltipster({
// content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
// We'll make this function asynchronous and allow the tooltip to go ahead and show the loading notification while fetching our data
continueTooltip();
// Next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'GET',
url: 'getDetails.php',
data: $(this).attr('id'),
success: function(data) {
// Update our tooltip content with our returned data and cache it
//alert("Data is : "+data);
var finalData = 'Total Data : 300 <br> Total Completed : 200';
//alert("DATA");
//origin.tooltipster: $('<span>testst<strong>This text is in bold case !</strong></span>')
origin.tooltipster({
content: finalData,
multiple: true,
contentAsHTML: true
});
//origin.tooltipster({content: data,contentAsHTML: true}).data('ajax', 'cached');
}
});
//}
}
});
3. Letting tooltipster handle everything from here
Tooltipster (when intialised) is triggered by default when hovering over an element, this means your functionBefore will be run before this "hover" event, causing your AJAX request to be run each time, there is no need to do anything more thereafter :D
I hope this helps! :)
You can use this code :
var tooltipInstance;
$("body").on('mouseover', 'td[id]:not(.tooltipstered)', function(){
tooltipInstance = $(this).tooltipster({
//your code ...
});
tooltipInstance.tooltipster('open');
});

jquery mobile swipe function only works after page refresh

I am using jquery mobile for sideswipe gestures on ipad.
The below code is in a file referenced in my html file.
My html file has:
<div data-role="page" id="device1">
<!--content for this part of html page -->
</div>
<!--more divs with incrementing id -->
<div data-role="page" id="device4">
<!--content for this part of html page -->
</div>
This format is used in multiple html files.
I use this code (found on stackoverflow) - didnt want to post on old thread.
$(document).ready(function() {
$('.ui-slider-handle').on('touchstart', function(){
// When user touches the slider handle, temporarily unbind the page turn handlers
doUnbind();
});
$('.ui-slider-handle').on('mousedown', function(){
// When user touches the slider handle, temporarily unbind the page turn handlers
doUnbind();
});
$('.ui-slider-handle').on('touchend', function(){
//When the user let's go of the handle, rebind the controls for page turn
// Put in a slight delay so that the rebind does not happen until after the swipe has been triggered
setTimeout( function() {doBind();}, 100 );
});
$('.ui-slider-handle').on('mouseup', function(){
//When the user let's go of the handle, rebind the controls for page turn
// Put in a slight delay so that the rebind does not happen until after the swipe has been triggered
setTimeout( function() {doBind();}, 100 );
});
// Set the initial window (assuming it will always be #1
window.now = 1;
//get an Array of all of the pages and count
windowMax = $('div[data-role="page"]').length;
doBind();
});
// Functions for binding swipe events to named handlers
function doBind() {
$('div[data-role="page"]').on("swipeleft", turnPage);
$('div[data-role="page"]').on("swiperight", turnPageBack);
}
function doUnbind() {
$('div[data-role="page"]').die("swipeleft", turnPage);
$('div[data-role="page"]').die("swiperight", turnPageBack);
}
// Named handlers for binding page turn controls
function turnPage(){
// Check to see if we are already at the highest numbers page
if (window.now < windowMax) {
window.now++
$.mobile.changePage("#device"+window.now, "slide", false, true);
}
}
function turnPageBack(){
// Check to see if we are already at the lowest numbered page
if (window.now != 1) {
window.now--;
$.mobile.changePage("#device"+window.now, "slide", true, true);
}
}
// Named handlers for binding page turn controls
function navigate_without_swipe(page){
// Check to see if we are already at the highest numbers page
$.mobile.changePage("#device"+page, "slide");
}
Please tell me why I need to reload the page for this javascript to work
Because you are using $(document).ready
Thats a JQuery event.
Jquery Mobile has its own loading events because pages are loaded by JQM using AJAX which means that event is not fired.
I think you probably want to do that in a pageinit but check the documentation to see if there is amore appropriate event for your situation.
JQuery Mobile documentation

simple modal - calling modal when another modal is present?

I am using Simple Modal and I have it working perfectly except for one thing.
I can't work out how to handle cases where the modal is already visible and another modal is called.
What I want is something like shadowbox where it will resize the box to the size of the new content.
Although if not possible I will settle with the box disappearing and the new one appearing.
How would I do this?
This is my current code
//show/hide animations
$.extend($.modal.defaults, {
onOpen: function (dialog) {
dialog.overlay.fadeIn('fast', function () {
dialog.data.show();
dialog.container.show('slide', {direction: 'down'}, 'medium');
});
},
onClose: function (dialog) {
dialog.container.hide('slide', {direction: 'up'}, 'medium', function () {
dialog.overlay.fadeOut('fast', function () {
$.modal.close();
});
});
}
});
//triggers
$('#subscribe_form').modal({
minWidth: 860,
minHeight: 390
});
//this link is both inside the subscribe_form modal, and on a menu bar
$('.login_link').live('click', function() {
$('#login_dialog').modal();
});
This doesn't seem like the greatest solution, but you could try:
http://jsfiddle.net/Xwn3G/
$('.login_link').live('click', function() {
setTimeout(function(){$('#login_dialog').modal();}, 1500);
$.modal.close();
});
From what I can tell, the call to the show the new modal has to follow the completion of the model close; or, it's canceling the events of the elements within the model html onClose. I was also able to get it to work with 1000 milliseconds, but that will probably depend on the user's browser.
You could do this doing a fake get call
$('.login_link').live('click', function() {
$.get('', function(){
$('#login_dialog').modal();
});
});
That way the modal function will be called on the callback and would work. I am not sure the reasons why this doesn't work without getting out of the current scope but at least works :)

load ajax content before showing tooltip

I wanted to create a drop down at a
certain position based on a users
click and
I wanted this to come in the form of a drop down also
the content in the drop down would be dynamically genereated through
ajax..
im using jquery-tools tooltip to do this but am facing some problem...
the ajax content is loading only after the second click ..
THIS IS THE CODE TO CREATE AN ARRAY of TOOLTIP OBJECTS
$(document).ready(function(){
var show = false;
var tips = new Array();
$(".replie").each(function(){
$(this).tooltip({ effect: 'fade', events: {widget:'click,'},position:"bottom right",onBeforeShow:function() {
this.getTrigger().fadeTo("slow", 0.8);
}})
tips.push($(this).tooltip(0));
});
AND THIS IS THE CODE TO CONTROL THE TOOLTIPS BEHAVIOR AND LOAD AJAX CONTENT
$(".replie").click(function(evt){
if(!evt){
evt=window.event;
}
var row =evt.target.parentNode.id[2];
var aid=evt.target.id;
var uid= <?php echo $uid ?>;
var tip;
$("#tip"+row).load("reply.php?uid="+uid+"&aid="+aid,function(){
$(this).hide()
});
if(tips[row].isShown)
{
tips[row].hide();
}
else
{
tips[row].show();
}
});
HOW DO I LOAD THE CONTENT AND THEN SHOW THE TOOLTIP .. ?
Use jQuery.ajax() function instead of jQuery.load() function. You can set a callback function on complete or success event. Inside that handler, trigger the tooltip function.
This is the documentation of jQuery.ajax(): http://api.jquery.com/jQuery.ajax/

Categories