MVC 5 PartialView update with AJAX not updating View? - javascript

I'm in the process of getting my head wrapped around using AJAX to update a portion of an MVC View using some conditional logic. I posted the question earlier and was pointed to using PartialView to build out the whole HTML table and then pass that back to the View.
That lead me to use this article and an example.
https://www.red-gate.com/simple-talk/dotnet/asp-net/revisiting-partial-view-rendering-in-asp-net-mvc/
I then pulled out my table code and put it in a Partial View. All that worked just fine. However, now I'm trying to update with AJAX and the actual updating of the database is working but the updating of the View is not.
In other words, when I click on the "Test" button in the code below I can see it going to the HttpPost in the controller as well as seeing the database being updated. However, the page doesn't get updated. I have to refresh the page again to see the change.
I'm betting it has to do with the #Html.Partial call in the View but I'm not figuring out what I need to do to fix it.
From what I've read it sounds as though when I make the AJAX call and it returns the HTML it should replace everything in side of my DIV.
Here is what I have in my View. Upon initially viewing the page the #Html.Partial is populating the table as expected.
<div id="exceptionTable">
#Html.Partial("_DailyLogExceptionsTable", Model.listExceptions)
</div>
Here is my AJAX call. I can see the values coming through. The RID is the record ID and the arg would be a static value of either "A" or "D" depending on which button they will click.
function ApproveDeny(rid, arg) {
var url = "/Exception/ExceptionApproveDeny/";
$.post(url, {rid:rid, arg:arg})
.done(function (response) {
$("#exceptionTable").html(response);
})
};
This is my ActionResult which updates the database through the DAL. Then I create a new ViewModel, call get the new list of Exceptions, and then call the PartialView again passing it the new list of exceptions.
public ActionResult ExceptionApproveDeny(int rid, string arg, string shift)
{
try
{
DAL.ExceptionApproveDeny(rid, arg);
var vm = new ExceptionLogDailyTableViewModel();
vm.listExceptions = DAL.GetEmployeeExceptionsByDate(CurrentEmployeeId, DateTime.Parse(shift));
return PartialView("_DailyLogExceptionsTable", vm);
}
catch (Exception ex)
{
//error code
}
}

Related

MVC Controller View Javascript and passing values

I have a view that displays both the search screen and the results list. To start the results list is hidden.
On clicking the search button, instead of the view posting back to the controller using a Html.BeginForm, it has a JavaScript event handler which is called.
The Handler passes over a complex object, in the form of:
{ "searchData":
{ "ticketNumberCompare":0,
"ticketSearchTextFrom":"0",
"ticketSearchTextTo":null,
"ticketDateCompare":1,
"startDate":"2017-01-06T00:00:00",
"endDate":"2017-01-13T00:00:00",
...
etc
...
},
"searchMode":
{ "mode":2,
"pageNumber":1,
"pageSize":5,
"sortDirection":"desc",
...
etc
...
"ValidationErrorMessages":null
}
}
By using Json.Stringify, I have got the above structure to be converted for use by a function within the c# MVC 5 controller, defined as follows.
[HttpPost]
public JsonResult GetSearchResultsJson(ComplexObject searchCriteria, int? page)
{
}
This function returns back html which is rendered from a Razor view using a model that contains the results from the database.
When I click on the submit button for the initial search all works and I get a partial view of five records displayed with the correct pageList values displayed.
When I click on the pageList items I get a page not found error.
On checking the ajax call for the initial load it is passing over the Json.Stringify of the structure at the top of this question. But the pageList items are not, they just pass over the page
Addendum:
Oh I forgot to mention that I have upgraded this function to use an object instead of the four string that used to be passed, because a new super search now has around 30 properties. Before the change the code worked fine.

Transfer data from one html to another using AngularJS services (data share between controllers)

