title: Adding Ajax.ActionLink to DataTable column while using server-side processing?
body: <p>Alright, so I was unable to find any posts with people trying to do this.</p>
  
  <p>I have an MVC4 razor view which contains a jQuery DataTable with a list of Vendor data. In the 1st column I have added 3 buttons: info/edit/delete, which <strong>open a partial view in a hidden div</strong> to the right of the table. I can do a foreach to loop through the model and write the table rows with Ajax Actionlinks and data columns for each item; this all works fine.</p>
  
  <p>My issue came about when I decided to use server-side processing with DataTables because the list contains thousands of rows and the initial page load was very slow. I have server-side processing working fine, but I do not know how to go about getting the Ajax ActionLinks back into the 1st column.</p>
  
  <p>For reference, I followed <strong><a href="http://www.codeproject.com/Articles/155422/jQuery-DataTables-and-ASP-NET-MVC-Integration-Part" rel="nofollow noreferrer">this article</a></strong> to get server-side processing set up with filtering, sorting, and paging and this all works fine.</p>
  
  <p>I used <strong><a href="http://datatables.net/ref#mRender" rel="nofollow noreferrer">mRender</a></strong> to add the buttons in anchor tags, but they do not work. In glimpse I can see my Ajax request returning a 404. The links render and when I hover on them the URL looks good, but glimpse is telling me: </p>
  
  <pre><code>Ajax GET 404 - Not Found - http://localhost/Vendor/Details/1?X-Requested-With=XMLHttpRequest
  </code></pre>
  
  <p>Here is my HTML and code which initializes the DataTable:</p>
  
  <pre><code>&lt;div id="ListContent"&gt;
  &lt;table id="VendorList"&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;&lt;/th&gt;
              &lt;th&gt;Vendor Name&lt;/th&gt;
              &lt;th&gt;Vendor District&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          @* DataTables renders the data here *@
      &lt;/tbody&gt;
  &lt;/table&gt;
  &lt;/div&gt;
  
  &lt;div id="DetailContentWrapper" class="collapsed"&gt;
      &lt;div class="closeLink"&gt;&lt;/div&gt;
      &lt;div id="DetailContent"&gt;
          @* info/edit/delete partial views should load here *@
      &lt;/div&gt;
  &lt;/div&gt;
  
  &lt;script&gt;
  $(document).ready(function () {
      $('#VendorList').dataTable({
          "bServerSide": true,
          "sAjaxSource": '@Url.Action("AjaxHandler")',
          "bProcessing": true,
          "bJQueryUI": true,
          "bAutoWidth": false,
          "sPaginationType": "full_numbers",
          "aoColumns": [
                          {
                              "mData": "VendorId", "bSearchable": false, "sWidth": "90px",
                              "mRender": function( data, type, full) 
                               { 
                                  return '&lt;a class="detailsButton" title="Details" href="/Vendor/Details/' + data + '" data-ajax-update="#DetailContent" data-ajax-mode="replace" data-ajax-method="GET" data-ajax-loading="#progress" data-ajax-begin="ExpandRightColumn" data-ajax="true"&gt; &lt;/a&gt; '
                                       + '&lt;a class="editButton" title="Edit" href="/Vendor/Edit/' + data + '" data-ajax-update="#DetailContent" data-ajax-mode="replace" data-ajax-method="GET" data-ajax-loading="#progress" data-ajax-begin="ExpandRightColumn" data-ajax="true"&gt; &lt;/a&gt; '
                                       + '&lt;a class="deleteButton" title="Delete" href="/Vendor/Delete/' + data + '" data-ajax-update="#DetailContent" data-ajax-mode="replace" data-ajax-method="GET" data-ajax-loading="#progress" data-ajax-begin="ExpandRightColumn" data-ajax="true"&gt; &lt;/a&gt; ';
  
                               }
                          },
                          { "mData": "VendorName" },
                          { "mData": "VendorDistrict" }
                      ]
          });
      });
  &lt;/script&gt;
  </code></pre>
  
  <p>The Ajax ActionLink I'm trying to reproduce looks like this:</p>
  
  <pre><code>@Ajax.ActionLink(" ", "Details", new { id = item.VendorId }, new AjaxOptions()
                                         {
                                             UpdateTargetId = "DetailContent",
                                             InsertionMode = InsertionMode.Replace,
                                             HttpMethod = "GET",
                                             LoadingElementId = "progress",
                                             OnBegin = "ExpandRightColumn"
                                         }, new { @class = "detailsButton", title="Details" })
  </code></pre>
  
  <p>The resulting HTML from the above ActionLink is this:</p>
  
  <pre><code>&lt;a class="detailsButton" title="Details" href="/VendorMap/Details/1" data-ajax-update="#DetailContent" data-ajax-mode="replace" data-ajax-method="GET" data-ajax-loading="#progress" data-ajax-begin="ExpandRightColumn" data-ajax="true"&gt; &lt;/a&gt;
  </code></pre>
  
  <p>which is why that is what I'm using in mRender, but even though the resulting HTML is identical, the non-ajax link in mRender is not wired the same with MVC, and is therefore throwing the 404.</p>
  
  <p>I even tried to pass to mRender:</p>
  
  <pre><code>return '@@Ajax.ActionLink(" ", "Details", new { id = ' + data + ' }, new AjaxOptions() { UpdateTargetId = "DetailContent", InsertionMode = InsertionMode.Replace, HttpMethod = "GET", LoadingElementId = "progress", OnBegin = "ExpandRightColumn" }, new { @@class = "detailsButton", title="Details" })';
  </code></pre>
  
  <p>but, as expected, it simply displayed that chunk as text in the first column.</p>
  
  <p>Basically, I need to somehow wire my anchor tag to act like an Ajax Actionlink. Sorry if I haven't been clear, let me know if there is any more information I can provide.</p>
  
  <hr>
  
  <p>I've made some progress, but am stuck again. I'm pretty sure it's impossible to render an Ajax Actionlink using jQuery, but what I can do is call an action method and render the resulting partial view. I have updated my mRender value to:</p>
  
  <pre><code>"mRender": function( data, type, full) 
                               { 
                                  return '&lt;a class="detailsButton" title="Details" id="details' + data + '" onClick="showDetails(' + data + ');"&gt; &lt;/a&gt;'
                                       + '&lt;a class="editButton" title="Edit" id="edit' + data + '" onClick="showEdit(' + data + ');"&gt; &lt;/a&gt;'
                                       + '&lt;a class="deleteButton" title="Delete" id="delete' + data + '" onClick="showDelete(' + data + ');"&gt; &lt;/a&gt;';
                               }
  </code></pre>
  
  <p>Then I have implemented the following functions:</p>
  
  <pre><code>function showDetails(id) {
      ExpandRightColumn()
      $.get('@@Url.Action("Details", "Vendor", new { id = "' + id + '"} )', function (data) {
          $('#DetailContent').html(data);
      });
  }
  function showEdit(id) {
      ExpandRightColumn()
      $.get('@@Url.Action("Edit", "Vendor", new { id = "' + id + '"} )', function (data) {
          $('#DetailContent').html(data);
      });
  }
  function showDelete(id) {
      ExpandRightColumn()
      $.get('@@Url.Action("Delete", "Vendor", new { id = "' + id + '"} )', function (data) {
          $('#DetailContent').html(data);
      });
  }
  </code></pre>
  
  <p>ExpandRightColumn() simply displays the DetailContent div, where the resulting partial view should be rendered. The $.get(Url.Action should go to the Vendor controller, call the Details/Edit/Delete action method, and return the partial view rendered as html. It should then be pasted into the DetailContent div. <a href="https://stackoverflow.com/questions/1570127/render-partial-view-using-jquery-in-asp-net-mvc">Here is the source</a>.</p>
  
  <p>I have tested the Url.Action and it is returning the correct URLs. When I browse to the URLs I get the correct partial view. However, when I try to do the $.get on that URL, the server is returning a 404. Any ideas?</p>