Trying to load a partial view with Ajax.ActionLink - ajax

After reading a few other posts on here I've got this far with attempting to load a partial view on the click of a link (the text link may actually change to be an image once I get past this proof of concept stage). The problem is I am being directed to the partial view on click instead of it populating a div within the view I am clicking the link on:
The layout:
<script src="#Url.Content("~/scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
The View:
#Ajax.ActionLink("Item 1 Ajax", "Details", "Portfolio", new { name = "test" }, new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "row1Content",
OnComplete = "portfolioItemLoaded"
})
<div id="row1content"></div>
<script type="text/javascript">
function portfolioItemLoaded() {
alert("Done");
}
</script>
The controller:
public class PortfolioController : Controller
{
public ActionResult Details(string name)
{
return PartialView(name);
}
}
The partial (obviously named test.cshtml):
<p>Item 1 test</p>
Have I missed something obvious? It's the first time I have attempted to use AJAX in MVC, so there might be a school boy error or two.
I am planning on having several different Ajax Action Links that call different partial views, hence the reason I am passing the name in to the controller.

Code fixed
Do you wanna try this, you have a better control, if error, etc....
HTML with helper
#Html.ActionLink("Item 1 Ajax", "Details", "Portfolio", Nothing, New With {.Id = "myLink"})
JavaScript
<script type="text/javascript">
$(document).ready(function() {
$('#myLink').click(getIt);
});
function getIt() {
$.ajax({
type: "POST",
url: $(this).attr('href'),
error: function () {
//show error handler
},
success: function (r) {
$('#row1content').html(r);
}
});
return false;
}
</script>

Related

How to show a partial view on click of actionlink in mvc

I have the following two action links on a page:
#Html.ActionLink("User List","list");
#Html.ActionLink("Admin List","admin");
On their click I want to show/hide a partial view using jQuery. Help me with solution for this.
You could use the Ajax.ActionLink helper instead:
#Ajax.ActionLink("User List","list", new AjaxOptions { UpdateTargetId = "someDiv" });
#Ajax.ActionLink("Admin List","admin", new AjaxOptions { UpdateTargetId = "someDiv" });
This assumes that the list and admin actions return partial views:
public ActionResult List()
{
return PartialView();
}
and the result of this partial view will be injected into a DOM element with id="someDiv". Also for this to work don't forget to include the jquery.unobtrusive-ajax.js script to your page
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<div id="test"></div>
#Ajax.ActionLink("User List","list", new AjaxOptions{ UpdateTargetId = "test" });
#Ajax.ActionLink("Admin List","admin", new AjaxOptions{ UpdateTargetId = "test" });

Set div id dyanmically in each item in the loop to be referred in Ajax.ActionLink method?

Do we have better ways to handle it?
#foreach (var item in Model)
{
<div id="divDetail#{#item.CategoryId}"/>
#Ajax.ActionLink(
item.CategoryName,
"GetDetails",
new { id = item.CategoryId },
new AjaxOptions() { UpdateTargetId = string.Format("divDetail{0}", item.CategoryId) })
}
</div>
}
I would use the HTML.ActionLink helper method to generate the link and then use my custom jQuery ajax call to get the data. The advantage of doing this is i have full control so that i can do some manipulation of the response data before showing in the detail div.
I added a CSS class to the link so that i can be more specific (in selection of element) when binding my functionality.
#foreach (var item in Model)
{
<div id='divDetail#(item.ID)'></div>
#Html.ActionLink(item.CategoryName, "GetDetails", new { #id = item.CategoryId}, new {#id= "link-"+item.CategoryId, #class="lnkItem" })
}
and the script is
<script type="text/javascript">
$(function () {
$(".lnkItem").click(function (e) {
e.preventDefault();
var itemId = $(this).attr("id").split("-")[1]
$.get($(this).attr("href"), { id: itemId }, function (data) {
//i am free to do anything here before showing the data !
$("#divDetail" + itemId).html(data);
})
});
});
</script>

Delete a row with ajax in mvc3

