As you have discovered it is not possible to extend the InsertionMode
enum that ActionLink
accepts.
That said, if you re-examine the core problem you're trying to solve that approach shouldn't be necessary.
The only thing Ajax.ActionLink
does is generate an HTML anchor tag. You can create the same tag by substituting the invalid call (using your AppendTo
option):
@Ajax.ActionLink("Append To Table", "GetRowData",
new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.AppendTo,
UpdateTargetId = "myAjaxData",
});
with:
@Html.ActionLink("Append To Table", "GetRowData", null,
new {
data_ajax = "true",
data_ajax_method = "GET",
data_ajax_mode = "appendTo",
data_ajax_update = "myAjaxData"
}
);
This produces the same anchor tag as if you had been able to extend the enums.
As far as the solution goes that is only half the story, because you'd also need to modify the Unobtrusive JavaScript library to handle your new AppendTo
and PrependTo
options (not recommended).
Unobtrusive JavaScript adds click handlers to each anchor tags with data-ajax="true"
attributes. If it detects an invalid InsertionMode
it will default to InsertionMode.Replace
.
One solution, if you particularly want to use Ajax.ActionLink
, is use its standard functionality to update a hidden div, and then call a JS function to append/prepend the data to the table:
Index.cshtml:
@Ajax.ActionLink("Prepend To Table", "GetRowData",
new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "myAjaxData",
OnComplete = "prependToTable('#tableOfDoubles', '#myAjaxData');"
});
@Ajax.ActionLink("Append To Table", "GetRowData",
new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "myAjaxData",
OnComplete = "appendToTable('#tableOfDoubles', '#myAjaxData');"
});
<div id="myAjaxData" style="display:none;">
data will end up here
</div>
<table style="border-spacing: 7px; border-collapse: separate;">
<thead>
<tr>
<th>Number</th>
<th>Number doubled</th>
</tr>
</thead>
<tbody id="tableOfDoubles">
<tr>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
JavaScript:
<script type="text/javascript">
function prependToTable(tableId, dataId) {
try {
var newData = JSON.parse($(dataId).text());
var row = ("<tr><td>" + newData.Number + "</td><td>" + newData.Doubled + "</td></tr>");
$(tableId).prepend(row);
} catch (ex) {
console.error(ex);
}
}
function appendToTable(tableId, dataId) {
try {
var newData = JSON.parse($(dataId).text());
var row = ("<tr><td>" + newData.Number + "</td><td>" + newData.Doubled + "</td></tr>");
$(tableId).append(row);
} catch (ex) {
console.error(ex);
}
}
</script>
Controller:
using System.Web.Mvc;
using System.Web.Script.Serialization;
namespace AjaxActionLink.Models
{
public class MyData
{
public int Number { get; set; }
public int Doubled => Number * 2;
}
}
namespace AjaxActionLink.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public string GetRowData()
{
JavaScriptSerializer js = new JavaScriptSerializer();
// generate demo data
int someNumber = (int)(Session["tableRowValue"] ?? 1);
Session["tableRowValue"] = ++someNumber;
// end of data generation
var newData = new MyData { Number = someNumber };
return js.Serialize(newData);
}
}
}
Having said all that, personally I would just add a onclick
handler to a tag and make an ajax call using jQuery (something like this), using my functions above to add the response to the table.