ASP.NET MVC 3 - tell partialview to regrab the viewdata values? - asp.net-mvc

Let's say I have a partial view X.ascx like this:
<div id = "updateTargetIdForAjaxForm">
... javascript code which only has function definitions.
... ajax form with buttons inside
<div id = "stuff"></div>
<script type = "text/javascript">
do things to "stuff" div as soon as X.ascx is loaded.
</script>
</div>
Now I want to update things on X.ascx, based on Ajax response. Earlier, I was returning PartialView but inline javascript that does things to stuff div wouldn't like that, meaning the inline javascript just won't get executed when X.ascx is reloaded.
So is there a way I can not return PartialView in my controller, but just update ViewData values and tell the PartialView to re-grab the updated ViewData values? And also call one or two javascript functions based on the response from server maybe?

I see two possible ways to go:
Fixing your javascript code to run with dynamically loaded partial view:
http://api.jquery.com/live/
http://api.jquery.com/delegate/
These two should help you out.
The other way is to create an action on your controller that would return JSON result and from jQuery you should be able to handle JSON object and update your form. Your Action could look like :
public JsonResult GetFormValues()
{
var jsonFormValues = new
{
key1 = "abc",
key2 = "123",
key3 = "abcdef"
};
return Json(jsonFormValues, JsonRequestBehavior.AllowGet);
}
and check out http://api.jquery.com/jQuery.getJSON/ on how to handle the result

Related

cannot applybindings multiple times knockout in MVC partial view

Hi have a parent page in which i have used knockout js to bind model with html element.
Now i make a ajax call to receive a partialviewresult which i place it in a div conbtainer.
All works fine if use the inbuilt mvc model binding.
But when i go for knockout in my partial view as well. I get the errorcannot applybindings multiple times knockout in MVC partial view.
I have even tried using
ko.applybindings(new vm(),document.getelementbyId("div1"))
ko.applybindings(new vm1(),document.getelementbyId("div2"))
But still get the same error. Is it not possible to get the partial view result from the action method and use knockout in partial view ? I do not want hide the div in my parent page and get a JsonResult and bind it to my div element.
If you have the following (general layout):
<div id="parent">
content
<div id="partialTarget"></div>
</div>
and you've already applied your bindings to #parent, you have to clean #partialTarget before applying the viewmodel again. #partialTarget has already been bound from the first pass, so to apply the bindings to the loaded contents, you need to do something like this:
var reapplyBindings = function(element){
var vm = ko.dataFor(element);
if( vm ) {
ko.cleanNode(element);
ko.applyBindings(vm, element);
}
};
element.load(‘path/to/fragment.html’, function() {
//the [0] selector is needed to be sure we have an actual dom element, not the jQuery wrapper
reapplyBindings(element[0]);
//do whatever you’re already doing
});

passing the original controller and action name - mvc

I have an ascx control for fruits that contains following code:
<div id = "fruits">
....
Ajax stuff1 UpdateTargetId = "fruits"
Ajax stuff2 UpdateTargetId = "fruits"
<%Html.RenderPartial("PagerAjax", (Pager)ViewData["pager"]); %>
</div>
now this fruit control can appear on a number of webpages and the pager would need to know what page the user is on so that it can pull next set of fruits accordingly. For example, if I am on red-fruit page, then PagerAjax should know I am only pulling out red fruits. So, basically I would need to know ControllerName (assume it's home) and actionName (assume it's redFruits()). (Example may seem inefficient but it makes sense for the real purpose.) Now, I could do something like this:
<%Html.RenderAction("PagerAjax", (Pager)ViewData["pager"], ViewContext.RouteData.Values["action"], controllerFilter = ViewContext.RouteData.Values["controller"] }); %>
However, as you noticed, the above RenderAction is inside the div that is being updated by Ajax callback, which means it will contain action and controller of the Ajax stuff rather than the original URL's.
What should be an efficient workaround?
You could pass the original ViewContext.RouteData.Values["action"] as parameter when calling your AJAX action. This way the action knows what was the original action and store it in the model (or ViewData as in your case I see that your views are not strongly typed). Now your markup could become:
<% Html.RenderPartial(
"PagerAjax",
(Pager)ViewData["pager"],
new ViewDataDictionary() { { "originalAction", ViewData["originalAction"] } }
); %>

PartialView not clearing after ajax postback