I have looked up several posts with similar issue but was unable to find a solution for my case.
I have a search page that sends a request to the backend an populates the page with search results (each result is an object). I display a concise view of each object and, upon a mouse click on a specific object, the user should be redirected to a page that shows a more detailed view for that object.
On my JS side, I have one controller that handles the $http.post call and retrieves the objects from the backend to display on the first page. I use a different controller for the second page to try and get the relevant object from the first controller (through angular's .service ), but for some reason I get an empty object on the second page. The service works with a getter and a setter. The service is able to set the object just fine, through the first controller, and I am able to print it. However, when redirecting to the second page, while using the second controller's getter, the object gets deleted and shows as empty for some reason.
Here is the relevant code. The service:
app.service('shareService', function(){
var savedData = {}
function set(data) {
savedData = data
console.log(savedData);
}
function get() {
console.log(savedData);
return savedData;
}
return {
set: set,
get: get
}
});
The search (setter) contoller:
app.controller('SearchCtrl', function(shareService, $scope, $http) {
$scope.sendSearch = function() {
$http.post("http://localhost:9080/MedNetApp/rest/mednet/searchCollections", json).success(function (response) {
$scope.collections = response.searchResults;
shareService.set($scope.collections);
});
};
});
The second (getter) controller:
app.controller('CollectionsCtrl', function(shareService, $scope){
$scope.collections = shareService.get();
})
Not sure if this is relevant, but here is also the html part where I set up a temporary test button to redirect to the second page:
<button id=mixing type = "button" class="btn btn-primary-aligned"
data-ng-click = "go('second-page.html')">temp</button>
So, at the end, savedDatashows as empty object when printing it the second time through the get() function. Any idea why this is not working? or a better way to send data to a new page?
EDIT - I should mention that I basically relied on this solution:
AngularJS - Passing data between pages
So, after further research, I came across this solution:
Sharing Data between pages in AngularJS returning empty
I used sessionStorage in my service, as described in the link above, and it fixed the problem.
Use localStorage or sessionStorage
var myJson ={};
localStorage.set("your_Data",myJson);
// to get the value from another page
var returnJson = localStorage.get("Your_Data");

$.post always returns initiated view from mvc

from my razor edit view I'm hitting mvc controller action where I'm returning ActionResult View.
$.post('/products/details/', { id: someId });
public ActionResult Details(id)
{
...
return View();// in breakpoint this is hitted but never returned as this view.
}
It's always returns me on page where jquery post is initated.
$.post without a callback is like ordering a Pizza then going to bed and forgetting about it. The delivery guy leaves it on the doorstep, where it then gets dragged away by dogs and you never see it :)
Basically: The result of an Ajax post is ignored unless you do something with it.
e.g.
$.post('/products/details/', { id: someId }, function(htmlReturned){
// Do something with the page HTML returned
$('body').html(htmlReturned); // e.g. replace the entire page!
});

Load Partial View on ajax success method in MVC 4

