How to use $(this) inside MVC3 Ajax.ActionLink OnBegin,OnComplete Events

MichaelLake picture MichaelLake · Jul 8, 2011 · Viewed 9.9k times · Source

My Controller creates a list of links like this

<ul id="MainMenu">
@foreach (var item in Model.MenuItems)
{
    <li>@Ajax.ActionLink(item.Caption,
    item.ActionName,
    item.ControllerName,
    new AjaxOptions
    {
        UpdateTargetId = "pageBody",
        OnBegin = "BeginUpdatePage",
        OnComplete = "EndUpdatePage",
        OnFailure = "FailUpdatePage"
    })
    </li>
}
</ul>

I have some javascript like this

function BeginUpdatePage() {
 $("#MainMenu li").removeClass('selected');
 $(this).parent().addClass('selected');
 $("#pageBody").fadeTo('slow', 0.5);
}

function EndUpdatePage() {
 $("#pageBody").fadeTo('slow', 1);    
}

function FailUpdatePage() {
 alert('There has been an error loading this page please try again.');
}

in the BeginUpdatePage function line 1 and 3 execute fine, but line 2 "$(this).parent().addClass('selected');" does not visiably do anything... (I have declared that class in my css).

I have looked at Jquery docs (Jquery.ajax()) it says that "this" is the element that was clicked. I have also checked in "jquery.unobtrusive-ajax.js" that was in my project by default. This file also passes "this" when executing my function.

"result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this,arguments);"

What am I doing wrong here... I have seen other examples that have used this technique but I have been failing all day!

How can I get to the element that was clicked, inside my Begin, complete functions.

Answer

Nick Albrecht picture Nick Albrecht · Jan 30, 2013

UPDATE Jan 20, 2014: The official 3.1 version of the unobtrusive ajax script contains this change, and was published at the same time as the MVC 5.1 release (Jan 17th). Go check check it out :-)

Original response

I came across this a while back to achieve the result you are looking for. VERY simple to do.

Arround approximately line # 100 of the jquery.unobtrusive-ajax.js file, add this one line of code.

options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });

options.context = element; // <--- Add this line

method = options.type.toUpperCase();
if (!isMethodProxySafe(method)) {
    options.type = "POST";
    options.data.push({ name: "X-HTTP-Method-Override", value: method });
}

That's it, you should be able to use this to reference the source element now.