I am doing a web application using ASP.NET MVC 5. It seems to me that I did everything as it goes, but ajax is just not working. I see results only after refreshing.
This is in my View:
#{
AjaxOptions ajaxOptions = new AjaxOptions {
UpdateTargetId = "CommmentList",
HttpMethod = "Post",
InsertionMode = InsertionMode.Replace};
}
<div id="CommentList">
#using (Ajax.BeginForm("Index", "Comment", ajaxOptions))
{
// some content
<div>
#Html.Action("_AddCommentForItem", "Comment")
</div>
}
</div>
This is in a layout view:
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.8.0.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/mvc/3.0/jquery.unobtrusive-ajax.js" type="text/javascript"></script>
EDIT:
These are actions in a Comment controller:
// GET: Comment
public async Task<ActionResult> Index()
{
var comments = db.Comments.Include(k => k.Item);
return View(await comments.ToListAsync());
}
// GET
public PartialViewResult _AddCommentForItem()
{
ViewBag.ItemId = new SelectList(db.Items, "Id", "Name");
return PartialView("_AddCommentForItem");
}
// POST
[HttpPost]
public PartialViewResult _AddCommentForItem ([Bind(Include = "Id,ItemId,CommentContent")] Comment comment)
{
if (ModelState.IsValid)
{
db.Comments.Add(commment);
db.SaveChanges();
}
ViewBag.ItemId = new SelectList(db.Items, "Id", "Name", comment.ItemId);
return PartialView("_AddCommentForItem");
}
}
}
I included partial view _AddCommentForItem, which is creating a comment, in an index view of the Comment controller. That's way i want the result to be visible right away, without refreshing.
What am I missing?
Thank you.
Related
I am trying to load a div data using ajax rather than whole view on post method.
but it returns object%20HTMLInputElement action name on post action.
Controller:
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(DemoCLass objdemo)
{
return View();
}
View
<div id="divEmp">
#using (Ajax.BeginForm("Index", "Challan", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "divEmp" }))
{
#Html.AntiForgeryToken()
<h3 style="text-align:center;" class="row header">Challan Data</h3>
#Html.Partial("_DateCommonFT")
}
It includes _Layout.cshtml where i have defined scripts as:
<script src="~/Scripts/jquery-1.12.4.min.js"></script>
<script src="~/Scripts/jquery-ui-1.12.1.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
How to render only post action without loading whole page (_layout.cshtml) on post request using ajax.
Can you try to close your div tag and receive HtmlForgeryToken in controller like following.
you can also fill your target div with PartialView by returning PartialView() in Index method
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(DemoCLass objdemo)
{
return PartialView();
}
<div id="divEmp">
</div>
#using (Ajax.BeginForm("Index", "Challan", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "divEmp" }))
{
#Html.AntiForgeryToken()
<h3 style="text-align:center;" class="row header">Challan Data</h3>
#Html.Partial("_DateCommonFT")
}
please Ajax.Begin form you can use OnSuccess method.
In VIew:-
#using (Ajax.BeginForm("Index", "Challan", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "divEmp", OnSuccess = "AjaxForm" }))
{
}
In Script:-
here return json from post controller.
function AjaxForm(response){
.....do as uou want...
}
in Controller:-
[HttpPost]
public ActionResult Index(DemoCLass objdemo)
{
return json(new {IsSuccess = true},JsonRequestBehavior.AllowGet);
}
if you have any query in this one then tell to me
Use the PartialView method to return a view without the layout.
[HttpPost]
public ActionResult Index(DemoCLass objdemo)
{
return PartialView();
}
If you want to return the html without layout markup only for the ajax form submissions, you can check the request headers to see whether the request is an xhr request or not. Request.IsAjaxRequest() method will be handy here.
[HttpPost]
public ActionResult Index(DemoCLass objdemo)
{
if (Request.IsAjaxRequest())
{
return PartialView();
}
else
{
return View();
}
}
Currently we have a page where you select some parameters and click on a button to load data and display it in a grid, but there is no functionality to display the data on page load (via url parameters) yet. I've added the necessary routing configurations and Action, but I'm having troubles to render the page, it only displays the PartialView without styles.
How can I get the whole page to render and not just the PartialView?
Below is my simplyfied code for the View and Controller.
Views/Planing/Index.cshtml
#model PlaningTool.Web.Models.PlaningViewModel
<div class="row">
<div>
#using (Ajax.BeginForm("GetDataRows",
"Planing",
new AjaxOptions
{
HttpMethod = "Get",
UpdateTargetId = "gridPlaceholder",
LoadingElementId = "loadingIndicator"
}))
{
<!-- some comboboxes to select project and year -->
<input type="submit" value="Load data" />
}
</div>
</div>
<div id="gridPlaceholder">
<div id="loadingIndicator" style="display: none;">
<img src="~/Content/images/loading-image.gif" />
</div>
</div>
Controllers/PlaningController.cs
public partial class PlaningController : Controller
{
public virtual ActionResult Index()
{
return View();
}
public virtual ActionResult Plan(long projectID, int year)
{
var viewModel = new PlaningViewModel
{
ProjectID = projectID,
Year = year
};
// return GetDataRows(viewModel);
return RedirectToAction("GetDataRows", viewModel);
}
[RestoreModelStateFromTempData(typeof(PartialViewResult))]
public virtual PartialViewResult GetDataRows(PlaningViewModel viewModel)
{
// Load data from database with viewModel.ProjectID
// and viewModel.Year as parameters
[...]
var vm = new PlaningViewModel
{
// Set ViewModel for loaded data
[...]
};
return PartialView("Shared/_PlaningViewModelRows", vm);
}
[...]
}
I finally found a solution. I'm pretty sure it's not the best way to do this but it works.
If the Model is already set I render the PartialView.
<div id="gridPlaceholder">
#{
if (Model != null)
{
Html.RenderPartial("Shared/_PDataViewModelRows", Model);
}
}
<div id="loadingIndicator" style="display: none;">
<img src="~/Content/kendo/Bootstrap/loading-image.gif"/>
</div>
</div>
And in my Controller I've changed to this, so my ViewModel gets loaded independently and I simply return the same view as I would for Index with the new ViewModel.
public virtual ActionResult Plan(long projectID, int year)
{
var viewModel = new PlaningViewModel
{
ProjectID = projectID,
Year = year
};
return View("Index", LoadViewModel(viewModel));
}
public PlaningViewModel LoadViewModel(PlaningViewModel viewModel)
{
// Load data from database with viewModel.ProjectID
// and viewModel.Year as parameters
[...]
var vm = new PlaningViewModel
{
// Set ViewModel for loaded data
[...]
};
return vm;
}
I have a simple controller and view:
I just want the Index.cshtml view page to be reloaded with new data.I have debugged the code thoroughly. Infact, clicking on the "ul" when the control goes to the Index(string value) method the model object is populated with new data and even in the cshtml page the Model is showing the new list in the debugger, but the view is NOT getting refreshed. I really don't know why.. Can anyone help me plz?
If I have gone wrong horribly somewhere please excuse my ignorance as I am new to MVC.
Thanks in advance...
Controller:
namespace MVCTestApp1.Controllers
{
public class TestController : Controller
{
//
// GET: /Test/
public ActionResult Index()
{
ModelState.Clear();
List<string> ll = new List<string>();
ll.Add("qq");
ll.Add("aa");
ll.Add("zz");
return View(ll);
}
[HttpPost]
public ActionResult Index(string value)
{
ModelState.Clear();
List<string> ll = new List<string>();
ll.Add("kkk");
ll.Add("qq");
ll.Add("aa");
ll.Add("zz");
return View(ll);
}
}
}
View:
#model IEnumerable<string>
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<h2>Index</h2>
<ul id="bb">
#foreach (var i in Model)
{
<li>#Html.DisplayFor(ir=>i)</li>
}
</ul>
}
I suppose that you wrote some javascript code so that when the user clicks on a <li> element of the <ul> you are triggering an AJAX call to the [HttpPost] action sending the selected value to the server. The problem with your code might be that you probably forgot to update the DOM with the new contents in your success callback. So for this to work you could start by placing the <ul> contents in a partial view:
List.cshtml:
#model IEnumerable<string>
#foreach (var i in Model)
{
<li>#Html.DisplayFor(ir=>i)</li>
}
and then include this partial in the main view:
#model IEnumerable<string>
#{
ViewBag.Title = "Index";
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<h2>Index</h2>
<ul id="bb">
#Html.Partial("_List", Model)
</ul>
}
OK, now in your POST action you could return the partial:
[HttpPost]
public ActionResult Index(string value)
{
List<string> ll = new List<string>();
ll.Add("kkk");
ll.Add("qq");
ll.Add("aa");
ll.Add("zz");
return PartialView("_List", ll);
}
and the final bit is the javascript code:
$(function() {
$('#bb').on('click', 'li', function() {
var value = $(this).html();
$.ajax({
url: $(this).closest('form').attr('action'),
type: 'POST',
data: { value: value },
success: function(partialView) {
$('#bb').html(partialView);
}
});
});
});
so Iam new on this and I have a Ajax.ActionLink that work fine but can't understand (why I have to put the div "linkEdit" in my list view and in the partial view)
so have Ajax.ActionLink in my list view of solution (and when select a solution it get me all the product) and it goes to a action to
[HttpGet]
[Ajax(true)]
[ActionName("Index")]
public ActionResult Index_Ajax(Int32? id)
{
// to do = load the product that solution have
return PartialView("SolutionProduct", viewModel);
}
the Ajax.ActionLink
#Ajax.ActionLink("Select", "Index", "solution",
new { id = item.solutionId },
new AjaxOptions
{
HttpMethod = "GET",
UpdateTargetId = "linkEdit",
InsertionMode = InsertionMode.Replace
})|
i have this div in a partial view "SolutionProduct" and in my list view
<div id="linkEdit">
<table>
<tr>
<th>Nombre de Producto</th>
</tr>
#foreach (var item in Model.Productos)
{
<tr >
<td>
#item.Nombre
</td>
</tr>
}
</table>
}
</div>
so my question would be why if I take out the div on my list view it doesnt work?
I am going to share here different examples of using AJAX in ASP .NET MVC 4.
1) Use an Internet Application template to create ASP .NET MVC 4 project in Visual Studio 2012.
2) Under the folder Models create this simple class
public class Person
{
public string FirstName { set; get; }
}
3) Add following code to public class HomeController : Controller
[AcceptVerbs("POST")]
public bool MethodWithoutParameters()
{
bool allow = true;
if (allow)
{
return true;
}
else
{
return false;
}
}
[AcceptVerbs("POST")]
public string MethodWithParameters(string id)
{
return id + " i got it, man! ";
}
[AcceptVerbs("GET")]
public ActionResult GetSomeName()
{
var data = new { name = "TestName " };
return Json(data, JsonRequestBehavior.AllowGet);
}
[AcceptVerbs("POST")]
public ActionResult PerformAction(FormCollection formCollection, Person model)
{
model.FirstName += "Well done! Form 1";
return Json( model.FirstName);
}
[AcceptVerbs("POST")]
public ActionResult PerformAction2(FormCollection formCollection, Person model)
{
model.FirstName += "Well don! Form 2";
return Json(model.FirstName);
}
public JsonResult DeleteFile(string fileName)
{
var result = fileName + " has been deleted";
return Json(result, JsonRequestBehavior.AllowGet);
}
4) Replace all code within Index.cshtml with the following one (Perhaps, instead of MvcApplication1 you have to use your real application name...)
#model MvcApplication1.Models.Person
#{
ViewBag.Title = "Home Page"; } #section featured {
}
MethodWithoutParameters
MethodWithParameters
'parameter00001'
#using (Ajax.BeginForm("PerformAction", "Home", new AjaxOptions {
InsertionMode = InsertionMode.Replace, HttpMethod = "POST", OnSuccess
= "OnSuccess", OnFailure = "OnFailure" })) {
This is a demo form1.
#Html.LabelFor(model => model.FirstName)
#Html.TextBoxFor(model => model.FirstName, null, new { #class = "labelItem" })
}
#using (Ajax.BeginForm("PerformAction2", "Home", new AjaxOptions {
InsertionMode = InsertionMode.Replace, HttpMethod = "POST", OnSuccess
= "OnSuccess2", OnFailure = "OnFailure2" })) {
This is a demo form2.
#Html.LabelFor(model => model.FirstName)
#Html.TextBoxFor(model => model.FirstName, null, new { #class = "labelItem" })
}
cat.png
Delete File
function DeleteFile() {
var fn = $('#fileNameLabel').html();
$.ajax({
url: "Home/DeleteFile", //check this.href in debugger
dataType: "text json",
type: "POST",
data: { fileName: fn }, //pass argument here
success: function (data, textStatus) {
if (data) {
if (textStatus == 'success') {
$('#fileNameLabel').html(data);
$('#btnDeleteFile').hide();
}
else {
alert('error');
}
} else {
alert('error');
}
}
});
}
function OnSuccess(response) {
$('#form1').html(response);
}
function OnFailure2(response) {
alert("Error Form 2");
}
function OnSuccess2(response) {
$('#form2').html(response);
}
function OnFailure(response) {
alert("Error Form 1");
}
function MethodWithoutParameters() {
var url = "Home/MethodWithoutParameters";
$.post(url, function (data) {
if (data) {
alert(data);
} else {
alert('error');
}
});
}
function MethodWithParameters(id) {
var url = "Home/MethodWithParameters/" + id;
// alert(url);
$.post(url, function (data) {
if (data) {
alert(data);
} else {
alert('error');
}
});
}
$(document).ready(function () {
$.getJSON("Home/GetSomeName",
null,
function (data) {
if (data) {
$('#UserNameLabel').html(data.name);
} else {
alert('error');
}
}
);
}); </script>
5) Make sure that header of the _Layout.cshtml looks like
<meta charset="utf-8" />
<title>#ViewBag.Title - My ASP.NET MVC Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"
type="text/javascript">
6) And everything should work fine.
I hope all those samples will help you!
You have to put the div with an id of "linkEdit" into your list view as that is the portion of the page that is to be replaced by the result returned by the ajax link.
ASP.NET AJAX enables a Web application to retrieve data from the server asynchronously and to update parts of the existing page. This improves the user experience by making the Web application more responsive.
And is this case you are using the InsertionMode
InsertionMode = InsertionMode.Replace
so you will need a div with the id of "linkEdit" in both your list view and partial view.
First off, I am an ASP.NET MVC noob. It's my first project with ASP.NET MVC, so I am still learning. My background is mostly in WPF and XAML for the past two years.
So here is my problem: I have three cascading ListBoxes. The second listbox data is dependent on the first, and the third is dependent on the second. I want to use Ajax refreshes to fill the data in each list.
Here is my Index.cshtml:
#model WebApplication.Models.DevelopmentModel
<!DOCTYPE html>
<html>
<head>
<title>Dashboard</title>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>
</head>
<body class="body" scroll="auto">
<div class="page">
<div class="content">
<div id="lists">
#Html.Partial("DevelopmentListsView", Model)
</div>
</div>
</div>
</body>
</html>
My DevelopmentListsView.cshtml looks like this:
#model WebApplication.Models.DevelopmentModel
#using (Ajax.BeginForm("Index", "Development", new AjaxOptions() { UpdateTargetId = "lists" } ))
{
#Html.ListBoxFor(m => m.SelectedApplication, new SelectList(ViewBag.Applications), new { onchange = "this.form.submit();" })
#Html.ListBoxFor(m => m.SelectedVersion, new SelectList(ViewBag.Versions), new { onchange = "this.form.submit();" })
#Html.ListBoxFor(m => m.SelectedFlow, new SelectList(ViewBag.Flows) )
}
My Model looks like:
public class DevelopmentModel
{
public string SelectedApplication { get; set; }
public string SelectedVersion { get; set; }
public string SelectedFlow { get; set; }
}
And my Controller looks like this:
public class DevelopmentController : Controller
{
//
// GET: /Development/
public ActionResult Index()
{
FillViewBag();
return View(new DevelopmentModel());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(DevelopmentModel model)
{
FillViewBag(model);
return PartialView("DevelopmentListsView", model);
}
private void FillViewBag(DevelopmentModel model = null)
{
//Magic to get all three lists dependent on the available data in the model:
ViewBag.Applications = applications;
ViewBag.Versions = versions;
ViewBag.Flows = flows;
}
}
Now, I want to use Ajax callbacks to retrieve the data, so it won't refresh every time, but when I click one of the Listbox items, the page then only shows the DevelopmentListsView view after that, not refreshing anything..
Can someone tell me what I am doing wrong?
Thanks for looking!
Figured out my own question:
I had two errors:
I missed the jquery script include in the Index.cshtml:
<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>
And I used the wrong submit (it should have been the jQuery submit):
$(this.form).submit()
The submit placed inside my models
#model WebApplication.Models.DevelopmentModel
#using (Ajax.BeginForm("Index", "Development", new AjaxOptions() { UpdateTargetId = "lists" } ))
{
#Html.ListBoxFor(m => m.SelectedApplication, new SelectList(ViewBag.Applications), new { onchange = "$(this.form).submit()" })
#Html.ListBoxFor(m => m.SelectedVersion, new SelectList(ViewBag.Versions), new { onchange = "$(this.form).submit()" })
#Html.ListBoxFor(m => m.SelectedFlow, new SelectList(ViewBag.Flows) )
}
Hope this helps someone some day ;).