Replacing OuterHTML with AJAXHelper.ActionLink
There are various wayswhich provides unobtrusive way of updating UI with response from server via AJAX. One such option provided by MVC framework is Ajax.ActionLink. For example,
@Ajax.ActionLinkAbove code generates a link which when clicked, calls an action called “ActionName” of the controller “ControllerName” and what ever is returned from this action, is displayed in a div with id “DivToBeReplaced”. That’s so easy!But there is a minor caveat in using UpdateTargetID. By default, it replaces the contents of div and not the div itself. Which means in following Razor code,
(
"TextOfLink",
"ActionName",
"ControllerName",
new AjaxOptions() { UpdateTargetId = "DivToBeReplaced"}
)
<div id="mydiv">
Some Text
@Ajax.ActionLink(
"Refresh",
"Index",
new AjaxOptions(){UpdateTargetId = "myDiv"}
<div>
Clicking on generated action link would result in following:
<div id="mydiv">This is so because action link will replace what ever comes from server with the content inside mydiv and not mydiv itself (in other words, it replaces innerHTML and not OuterHTML)
<div id="mydiv">
Some Text
@Ajax.ActionLink
(
"Refresh",
"Index",
new AjaxOptions(){UpdateTargetId "myDiv"}
)
</div>
</div>
Fix: Instead of using UpdateTargetId, use OnComplete event handler which takes as input a JavaScript method name (automatically called when view response is received from server)
and in script:
@Ajax.ActionLink("TextOfLink",
"ActionName",
"ControllerName",
new AjaxOptions() { OnComplete= "setMyDiv"})
data is the object that contains response while responseText property returns response as a string. While divId is passed from view which needs to be replaced with response content. This gives a finer control over manipulating response and playing with DOM.
function setMyDiv(data)
{
$('#mydiv').replaceWith(data.responseText);
}
Q) What if div id is dynamically generated and hence not known in advance?
A) This is what I was stuck upon and found a cute hack. Internally, JQuery contains response in a variable called “xhr”. So, I was able to solve this problem as following:
@Ajax.ActionLink(
"TextOfLink",
"ActionName",
"ControllerName",
new AjaxOptions() { OnComplete= "setSomeDiv(xhr,'" + Model.UniqueID +"')" })
where Model.UniqeId is some property of model containing unique Id. And the script:
function setSomeDiv(data, divId)
{
$(document).find('#' + divId).replaceWith(data.responseText);
}
This works great!! Hope it helps someone!!
Do let me know if you've a better approach.
Comments
Post a Comment