I am trying to do a delete with Ajax from a list view and when I press button "Delete (Ajax)" it doesn't enter on the controller method, it generates the error:
The resource cannot be found. Description: HTTP 404. The resource you
are looking for (or one of its dependencies) could have been removed,
had its name changed, or is temporarily unavailable. Please review
the following URL and make sure that it is spelled correctly.
Requested URL: /Idea/DeleteAjax/30
Any ideas?
//controller
[HttpPost]
public ActionResult DeleteAjax(int id)
{
IdeeRepository ideeRepo = new IdeeRepository();
WIKIIDEE idee = new WIKIIDEE();
idee = ideeRepo.GetIdeeByID(id);
ViewModels.AjaxResponseVM ajaxVM;
try
{
ideeRepo.DeleteIdea(idee);
ideeRepo.SaveIdea();
ajaxVM = new ViewModels.AjaxResponseVM(Convert.ToInt32(idee.ID), "Idee eliminato con successo!");
}
catch
{
ajaxVM = new ViewModels.AjaxResponseVM(-1, "Error!");
}
return Json(ajaxVM);
}
// view
#Ajax.ActionLink("Elimina Idea(Ajax)", "DeleteAjax", "Idea", new { id = ViewBag.Ideas[i].ID }, new AjaxOptions { Confirm = "Are you sure!", OnSuccess = "DeleteResponse", HttpMethod = "POST" })
Make sure you are referencing the following files:
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>

tinymce in mvc 3 razor, Ajax.ActionLinks fail after first ajax call

I am using Tinymce inside an asp.net mvc 3 Razor application. An Ajax.ActionLink loads the tinymce editor via a call to a controller action named "GetContent". The GetContent method loads a text file from the file system. All is well. But, after I save the tinymce text via an $.ajax call, the Ajax.ActionLink no longer fires the controller method. In other words, something in the $.ajax post breaks the Ajax.ActionLink on the client so that it no longer calls the GetContent controller action.
Interestingly, the Ajax.ActionLink still loads the tinymce editor, but from the browser cache. In the example below I have 2 links "FileOne" and "FileTwo", which load two different text files. Before I call $.ajax the links load the file from disk. After I call $.ajax the links load the last "FileOne" or "FileTwo" from the browser cache.
This is the view. The $.ajax post occurs inside the tiny_mce_save_click() function, which is wired to the tinymce save button click:
#model TestTinyMCE.Models.HomeModel
#{
ViewBag.Title = "Home Page";
}
#section JavaScript
{
<script src="#Url.Content("~/Scripts/tiny_mce/jquery.tinymce.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
<script type="text/javascript">
$().ready(function () {
init_tiny_mce();
});
function init_tiny_mce() {
$('textarea.tinymce').tinymce({
// Location of TinyMCE script
script_url: '/Scripts/tiny_mce/tiny_mce.js',
//javascript function called when tinymce save button is clicked.
save_onsavecallback: "tiny_mce_save_click",
encoding: "xml",
theme: "advanced",
plugins: "save",
theme_advanced_buttons1: "save",
theme_advanced_toolbar_location: "top"
});
}
function tiny_mce_save_click(tinyMceInstance) {
$.ajax({
type: 'POST',
url: '/Home/SaveContent',
data: $('form').serialize(),
success: function (data, status, xml) {
$('#results').html(data);
},
error: function (xml, status, error) {
$('#results').html(error);
}
});
return false;
}
</script>
}
#using (Html.BeginForm())
{
<ul>
#foreach (string fileName in Model.FileList)
{
<li>#Ajax.ActionLink(fileName, "GetContent", new { FileName = fileName }, new AjaxOptions() { UpdateTargetId = "divContent" })</li>
}
</ul>
<div id="divContent">
#Html.Partial("GetContent", Model)
</div>
}
The partial view "GetContent" is:
#model TestTinyMCE.Models.HomeModel
#{
Layout = null;
}
<div id="divContent">
<fieldset id="fsContent">
<span id="results"></span><legend>Edit Content #Html.DisplayTextFor(m => m.FileName)</legend>
#Html.TextAreaFor(m => m.Content,
new Dictionary<string, object>{
{"class","tinymce"}, {"cols","80"}, {"rows","10"}}
)
#Html.HiddenFor(m => m.FileName)
</fieldset>
#if (#IsAjax)
{
<text>
<script type="text/javascript">init_tiny_mce();</script>
</text>
}
</div>
This is the controller. The GetContent method no longer gets called after the $.ajax post occurs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TestTinyMCE.Models;
namespace TestTinyMCE.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new HomeModel());
}
public ActionResult GetContent(HomeModel homeModel)
{
if (!string.IsNullOrEmpty(homeModel.FileName))
{
string path = string.Format("~/App_Data/{0}.htm", homeModel.FileName);
string physicalPath = Server.MapPath(path);
if (!System.IO.File.Exists(physicalPath))
homeModel.Content = string.Format("The file '{0}' does not exist.", physicalPath);
else
homeModel.Content = System.IO.File.ReadAllText(physicalPath);
}
return View(homeModel);
}
[HttpPost]
[ValidateInput(false)]
public ActionResult SaveContent(HomeModel homeModel)
{
string path = string.Format("~/App_Data/{0}.htm", homeModel.FileName);
string physicalPath = Server.MapPath(path);
System.IO.File.WriteAllText(physicalPath, homeModel.Content);
ViewBag.Result = "The file was successfully saved.";
return View();
}
}
}
The problem is broswer caching. To prevent caching on the Ajax.ActionLink you must add AjaxOption HttpMethod = "POST". In the above code change ActionLink to
<li>#Ajax.ActionLink(fileName, "GetContent", new { FileName = fileName }, new AjaxOptions() { UpdateTargetId = "divContent", HttpMethod = "POST" })</li>.
See http://forums.asp.net/t/1681358.aspx?Disable+cache+in+Ajax+ActionLink+extension+method+in+asp+net+MVC

