Caching ajax result on client side in asp.net mvc2 - user-interface

I want to do something like
This is screenshot of google transliterator that can be found here. In this application user writes in Roman script and when he/she presses space an ajax request goes to server bringing back list of words. Roman word is then replaced by word top in the result list (Urdu result list in my case). Now when I continue typing and after sometime i come back and see that a word is not like I intended to write.
I click on that word and a context menu would open like shown in the figure, but the important thing is that this time no ajax request goes to the server rather Google picks the result somewhere stored in client area (browser). My question is how can I cache ajax result on client side and second thing is how I can associate each result with each word in text area or rich text box using a context menu or similar interface.
I want to accomplish similar functionality in asp.net mvc2.

Just store the result of your ajax call in a javascript variable - you can access it later on:
var dictionary = new Object();
var input = 'hello';
$.ajax({
url: url,
dataType: 'json',
data: data, // <-- you send your input to server here
success: function(response) {
dictionary[input] = response;
}
});

Related

Ajax call bring the user back to same page

I have a search page done using Laravel. On that page there is a button which makes an AJAX call to another url. That page is paginated, so the user can be on the first, second or last page.
My problem is, How can I bring the user back to the same page and point that he was.
Or, Is there a way to just call a method to perform some actions on the database?
Thats my Ajax Call:
$.ajax({
url: $(this).attr('data-href'),
dataType: 'html',
success:function(data) {
$('#ajaxResponse').html(data);
$.growl.notice({ title: 'Voto', message: 'Computado com sucesso' });
$(this).find('.fa').toggleClass('fa-heart-o fa-heart');
}
});
I know if i take the $('#ajaxResponse').html(data); bit it is going to perform the change but not update the numbers that i need. Any ideas?
Here is the documentation for pagination in Laravel with JSON. As you can see, when you paginate your data, the resulting JSON object will contain information about the next and previous pages. Update the links your users click with the provided information and they should see the correct data.
You can try to store the actual page in a session key and use a controller to check this key and display the page that you want. In this case you can keep your ajax call as it is and change only your laravel controller ad view.

How to use location hash with ajax forms so clicking 'back' button returns user to the previous page state?

I read the manual about location hash, but seems I didn't understand it.
I do like this:
$.ajax({
url: "/tst.htm",
success: function(data){
$("#center").html(data.content);
location.hash="#ACHTUNG";
}
});
and when I press 'back' in the browser, I return to the blank browser page, not to the page I created to test how location hash works.
I need a simple answer how to workaround this most common and simple ajax-based task, not please again a reference to the manual.

Generate save as dialog box with AJAX request in Ext Js

I have an application that contains a grid and button for the user to be able to export the grid to excel. I want to be able to show the save as dialog box when the server responds with the excel file.The server accepts the parameters as a JSON object. Here is my code:-
Ext.Ajax.request({
url: '/export/excel/',
method: 'POST',
//Send the query as the message body
jsonData: jsonStr,
success: function (result,request) {
Ext.DomHelper.append(document.body, {
tag: 'iframe',
frameBorder: 0,
width: 0,
height: 0,
//src:result,
css: 'display:none;visibility:hidden;height:1px;'
});
}, //success
failure: function (response, opts) {
var msg = 'server-side failure with status code: ' + response.status + ' message: ' + response.statusText;
Ext.Msg.alert('Error Message', msg);
}
});
I know there is a similar question ( ExtJS AJAX save as dialog box) but that references a static file on the server.In my case, depending upon the json sent the result is going to be different each time. I get back the entire excel file that i want in the result.responseText. What needs to be done so that the dialog box popup up asking the user for save as options? Also, im not sure how the src in the domhelper should be configured. Any help would be really appreciated.
I believe the only way to do this in a totally client agnostic way is to force it from the server-side using a Content-Type of: octect-stream and Content-Disposition of 'attachment' with a suggested filename. See:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1
and
http://www.ryboe.com/tutorials/php-headers-force-download
You can also use so-called 'dataURIs' but they have their own set of issues:
http://en.wikipedia.org/wiki/Data_URI_scheme
My recommendation would be to return EXCEL content dynamically on the server and just make the button a link to that url that POSTS the current data your working with and sets the correct response headers to trigger your browser to download the file. Since you are doing an AJAX call and not letting the web-browser get the URL directly, any HTTP headers you set to control the way the browser interprets the content won't matter because you are doing it in JS not in the user's browser. By returning the content directly to the user through a link on the server, you'll get around this problem.
Since you actually want the user to click on the link, I don't think AJAX is appropiate here.
I made the server side return the path of the location the file is created and saved, instead of sending the file as an attachment in the response and hence avoiding the problem of setting the headers in the response. Then i just set the source of the iframe in the code to the path that gets returned in the response (result.responseText).

