MVC3 WebGrid: When sorting or paging, is there a way to call a javascript method BEFORE the Controller Action method is called? - asp.net-mvc-3

I've been using this link as a reference for developing my WebGrid (http://msdn.microsoft.com/en-us/magazine/hh288075.aspx).
Currently what is happening is that my WebGrid is loaded, and I'm able to asynchronously page and sort just fine...no problems. What is an irritation is that once I click to page or sort, the user isn't aware that anything is happening.
So what I'm looking for is a way to call a javascript function (or anything really) before the controller's action method is called, so that I have something appear to let the user know work is being done to return their next page, sort, and so forth.
I'm not sure if I'm just missing something, but any help would be appreciated.

You could use the .ajaxSend() and .ajaxComplete() methods to show and hide some spinner during the AJAX requests:
$(function() {
$('#grid').ajaxSend(function () {
// this will be called before the AJAX request is sent
// here you can show some spinner
$('body').append('<div id="spinner">Loading ...</div>');
}).ajaxComplete(function () {
// this will be called after the AJAX request completes and
// could be used to hide the spinner
$('#spinner').remove();
});
});

Related

Optimal way to use Ajax

i have a web page that once it loads, it sends a lot of Ajax calls to fill some parts of the page. It's a Django template, it's sending around six calls with code similar to this :
$.get("http://127.0.0.1:8000/purchase/?name="+me.username, function(data){
$("#purchase").append(data);
});
sometimes they are called when the user clicks on a button, but they are mostly called when the page is refreshed.
Im new to Ajax, and I want to know if it's the right way to use this technology in an optimal manner. Is it alright to send Ajax calls similar calls that are separate ?
Thanks
For now i think just put those $.get() scripts into a jQuery ready function if you want them to fire when page loads and not on refresh... And yes its normal for a page to behave like this. That's what AJAX is meant for.
$(document).ready(function(){
$.get("http://127.0.0.1:8000/purchase/?name="+me.username, function(data){
$("#purchase").append(data);
});
//other $.get 's
});
Also use the jQuery ready() documentation.

jquery prevent functions form executing, while an ajax post is in progress

I´m looking for a possibillity to prevent all functions from being executet while an ajax post is in progress. For example: I have a modal box where you can switch between two forms with a simple tab-navigation. When a user submits one of the forms, the data will be sent via ajax. So how can I avoid that the user can switch between the forms till the post is finished.
Is there a simple way to do that?
something like event.stopImmediatePropagation() during the ajax post.
Simple way to do that is just display an overlay. An element that takes up the whole screen and has no event handlers. The most popular option seems to be semi transparent div with a loading indicator to give user an idea about what's happening and that nothing will work on the website until request finishes.
Example: http://jsfiddle.net/NezTc/11/
i am not sure if other methods exist but i would bind a listener for all submits and check there if a flag for ongoingAjax request is set. This flag would be set by my ajax calls.
something like
$(function(){
var onGoingAjaxRequest = false;
$('form').submit(function() {
if(!onGoingAjaxRequest) {
return true;
}
return false;
});
});
I'm not sure you can "cut off" all functions until a given point in time, but I know you can always:
Header all functions with if(isPosting) return; and add
var isPosting = true
$.ajax({ [...], complete:function(r){ // this is the ajax function
isPosting=false;
}});
Or, overlay the whole thing and add a big preloader and a Please wait... message.

How to trigger unobtrusive javascript when the content is dynamic with ajax (Lightbox)

I've got some links coming in from ajax that need lightbox functionality:
<img src='...'>
Normally this is given behavior via an on page load handler, but since the content is coming from ajax, the UJS isn't getting triggered.
Any way to do this?
If the content is coming from AJAX, then din't setup the event handling during page load. Instead, let the event bubble to the topmost container that is not being changed or replaced by AJAX. Worst case, use document as the topmost node.
$('<root element selector>').on('click', 'a.lightbox', function() {
// activate lightbox on the clicked element.
});
I'm not sure how you're triggering the ajax requests, but if it's with jQuery which seems likely, you can bind the lightbox in the success callback:
$.ajax({
url: '/route',
success: function (response, status) {
$('.lightbox').lightbox();
}
});
You can pass in a context to the jQuery selector so you don't re-attached the lightbox to links that are already in the page, for example if your ajax call is adding the links to a div with id 'lightbox_links', use this selector instead:
$('.lightbox', '#lightbox_links').lightbox();

jQuery: Firing an AJAX event local to the element that is loading data

I've been playing around with subscribing elements to AJAX events in jQuery.
I have an element that I am using to load AJAX response's. This element is only displayed IF there is data pertinent to the current context of the program.
So, I thought it would be nice and easy to .show() whenever an AJAX request has completed on it and hide it when I need to. I would like to remove the need to implicitly .show() the element every time I make an AJAX request.
In jQuery there is .ajaxSuccess() and .ajaxComplete(). These however, will fire when any AJAX request completes/succeeds, so when loading data in other parts of the page, my hidden element will .show().
The solution seems to be (per. the jQuery API reference) to use the ajaxOptions parameter in your event handler function:
$('.log').ajaxComplete(function(e, xhr, settings) {
if (settings.url == 'ajax/test.html') {
$(this).text('Triggered ajaxComplete handler.');
}
});
What I don't understand is the reason for registering an event handler for all AJAX requests to a specific element, besides being able to use $(this). Am I missing something, can I register an event handler for an AJAX request specific to an element?
If not, is there any event driven alternative to using the .url? The reason I ask is that I use the page fragment extensively for tracking page state and it would be easier to have an event handler .show() my element whenever an AJAX request loads data into it.
EDIT: Post title grammar.
My thinking, is that you want something like this:
$(document).ajaxComplete(function(e, xhr, settings) {
if(settings.url == 'ajax/test.html') {
$('#foo').text('Triggered ajaxComplete handler.');
} else if(settings.url == 'ajax/another.html') {
$('#bar').text('Triggered ajaxComplete handler.');
}
});
Does that make sense, or am I completely missing the point?
Bind a global event handler to AJAX requests and then use the event target member to decide to show elements:
$(document).ajaxSuccess(function (event, xhr, settings) {
if ($(event.target).is('#main'))
$('#main').show();
});
Would be nice to be able to fire on AJAX requests that only target specific elements, but there doesn't seem to be a way.
EDIT: Syntax

Bind custom event handler after ajax load

Specifically I'm looking to bind lightbox to a specific element. Normally I would just do this: $('a.lightbox').lightBox(); but that isn't working since I'm doing some loading with AJAX. Looking at the jQuery API I found .bind() and .live() but I'm not getting anything when I do $('a.lightbox').bind('lightBox') after the AJAX .load() call.
What am I missing?
You need to add a callback function that handles that.
$("#div").load(url, {}, function(){ $('a.lightbox').lightBox(); });
Bind isn't going to help you, as the event isn't getting an event fired on it.
Another way would be to bind to an element higher up in the dom and check the target type. Such as:
$('#div').bind('click', function (event) {
target = $(event.target);
if (target.hasClass('lightbox')) {
// do stuff here
}
});
Just don't go too far up or you'll be catching way too many clicks.

Resources