react-social-login

The easiest way to integrate Social Login in your React Apps ...Checkout NPM

Tuesday, March 20, 2012

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.ActionLink
(
      "TextOfLink", 
      "ActionName",
      "ControllerName", 
      new AjaxOptions() { UpdateTargetId = "DivToBeReplaced"}
)
Above 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,

<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">
<div id="mydiv">
    Some Text
    @Ajax.ActionLink
(
       "Refresh",
       "Index", 
       new AjaxOptions(){UpdateTargetId "myDiv"}
)
</div>
</div>
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)

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)
@Ajax.ActionLink("TextOfLink",
"ActionName",
"ControllerName",
new AjaxOptions() { OnComplete= "setMyDiv"})
and in script:
function setMyDiv(data)
{
  $('#mydiv').replaceWith(data.responseText);
}
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.

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.

2 comments :

  1. What does your method look like on the controller?
    I have something like this: public ActionResult AddCampus(int CampusUID, string CampusID, string CampusName, int extractID)
    {

    which returns -->
    return PartialView("_ExtractCampusDetails", model); and it is reloading the entire page instead of just refreshing the div content.. kind of driving me crazy...

    ReplyDelete
    Replies
    1. I don't think controller can be an issue as long as you are using AJAX.BeginForm and not HTML.BeginForm.

      Delete

What are your thoughts on this post? Did you like it?