I have this weird thing happening.
I have a PartialView with 3 fields on it. I do a jQuery ajax post to my action result and if the model passes validation i save the record. I also then set the model to empty and pass it back to the view as a partial view.
public ActionResult jQueryAddComment(Comment comment)
{
if (ModelState.IsValid)
{
//do stuff here
comment = new Comment();
}
return PartialView("AddNewComment", comment);
}
When I get back to the page my JS replaces the contents of the comments div with the html from the new partial view.
function submitComment() {
$.post('/Home/jQueryAddComment', { forumItemId: $('#id').val(), owner: $('#owner').val(), text: tinyMCE.get('text').getContent(), emailAddress: $('#emailAddress').val() }, function (result) {
alert(result);
$('.AddNewComment').html(result);
});
}
However, when the page renders the values are back in place. I can see that an empty model is being passed to the view so why are my previous values still there?
Even the alert shows the values in place even though I'm passing an empty object to the partial view in the controller.
edit
I should mention that I can't clear the fields within the JS of the page as I want to use the same code to render errors as well as successful requests.
Use ModelState.Clear() before returning the new blank model as a partial view, like:
if (ModelState.IsValid)
{
//your save logic
ModelState.Clear();
comment = new Comment();
}
return PartialView("AddNewComment", comment);
The standard HTML helpers look into ModelState and ViewData for values before using the values you passed to the helper.
This may help:
How to clear textboxes defined with MVC HTML helpers

ASP.NET MVC - Build Search Results into a Div

I'm new to ASP.NET MVC, but I need to perform a search for articles that match a selected category. The results of this query need to be written into a "search results" div overlay with DHTML- jquery, probably.
So, I need the results of an Action, but not to render a view. I was thinking I could use Json and then iterate over the resulting records, somehow.
Or is it easier to use RenderPartial... but how would I use this in this DHTML scenario?
Thanks.
I like the way Steve Sanderson describes in his ASP.NET MVC book. It dosnt work with JSON, but returns a partial. This makes it easier to have both: An Ajax and a non-Ajax version.
The cotroller returns a View or Partial depending on the type of request:
public ActionResult GetArticles(string category)
{
...
if(Request.IsAjaxRequest())
{
return PartialView("ArticleListPartial",articleModel)
}
else
{
return View("ArticleListPage",articleModel)
}
}
The search by default submits the from with with a Non-Ajax post:
<form id="articleSearch" method ="post" action="/Article/GetArticles" >
...
<input type="submit" value="Get the articles!" />
<form>
Then there is a Jquery snippet that kicks in when Javascript is available and submits the request via Ajax
<script language="javascript" >
$(function() {
$("#articleSearch").submit(function() {
$.post($(this).attr("action"), $(this).serialize(), function(modelResponse) {
("#articleResultContainer").html(modelResponse);
});
return false;
});
});
</script>
Hmmm, sounds like you are trying to do a filter?
If this is the case I think it's a bad idea trying to search within your html. I think a better approach would be to post back using jQuery, get your result set from whatever database you are using, and return that back to the view as apartial view.
When you are searching your database you should apply the filter at that point using sql, Linq2Sql or whatever you're using.
If you are still Hell bent on searching the HTML then I'd give each relevant div a class name of say class="DivSearchable". Then in jQuery you can do something like;
$('.DivSearchable").each(function() {
var text = $(this).val();
"Now test text for contents of your seach string"
if (BoolIfFound == true)
$(this).addClass("highlightClassName");
});
highlightClassName would set the background-color to something so you can see which divs contains the search string.
make sense?

ASP.Net MVC Ajax call that returns JsonResult

I'm starting to learn ASP.Net MVC (the release candidate), and I'm having a little trouble. I might just be being picky, but I thought I'd ask.
I want to use the built-in (extended) ASP.Net Ajax methods to make a call to my controller, called "GetNames," that returns a JsonResult object. I've seen examples that use the $.getJSON() jQuery method, but I would instead prefer to do something like this:
<%using ( Ajax.BeginForm("GetNames", new AjaxOptions() { OnSuccess = "GetNamesSuccess", OnBegin = "GetNamesBegin", OnComplete = "GetNamesComplte", OnFailure = "GetNamesFailure" } ) ) { %>
<%=Html.TextBox("DummyData") %>
<input type=submit />
<% } %>
<script type="text/javascript">
function GetNamesSuccess()
{
alert("Success");
}
function GetNamesBegin()
{
alert("Begin");
}
function GetNamesComplete()
{
alert("Complete");
}
function GetNamesFailure()
{
alert("Failure");
}
</script>
When I click the Submit button, I get none of the alerts, and I get prompted to download a file containing the text of Json object, which I believe indicates that at least the controller method is working fine. But that's not the intended behavior for me... Ideally, Ajax.BeginForm would set it up such that the Json object would get passed to either the OnSuccess or the OnComplete method.
Is there a way to accomplish that?
Have you included both the MicrosoftAjax.js and MicrosoftMvcAjax.js javascript files in your view page? It sounds to me like it is actually posting the form instead of using Ajax. I've had this problem when I was missing the MicrosoftAjax.js include because the Ajax postback failed due to missing javascript classes and thus it invoked the normal form post.
On a related note, you should check to see if the request is Ajax or not in the controller and return a ViewResult (or Redirect) instead of Json if it's not. If someone has javascript turned off or you have errors on your page you want it to gracefully degrade and handle it as a normal postback rather than return Json.

Resources