Problem Statement:View not able to load on ajax success method.
Description:
I'm having couple of dropdowns as cascaded(second binding based on the value of first).
On change of the first dropdown I'm binding second dropdown and again on change of the second dropdown,now on right side I want to display a list of record based on the two dropdown values.
For this,I'm using the following JS code in onchange event for the dropdown 2:
function ShowDocsList() {
var teamId = $('#TeamID').val();
var projectId = $("#ProjectID").val();
var Url = "#Url.Content("~/DocsHome/DocsList")";
$.ajax({
url: Url,
type:'POST',
dataType: 'html',
data: { TeamID: teamId ,ProjectID : projectId},
success: function (data) {
return data;
$('.docs-detail').html(data);
}
});
Here,in DocsHome Controller,DocsList method is getting hit on change of second dropdown which is project dropdown.But the view is not getting rendered .Following is my Controller Code:
public ActionResult DocsList(int teamId, int projectId)
{
List<CustomerViewModel> customerViewsModels = SmartAdminHelper.GetCustomers(db1);
if (Request.IsAjaxRequest())
return PartialView("DocsList");
else
return View("DocsList");
}
Again ,I'm getting record in List but while debugging it does not pass to the DocsList view which according to me is correct.
Here DocsList is the view I want to render as a partial view on change of the second dropdown.
According to my knowledge,while debugging it comes to the point return PartialView("DocsList") but then again it goes back to the ajax success method and finally I find that there I'm doing something wrong.
Earlier I have Json to get data but here I'm calling actionmethod from ajax. So, not sure that also might be a problem as I'm new to this.
What and where exactly I'm doing wrong?
Saroj, I see that this is an old question and that you needed to get it done quickly, but if you happend to come back to this, I'll add my two cents. You need to remove the return statement that David and Ehsan mention above. The rest of the callback function does what it should. In your action method it doesn't look like you're doing anything with the parameters you pass in. I'm assuming that you are going to figure that out after you get the view down to the client. So, lets get that view down to the client.
I like to pass the rendered partial view back to the client as a string of HTML. I do this using a method that I keep in a controller base class that each of my controllers inherit from. To use the method you will need to reference System.Web.Mvc and System.IO namespaces.
The method looks like this:
private string RenderViewToString( string viewName, object model ) {
ViewData.Model = model;
using ( var sw = new StringWriter() ) {
var viewResult = ViewEngines.Engines.FindPartialView( ControllerContext, viewName );
var viewContext = new ViewContext( ControllerContext, viewResult.View, ViewData, TempData, sw );
viewResult.View.Render( viewContext, sw );
viewResult.ViewEngine.ReleaseView( ControllerContext, viewResult.View );
return sw.GetStringBuilder().ToString();
}
}
You pass your model and the name of the view to the method and it returns the rendered view HTML as a string which you can return to the client as a ContentResult.
Update your action method like so:
public ActionResult DocsList(int teamId, int projectId)
{
List<CustomerViewModel> customerViewsModels = SmartAdminHelper.GetCustomers(db1);
if (Request.IsAjaxRequest())
var viewContents = RenderViewToString("DocsList", customerViewsModels);
return Content(viewContents);
else
return View("DocsList");
}
Assuming that the element that you want the rendered view to appear in has the css class '.docs-detail' on it you'll be in business. Hope this helps!

JSON object from ASP.NET controller to view

I have a situation where a when a web page is accessed a controller action runs which retrieves the data for that page based on a user selection. I am attempting to send the data back to the page as a JSON object, however, the data opens up as one large string in an HTML page. The controller action, in a nutshell, looks like the following snippet:
Public JsonResult MyMethod(string userSelection)
{
string userData = (string) Data;
return Json(userData, “text”, JsonRequestBehavior.AllowGet);
}
I first tried to use the JQuery $.getJson() method but I think this is wrong as I believe it issues another call to the action method for the data, which is not what I want to do. What I want is to access the JSON object in JavaScript code so I can use the property data to populate fields on the web page. The basic question is what must I do in my JavaScript to receive the JSON object when the page is first rendered? I apologize if I am missing something fundamental; this is my first try.
I still had no luck today but when I left work I came up with a strategy walking to my car. A user makes a selection from a page that presents a list prior to entering the page on which I cannot figure out how to work with JsonResult. Part of the problem is the user selection contains a link that calls the controller/action that returns the JsonResult which conflicts with using $.getJson() within the page where I want to work with JsonResult. So here is my strategy: When the user makes the selection that brings them to the (problematic) page, I will call a controller/action that strictly works with (ASP) ViewData, and use the ViewData to initially present that page. Once on the page, the user can change the selection -- I will handle this with a JavaScript event that uses a $.getJason() call to a different controller/action method that works with (ASP) JsonResult. After I try this strategy I shall post my results for whomever is interested.
You want parseJSON not getJSON
http://api.jquery.com/jQuery.parseJSON/
Edit - Oh wait you are pointing your browser at the JsonResult as if it was an ActionResult? That is not going to work.
Render a proper view, and use getJSON to call the JsonResult action.
getJSON is what you are looking for. Call that on the DOM ready event which will executes once the DOM finishes loading.
$(function(){
//This code will be executed on the DOM ready ( when the page is loaded)
$.getJSON("YourControllerName/MyMethod?userSelection=someValue",function(data){
alert(data.FirstName);
alert(data.AnotherPropertyName);
});
});
getJSON is a shorthand of jQuery ajax method with datatype set as json
Assuming your JSON data you are retuning is something like this
{
"FirstName": "Scott",
"AnotherPropertyName": "SomeValue"
}
To return data like above, change your Action method like this
public JsonResult MyMethod(string userSelection)
{
var result=new { FirstName="Scott", AnotherPropertyName="Great"};
return Json(result,JsonRequestBehavior.AllowGet);
}

Categories