"UpdatePanel" in Razor (mvc 3)

Is there something like UpdatePanel (in ASPX) for Razor?
I want to refresh data (e.g. table, chart, ...) automaticly every 30 seconds.
Similar to clicking the following link every 30 seconds:
#Ajax.ActionLink("Refresh", "RefreshItems", new AjaxOptions() {
UpdateTargetId = "ItemList",
HttpMethod = "Post"})
Edit:
I may should add that the action link renders a partial view.
Code in cshtml:
<div id="ItemList">
#Html.Partial("_ItemList", Model)
</div>
Code in Controller:
[HttpPost]
public ActionResult RefreshItems() {
try {
// Fill List/Model
...
// Return Partial
return PartialView("_ItemList", model);
}
catch (Exception ex) {
return RedirectToAction("Index");
}
}
It would be create if the PartielView could refresh itself.
You can try something similar to the following using Jquery (have not tested though)
<script type="text/javascript">
$(document).ready(function() {
setInterval(function()
{
// not sure what the controller name is
$.post('<%= Url.Action("Refresh", "RefreshItems") %>', function(data) {
// Update the ItemList html element
$('#ItemList').html(data);
});
}
, 30000);
});
</script>
The above code should be placed in the containing page i.e. not the partial view page. Bear in mind that the a partial view is not a complete html page.
My initial guess is that this script can be placed in the partial and modified as follows. Make sure that the ajax data type is set to html.
<script type="text/javascript">
setInterval(function()
{
// not sure what the controller name is
$.post('<%= Url.Action("Refresh", "RefreshItems") %>', function(data) {
// Update the ItemList html element
$('#ItemList').html(data);
});
}
, 30000);
</script>
Another alternative is to store the javascript in a separate js file and use the Jquery getScript function in ajax success callback.
Well, if you don't need the AJAX expierience than use the HTML tag:
<meta http-equiv=”refresh” content=”30; URL=http://www.programmingfacts.com”>
go here: http://www.programmingfacts.com/auto-refresh-page-after-few-seconds-using-javascript/
If someone wants the complete code for a selfupdating partial view have a look!
Code of the Controller:
[HttpPost]
public ActionResult RefreshSelfUpdatingPartial() {
// Setting the Models Content
// ...
return PartialView("_SelfUpdatingPartial", model);
}
Code of the Partial (_SelfUpdatingPartial.cshtml):
#model YourModelClass
<script type="text/javascript">
setInterval(function () {
$.post('#Url.Action("RefreshSelfUpdatingPartial")', function (data) {
$('#SelfUpdatingPartialDiv').html(data);
}
);
}, 20000);
</script>
// Div
<div id="SelfUpdatingPartialDiv">
// Link to Refresh per Click
<p>
#Ajax.ActionLink("Aktualisieren", "RefreshFlatschels", new AjaxOptions() {
UpdateTargetId = "FlatschelList",
HttpMethod = "Post", InsertionMode = InsertionMode.Replace
})
</p>
// Your Code
// ...
</div>
Code to integrate the Partial in the "Main"-View (ViewWithSelfupdatingPartial.cs):
#Html.Partial("_FlatschelOverview", Model)
The <meta refresh ..> tag in HTML will work for you. Its the best option
Traditional controls don't works in ASP MVC
You could do it using Jquery timers http://plugins.jquery.com/project/timers
Other option could be to use the Delay function
In your target is as simple as refresh the whole page, this SO link will be of your interest: Auto refresh in ASP.NET MVC
Hope It Helps.

Resources