View not refreshing after AJAX post - asp.net-mvc

I have a view (Index.cshtml) with a grid (Infragistics JQuery grid) with an imagelink. If a user clicks on this link the following jquery function will be called:
function ConfirmSettingEnddateRemarkToYesterday(remarkID) {
//Some code...
//Call to action.
$.post("Home/SetEnddateRemarkToYesterday", { remarkID: remarkID }, function (result) {
//alert('Succes: ' + remarkID);
//window.location.reload();
//$('#remarksgrid').html(result);
});
}
Commented out you can see an alert for myself and 2 attempts to refresh the view. The location.reload() works, but is basically too much work for the browser. The .html(result) posts the entire index.cshtml + Layout.cshtml double in the remarksgrid div. So that is not correct.
This is the action it calls (SetEnddateRemarkToYesterday):
public ActionResult SetEnddateRemarkToYesterday(int remarkID) {
//Some logic to persist the change to DB.
return RedirectToAction("Index");
}
This is the action it redirects to:
[HttpGet]
public ActionResult Index() {
//Some code to retrieve updated remarks.
//Remarks is pseudo for List<Of Remark>
return View(Remarks);
}
If I don't do window.location.reload after the succesfull AJAX post the view will never reload. I'm new to MVC, but i'm sure there's a better way to do this. I'm not understanding something fundamental here. Perhaps a nudge in the right direction? Thank you in advance.

As you requesting AJAX call, you should redirect using its response
Modify your controller to return JSONResult with landing url:
public ActionResult SetEnddateRemarkToYesterday(int remarkID) {
//Some logic to persist the change to DB.
var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index", "Controller");
return Json(new { Url = redirectUrl });
}
JS Call:
$.post("Home/SetEnddateRemarkToYesterday", { remarkID: remarkID }, function (result) {
window.location.href = result.Url
});

After Ajax post you need to call to specific Url..
like this..
window.location.href = Url

When using jQuery.post the new page is returned via the .done method
jQuery
jQuery.post("Controller/Action", { d1: "test", d2: "test" })
.done(function (data) {
jQuery('#reload').html(data);
});
HTML
<body id="reload">

For me this works. First, I created id="reload" in my form and then using the solution provided by Colin and using Ajax sent data to controller and refreshed my form.
That looks my controller:
[Authorize(Roles = "User")]
[HttpGet]
public IActionResult Action()
{
var model = _service.Get()...;
return View(model);
}
[Authorize(Roles = "User")]
[HttpPost]
public IActionResult Action(object someData)
{
var model = _service.Get()...;
return View(model);
}
View:
<form id="reload" asp-action="Action" asp-controller="Controller" method="post">
.
.
.
</form>
Javascript function and inside this function I added this block:
$.ajax({
url: "/Controller/Action",
type: 'POST',
data: {
__RequestVerificationToken: token, // if you are using identity User
someData: someData
},
success: function (data) {
console.log("Success")
console.log(data);
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(data, 'text/html'); // parse result (type string format HTML)
console.log(htmlDoc);
var form = htmlDoc.getElementById('reload'); // get my form to refresh
console.log(form);
jQuery('#reload').html(form); // refresh form
},
error: function (error) {
console.log("error is " + error);
}
});

Related

Return RedirectToAction does not return new View

I have a method which return an action to a different controller. I am using return RedirectToAction and passing a parameter with it. The parameter successfully passed to the other controller. But it does not return any view. The page should load and return a new view. Here is my code:
Controller 1:
public ActionResult Work(int id, int staffId)
{
return RedirectToAction("CreateStaffWork", "Staff", new { id = staffId});
}
Controller 2 (Staff):
public ActionResult CreateStaffWork(int id)
{
Staff staffInfo= db.Staff.Find(id);
StaffInputModel newStaffWork = new StaffInputModel { StaffId = staffInfo.Id };
return View(newStaffWork);
}
It should return CreateStaffWork view, but the page does not reload. There is no error while running the code. What should I do for the view to return?
I submit the form using ajax request:
<script type="text/javascript">
$(document).ready(function () {
$("#LoadStaffListTable tbody").on('click', '.select', function (e) {
e.preventDefault();
$.ajax({
url: '/StaffWork/Work',
type: 'POST',
data: { id: $(this).data('id'), staffId: $(this).data('staffId') },
dataType: 'json',
}); // end ajax
});
});
As mentioned in the comments, the purpose of ajax is to stay in the same page. If you're redirecting to a new page, you simply redirect to the Work action methods with proper parameters.
Change your click event handler to:
$("#LoadStaffListTable tbody").on('click', '.select', function(e) {
location.href = '#Url.Action("Work", "StaffWork")?id=' + $(this).data('id') + '&staffId=' + $(this).data('staffId');
});

mvc display text after post and keep data in form

