Hi there,
I was wondering if it's possible to cache an ajax request so that the webservice isn't hit each time you mouseover the same element. I know in jquery there is a feature that allows this through their ajax options providing a good performance gain.
At the moment everytime you roll over the same tooltip element it makes a request. How can I go about setting the same option using qTip?
Regards DotnetShadow
If my understanding of how jQuery's internal AJAX functionality works is correct, caching should be done by the library itself automatically without any prior settings.
craig Wrote:If my understanding of how jQuery's internal AJAX functionality works is correct, caching should be done by the library itself automatically without any prior settings.
I've setup a test page which shows this isn't happening along with my other errors that I have reported:
http://74.212.223.45/qTipSample/admin/Default.aspx
Hope this helps
DotnetShadow
Nice demo dotnewshadow, very informative.
Regarding the caching issue, this isn't a case where caching can be used, since the page you're requesting is always changing. Caching only works on pages with static content, such as HTML pages or static text files. What are you trying to accomplish which requires the data caching?
craig Wrote:Nice demo dotnewshadow, very informative.
Regarding the caching issue, this isn't a case where caching can be used, since the page you're requesting is always changing. Caching only works on pages with static content, such as HTML pages or static text files. What are you trying to accomplish which requires the data caching?
Hi Craig,
Thanks for getting back to me, I understand what you mean with dynamic pages but even if I produce the same response it still doesn't cache it. I've implemented this in the past using another tooltip plugin and it would cache the result. But for some reason using your plugin it doesn't cache the result?
What I'm trying to achieve is to make unnecessary requests. The whole thing about caching the result is the next time it makes the same request it should just returned the cached version, so Im not sure what is happening there.
This was the tooltip plugin I had been using - Cluetip:
If you lok at Example 2:
http://plugins.learningjquery.com/cluetip/demo/ you can see through firebug that the ajax request is only made once then cached
Maybe you can get an idea how caching got implemented there? I think they just set up a variable that holds the ajax request response so if it exists then show the contents if not then make the ajax request.
http://github.com/kswedberg/jquery-cluet...cluetip.js
Regards Dotnetshadow
Dotnetshadow,
Looking over the code I can't see how it's being done any differently. Are you sure it's caching it and instead only retrieving the content once?
craig Wrote:Dotnetshadow,
Looking over the code I can't see how it's being done any differently. Are you sure it's caching it and instead only retrieving the content once?
Yeah I looked deeper into the code and looks like the code attaches the result to the element using jquery data api i.e div.data(). Then the next time you hover over the element it checks if the data is present and if so it returns it, else it does the ajax request. So basically you could implement the same trick provide perhaps an option whether you want this feature and basically on first ajax request populate the element with the result etc
What do you think about that?
Regards Dotnetshadow
Dotnewshadow, thanks for looking further into this. I'm 50-50 as to whether this should be a base-level feature or whether it should be implemented individually via the API...
I can however see that a majority of users may find this useful in some way or another, but in heinsight it seems like this could be accomplishe simply by using a different API callback i.e. onRender rather than onShow? I'll have a think, but in the mean time:
Would you the users, find this kind of feature useful?
craig Wrote:Dotnewshadow, thanks for looking further into this. I'm 50-50 as to whether this should be a base-level feature or whether it should be implemented individually via the API...
I can however see that a majority of users may find this useful in some way or another, but in heinsight it seems like this could be accomplishe simply by using a different API callback i.e. onRender rather than onShow? I'll have a think, but in the mean time:
Would you the users, find this kind of feature useful?
Thanks Craig for looking into this, in the meantime with the onRender method could you provide a quick example of what would be needed to accomplish this task?
DotnetShadow
Dotnetshadow,
Basically the code is indetical to what you ahve now, except that beforeShow within the api object becomes onRender e.g.:
JS Code
api:{ beforeShow: function() { } };
craig Wrote:Dotnetshadow,
Basically the code is indetical to what you ahve now, except that beforeShow within the api object becomes onRender e.g.:
JS Code
api:{ beforeShow: function() { } };
Hi there I noticed that in your latest branch version you have introduced a new pre-fetch feature which sounds great. I just wanted to know does that mean if you have 1000 tips on a page it will try and pre-fetch each one?
The problem I see with this is that there could be a case when a page loads and a user doesn't roll over any tooltips so all the pre-fetching is a waste, but having the ability to cache the tooltip once you have rolled over it that would be very handy, perhaps we need to options one to suggest whether to pre-fetch and one for caching only.
Also how do you I use the prefetch option using beforeShow function?
Currently I'm using this function (will prefetch and cache work with this?):
JS Code
function ShowInformation(item) {
$(item).qtip(
{
content: 'Loading...',
show: {
solo: true,
when: 'mouseover',
effect: { type: 'fade', length: 10 },
ready: true
},
hide: {
when: 'mouseout',
effect: { type: 'fade', length: 10 },
fixed: true
},
position: {
// corner: {
// target: 'rightMiddle',
// tooltip: 'leftTop'
// },
target: false,
adjust: { mouse: false, scroll: true, screen: true, x: 5 }
},
style: {
tip: 'bottomLeft', // No need to specify the corner explicitly if you want it to default to the tooltip corner
name: 'blue',
border: { width: 1, radius: 3 }
},
api: {
onHide: function() {
$(item).qtip('destroy');
},
beforeShow: function() {
var url, data, method, options, cache;
// Setup request configuration
url = 'Information.aspx/GetInfo';
//data = "{username:'" + username + "', c:" + c + "}";
data = "{}";
method = 'POST';
options = {
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: true,
beforeSend: function(xhr) {
xhr.setRequestHeader("X-MicrosoftAjax", "Delta=true");
},
error: function(xhr, textStatus) {
alert("error");
var isAjaxRedirect = xhr.status == 200 && xhr.responseText.match(/pageRedirect/);
if (isAjaxRedirect == "pageRedirect") {
// forms authentication ticket expired
var responseArray = xhr.responseText.split("|")
location.href = responseArray[responseArray.length - 2];
}
else {
// something else
}
}
};
// Load the content using the configuration
this.loadContent(url, data, method, options);
},
// Parse newly loaded content if an object is returned
onContentLoad: function(content) {
var parsedContent;
// Return if content isn't an object or is blank
if (typeof content !== 'object' || content.length < 1) return
// Do something with the content
parsedContent = content.d;
// Return that newly parsed content
return parsedContent;
}
}
});
}
Regards Dotnetshadow
Hi dotnewshadow,
Sorry it's taken so long to reply, busy preparing for the 1.0 release with a new rounded corner engine