HTML 5 - Ajax popstate and pushstate

I am trying to figure out how to use this pushstate and popstate for my ajax applications. I know there are some plug ins but i am trying to learn how to use it in it's raw form at the moment. I am also aware that in the raw form it is not supported by IE. All that aside, I need some help understanding how to use it.
the pushstate portion of it is pretty simple. Right now i have:
function loadForm(var1,var2){
string = "xyz="+var1+"&abc="+var2;
history.pushState("", "page 1", string);
}
This changes my url just fine and adds it to my url stack. I have another function that looks like the following:
function loadForm2(var1,var2, var3){
string = "xyz="+var1+"&abc="+var2+"&123="+var3;
history.pushState("", "page 2", string);
}
The second function also changes the url when called. Now that i have that part i am trying to figure out how to use the popstate. Right now i have it as follows
window.popState = ajax;
function ajax(){
jQuery.ajax({
type: "get",
url: "../html_form.php",
data: string,
dataType: "html",
success: function(html){
jQuery('#Right_Content').hide().html(html).fadeIn('slow');
validate();
toolTip();
}
})
}
So if you can image my page with two links, one calls the loadForm function and the other link calls loadForm2 function. When i click each of the links the forms loads via ajax just fine and the url changes as it should. When I hit the back button, the url will roll back to the previous page's url BUT the page content loads the current form again instead of the previous form. When i hit the back button it is making an ajax call (firebug) as if it is trying to load the previous form but instead of running the previous ajax call it runs the current ajax call. So my url goes back to the previous url but the form that is loaded or the ajax call that is called is the same as the most recent page load (not the previous page load).
I am not sure what i am doing wrong and any help would be much appreciated.
You are doing something weird.
window.popState = ajax;
I am even surprised that ajax() gets even called.
The normal way of doing it is to register an event handler.
$(window).bind('popstate', function(event) {
var state = event.originalEvent.state;
}
See How to trigger change when using the back button with history.pushstate and popstate?
EDIT:
Basically you need to know which form to load when your state is changed. .originalEvent.state will contain this information which you can then pass on to your ajax call. It should also contain the respective string.
The problem in your approach is that string, always remained the one of the last newly loaded page. You need to read that string in event.orginalEvent.state. use console.log() to find it in that object.
EDIT 2:
Is there a way you can give me an example of what my code should look like. I think you understand what i am trying to accomplish.
Everytime the back button (or forward button) of the browser is clicked, you need to load the page from AJAX.
You have attempted to do this by saying:
window.popState = ajax;
This is dangerous as you are replacing a system function.
Instead you should register an event handler for when the state changes.
jQuery(window).bind('popstate', ajax);
Now everytime the back button is pressed, your ajax() function (should) get called.
So far this will only improve your approach to it, but not fix your problem.
The problem is that your original ajax() function refers to a global variable called string. This global variable has no memory of the previous states. Therefore everytime the original form gets loaded again and again.
But you already are correctly storing string in the state by doing:
history.pushState("", "page 1", string);
So when ajax is called, the browser will give it an event object, which contains all this information.
So all you need to do now is change your ajax() as follows:
function ajax(){
jQuery.ajax({
type: "get",
url: "../html_form.php",
data: document.location.search.substr(1),
dataType: "html",
success: function(html){
jQuery('#Right_Content').hide().html(html).fadeIn('slow');
validate();
toolTip();
}
})
}
Finally you should also stop using string as a global variable by using the var keyword and make sure the string contains a "?":
function loadForm(var1,var2){
var string = "?xyz="+var1+"&abc="+var2;
history.pushState("", "page 1", string);
}
This will reduce any future confusion about something almost working, but not working properly.

Ajax state history in coldfusion page

I'm confused as to how to accomplish this. I have a page which, has a popup filter, which has some input elements and an "Apply" button (not a submit). When the button is clicked, two jquery .get() calls are made, which load a graph, a DataTables grid, photos, and miscellaneous info into four separate tabs. Inside the graph, if one clicks on a particular element, the user is taken to another page where the data is drilled down to a finer level. All this works well.
The problem is if the user decides to go back to the original page, but with the ajax generated graph/grid/photos etc. Originally I thought that I would store a session variable with the filter variables used to form the original query, and on returning to the page, if the session var was found, the original ajax call would be made again, re-populating the tabs.
The problem that I find with this method is that Coldfusion doesn't recognize that the session variable has been set when returning to the page using the browser's back button. If I dump out the session var at both the original and the second page, I can see the newly set var at the second page, and I can see it if I go to the original page through the navigation menu, but NOT if I use the back button.
SO.... from reading posts on here about ajax browser history plugins, it seems that there are various jquery plugins which help with this, including BBQ. The problem that I see with this approach is that it requires the use of anchor elements to trigger it, and then modifies the query string using the anchors' href attributes. I suppose that I could modify the page to include a hidden anchor.
My question, at long last is: is an ajax history plugin like BBQ the best way to accomplish this, or is there a way to make Coldfusion see the newly created session var when returning to the page via the back button? Or, should I consider re-architecting the page so that the ajax calls are replaced by a form submission back to the page instead?
Thanks in advance, as always.
EDIT: some code to help clarify things:
Here's the button that makes the original ajax calls:
<button id="applyFilter">APPLY</button>
and part of the js called on #applyFilter, wrapped in $(document).ready():
$('#applyFilter').click(function(){
// fill in the Photos tab
$.get('tracking/listPhotos.cfm',
{
id: id,
randParam: Math.random()
},
function(response){
$('#tabs-photos').html(response);
}
);
});
Finally, when the user calls the drill-down on the ajax generated graph, it uses the MaintAction form which has been populated with the needed variables:
function DrillDown() {
//get the necessary variables and populate the form inputs
document.MaintAction.action = "index.cfm?file=somepage.cfm&Config=someConfig";
document.MaintAction.submit();
}
and that takes us to the new page, from which we'd like to return to the first page but with the ajax-loaded photos.
The best bet is to use the BBQ method. For this, you don't have to actually include the anchor tags in your page; in fact, doing so would cause problems. This page: http://ajaxpatterns.org/Unique_URLs explains how the underlying process works. I'm sure a jQuery plugin would make the actual implementation much easier.
Regarding your other question, about how this could be done with session variables - I've actually done something similar to that, prior to learning about the BBQ method. This was specifically to save the state of a jqGrid component, but it could be easily changed to support any particular Ajax state. Basically, what I did was keep a session variable around for each instance of each component that stored the last parameters passed to the server via AJAX requests. Then, on the client side, the first thing I did was run a synchronous XHR request back to the server to fetch the state from that session variable. Using the callback method for that synchronous request, I then set up the components on my page using those saved parameters. This worked for me, but if I had to do it again I would definitely go with the BBQ method because it is much simpler to deal with and also allows more than one level of history.
Some example code based on your update:
$('#applyFilter').click(function(){
var id = $("#filterid").val(); // assumes the below id value is stored in some input on the page with the id "filterid"
// fill in the Photos tab
$.get('tracking/listPhotos.cfm',
{
id: id // I'm assuming this is what you need to remember when the page is returned to via a back-button...
//randParam: Math.random() - I assume this is to prevent caching? See below
},
function(response){
$('#tabs-photos').html(response);
}
);
});
/* fixes stupid caching behavior, primarily in IE */
$.ajaxSetup({ cache: false });
$.ajax({
async: false,
url: 'tracking/listPhotosSessionKeeper.cfm',
success: function (data, textStatus, XMLHttpRequest)
{
if (data.length)
{
$("#filterid").val(data);
$('#applyFilter').trigger('click');
}
}
});
This is what you need on the client-side to fetch the state of the photo list. On the server side, you'll need to add this modification to tracking/listPhotos.cfm:
<cfset session.lastUsedPhotoFilterID = URL.id>
And add this new one-line file, tracking/listPhotosSessionKeeper.cfm:
<cfif IsDefined("session.lastUsedPhotoFilterID")><cfoutput>#session.lastUsedPhotoFilterID#</cfoutput></cfif>
Together these changes will keep track of the last ID used by the user, and will load it up each time the page is rendered (whether via a back button, or simply by the user revisiting the page).

Resources