How can I after posting a form in my mvc page display a message and keeping the added/selected data in the form? I have tried to render a partialview but that renders a blank page which only contains the actual partialview.
<div id="resultTarget">
#Html.Partial("CalculationResult", new Model.CalculatedPrice())
</div>
[HttpPost]
public PartialViewResult GetPrice(FormCollection formCollection)
{
// This renders only the partialview
return PartialView("CalculationResult", model);
}
If you reload the page with a form post the data will be lost. Create a view model and bind the controls to specific properties using #Html.TextBoxFor(), #Html.ListBoxFor() etc.
Now instead of submitting the form back to the controller, use javascript to post data back to the controller on a button click function.
See below code :
In Button Click function :
var modelObj = {};
modelObj.prop1 = $('#txtField1').val();
modelObj.prop2 = $('#txtField2').val();
var postObj = JSON.stringify(modelObj); // convert object to json
$.ajax({
type: "POST",
traditional: true,
dataType: "json",
url: "/SomeController/GetPrice",
data: { formCollection: postObj }
cache: false,
success: function (data) {
if (data) {
//Some Code if post success
}
else {
// Some code if post failed
}
}});
In SomeController :
[HttpPost]
public JSonResult GetPrice(FormCollection formCollection)
{
// Do your action with the formCollection object here
// if(action.success)
{
return JSon(true);
}
return JSon(false);
}
This way you can prevent reloading of the page and keep the data in the forms as such.

ASP.NET MVC View (Razor) Working With Forms Checking Values

I have the standard ASP.NET MVC version installed with Visual Studio.
In thew view I have a companyname textbox which is using
#Html.EditorFor(model => model.CompanyName, new { htmlAttributes = new { #class = "form-control" } })
What I would like to do is grab the text box value and then call a function to save the value to another table. I also only want this to fire if the value has changed.
I hope that's enough information.
The type of scenario you're after is best handled in the controller action that handles the POST request when your form gets submitted. For example, assuming you are using Entity Framework to save to the database:
[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditPost(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var companyToUpdate = db.Companies.Find(id);
if (TryUpdateModel(companyToUpdate, "",
new string[] { "Name" }))
{
try
{
db.Entry(companyToUpdate).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
catch (SomeException ex)
{
//Can also log the error
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
}
return View(companyToUpdate);
}
Please note that the POST request can also be sent by javascript.
For more information about this, please have a look at the asp.net website.
As far as i have understood, you can do something like this:
<script>
$(document).ready(function(){
$("#CompanyName").change(function(){
var textValue= $(this).val();
//Call your function here: YourFunction(textValue);
$.ajax({
type: 'GET',
url: 'ControllerName/ActionMethodName',
data: {textValue: textValue}, //Keep the same parameter name in C# function
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(result)
{
// To do on successful ajax call
},
error: function(x,y,z)
{
alert("Ajax Error!");
}
});
});
});
</script>
In C#, you can write something like:
public class ControllerNameController : Controller
{
public JsonResult ActionMethodName(string textValue)
{
// To do your job here
return Json("succesful", JsonRequestBehavior.AllowGet);
}
}
You can check it in jSFiddle here

Using MVC4 how can you submit the [HttpPost] action without a submit button?

Typically I would create a submit button to post data, but in this case I want the [HttpPost] action to post on page load. This page is collecting data from other sources and there is no need for the user to hit submit.
simply use ajax call, imagine that a get action returns the list of tags like this:
public ActionResult Index()
{
var tags = _tagRepository.GetAllTag();
return View(tags);
}
now in the view of index you have all tags, and also want to add the remove capability, now you can do this by ajax call:
#model IList<Blog.Domain.Model.Tag>
//list of tags here
<script type="text/javascript">
$(function () {
$(".delete").click(function (e) {
e.preventDefault();
var link = this.href;
$.ajax({
type: 'Post',
url: link,
success: function (data) { }
});
});
});
</script>
and about the post action:
[HttpPost]
public JsonResult Delete(int tagId)
{
if (ModelState.IsValid)
{
_tagRepository.RemoveTag(tagId);
_tagRepository.Save();
RedirectToAction("Index");
}
return Json("");
}
If you don't want to use AJAX, you can simply submit the form with jQuery:
$('form').submit();

$.post() not working if the mvc model view controller has a parameter

I´m new with MVC. I´m using MVC4.
I'm having an issue with a callback. If I alert before and after the post() call both alerts show but the call doesn't fire.
[HttpGet]
[Authorize]
public ActionResult Dashboard(int Menu)
{
//some code
return View("Dashboard");
}
<script>
$(document).ready(function () {
$.post("../Client/GetFact", {},
function (data) {
//some code
});
});
</script>
[HttpPost]
[Authorize]
public JsonResult GetFact()
{
//some code to fill object_data
var data = object_data;
return Json(data);
}
As long as I leave ActionResult Dashboard without a parameter is works. If I add a parameter to Dashboard(int Menu) then the call back to GetFact doesn't work.
I searched and found a similar post and follow the instructions given by you guys, but still does not work( looked at: getJSON not working if the mvc model view controller has a parameter).
I do not know what I'm doing wrong. Can you help? Thank's!
I do something similar with $.get, using jquery with the #Url.Action instead of the url.
in addition to using the FormContext to pass to my Action :
Place just before #using (Html.BeginForm())
#{ ViewContext.FormContext = new FormContext(); }
example :
$.get('#Url.Action("ActionName", "ControllerName")', { IDName: $('#IdName').val() }, function (data) {
//Do Something here with the data
});
I would imagine form post would be
$.post('#Url.Ation("ActionName", "ControllerName")', function (data) {
//Do Something here with the data
});
This is a shorthand Ajax function, which is equivalent to:
$.ajax({ type: "POST",
url: url,
data: data,
success: success,// -> call alert here
dataType: dataType});

Resources