. Any who, the prefetch functionality is implemented as a pre-cursor to tooltip rendering, which means that sadly it can't be used using the beforeShow event like you need. You can however declare the URL and prefetch within the initial options to prefetch then set it manually like you are doing now? That may work. Get back to me if you require any more assistance.
Thanks for getting back to me,
I think earlier you mentioned to use onRender method to cache the data, do you mean just set up an array or something and just store the results in that? and then each time I check the array before calling the ajax method?
Dotnetshadow
The onRender solution should work fine for you. Basically it just involves replacing beforeShow with onRender in your API callbacks like so:
JS Code
function ShowInformation(item) {
$(item).qtip(
{
content: 'Loading...',
show: {
solo: true,
when: 'mouseover',
effect: { type: 'fade', length: 10 },
ready: true
},
hide: {
when: 'mouseout',
effect: { type: 'fade', length: 10 },
fixed: true
},
position: {
// corner: {
// target: 'rightMiddle',
// tooltip: 'leftTop'
// },
target: false,
adjust: { mouse: false, scroll: true, screen: true, x: 5 }
},
style: {
tip: 'bottomLeft', // No need to specify the corner explicitly if you want it to default to the tooltip corner
name: 'blue',
border: { width: 1, radius: 3 }
},
api: {
onHide: function() {
$(item).qtip('destroy');
},
onRender: function() {
var url, data, method, options, cache;
// Setup request configuration
url = 'Information.aspx/GetInfo';
//data = "{username:'" + username + "', c:" + c + "}";
data = "{}";
method = 'POST';
options = {
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: true,
beforeSend: function(xhr) {
xhr.setRequestHeader("X-MicrosoftAjax", "Delta=true");
},
error: function(xhr, textStatus) {
alert("error");
var isAjaxRedirect = xhr.status == 200 && xhr.responseText.match(/pageRedirect/);
if (isAjaxRedirect == "pageRedirect") {
// forms authentication ticket expired
var responseArray = xhr.responseText.split("|")
location.href = responseArray[responseArray.length - 2];
}
else {
// something else
}
}
};
// Load the content using the configuration
this.loadContent(url, data, method, options);
},
// Parse newly loaded content if an object is returned
onContentLoad: function(content) {
var parsedContent;
// Return if content isn't an object or is blank
if (typeof content !== 'object' || content.length < 1) return
// Do something with the content
parsedContent = content.d;
// Return that newly parsed content
return parsedContent;
}
}
});
}
I'll give this a try, it will be interesting to see if the result does cache or if I have to manually create a caching mechanism similar to the $(element).data() idea we discussed earlier
Dotnetshadow
Hi Craig, hi Dotnetshadow,
Me too, I would like to see a feature where you can the results of requests cached.
Any news on this?
Thanks,
hbf
Hi hbf,
There is currently a new content.url.once option in the newest branch revisions, but they are highly unstable at the moment with some quite heavy changes to the source code. If you want you can take a look through the branch revisions and pick out the revision the option was added:
http://bazaar.launchpad.net/~craig.craig..._revid=176