State Management of javascript conent in MVC - asp.net-mvc

I am using asp.net MVC2. i am facing a problem in state management of javascript contents.
i have got a image map in which on click on various part of image i am showing same page (redirect with parameters) with some parameter like : Secure/BodyWork?view=7
and on basis of value in parameter view i am showing various content on page. in that content i have got some checkboxes which i make checked and show it on left side in a div (checked one).
the issue is when i click on another part of image (of image map) it rediect me to same page with different "view=?" value but i loos state of my current divs(which contains name of checked check box of previous page).
my inherites line is like this:
Inherits="System.Web.Mvc.ViewPage<List<WBAC.Models.BodyWorkModel>>"
controller contains:
public ActionResult BodyWork(string view)
{
SecureModelService service = new SecureModelService();
return View(service.ListBodyWork(view));
}
[HttpPost]
public ActionResult BodyWork(BodyWorkModel model1)
{
//some code
}
i have tried with hidden field so in which i placed names of current page's checkbox but of course those loses value when i click on image map because of redirection of page to current page.
i have also tried with using ajax.beginform but its also not working because we are redirecting the page (to same page with different parameters like: view=3/view = 4) on click of image map.
please suggest me what should i change and how to do it.
Thanks
code in target div:
<div class="damageAreaMid" id="dvdamageAreaMid">
<% foreach (var item in Model)
{ %>
<div class="area">
<h2>
<%: item.Component %></h2>
<% Html.RenderPartial("~/Views/Shared/UCWorkArea.ascx", item.VehicleOption(item.ComponentID, item.Component));%>
</div>
<% } %>
</div>

You could use AJAX and refresh only the part of the page that needs to be refreshed.
public ActionResult BodyWork(string view)
{
SecureModelService service = new SecureModelService();
return View(service.ListBodyWork(view));
}
public ActionResult BodyWork(BodyWorkModel model)
{
//some code
return PartialView(model);
}
And in your view AJAXify the links on the image map:
$(function() {
$('#somecontainer a').click(function() {
$('#someresultcontainer').load(this.href);
return false;
});
});

Related

MVC 3 show hide Partial Views in jquery UI tabs

In our application we are using Tabs to display the information for example contacts, in this tab the user can switch between view contacts and created contact. When the user clicks on ‘Create’ I want the partial view changed to CreateContact within the same tab. What is the best way to show hide a Partial Views in jquery UI tabs? Should I use Ajax code to do this?
View
<div id="tabs">
<ul>
<li>Claim</li>
<li>Products</li>
<li>Contact Us</li>
</ul>
</div>
Controller
public ActionResult GetContact()
{
return PartialView();
}
public ActionResult CreateContact()
{
return PartialView();
}
Partial View
<li>#Html.ActionLink("Create", "Test", "Home")</li>
Thanks
Yes, you can use AJAX. That is in case you don't want to load all partial views at once.
If it doesn't matter, you can just render them at once:
<div id="tabs-1">
#Html.Partial("GetClaim")
</div>
<div id="tabs-2">
#Html.Partial("GetProduct")
</div>
<div id="tabs-3">
#Html.Partial("GetClaim")
</div>
jQuery hides the elements that are not currently visible and will manage the switching automatically.
You can use an Ajax.ActionLink() - http://msdn.microsoft.com/en-us/library/dd493106.aspx
This will asynchronously submit your form to your controller method. If you set the AjaxOptions.InsertionMode to be AjaxOptions.InsertionMode.Replace then it will replace the partial view content with whatever you return from the controller. Then, you just need to return the GetContacts view in the creatcontacts controller action, as below:
[HttpGet]
public ActionResult GetContact()
{
return PartialView(RetrieveListOfContacts());
}
[HttpPost]
public ActionResult CreateContact(StronglyTypedContactModel contact)
{
if (ModelState.IsValid)
{
// .. write your contact here
return PartialView("GetContact", RetrieveListOfContacts());
}
else
{
return PartialView(contact);
}
}
EDIT
Also, you can specify that it be a GET request in the HttpMethod of the AjaxOptions, so as not to require form (as I originally assumed you did).

ASP.NET MVC2 -- Trouble with Model Binding and Html.Textbox()

ASP.NET MVC Model Binding is still new to me and I'm trying to understand exactly how it works. Right now, I appear to be having problems with a feature of Html.Textbox()
Specifically, I have a View where I set Html.Textbox to a value both in the "Get" and the "Post". It sets fine in the "Get", but after the user submits a value during the "Post", I have the class change one of the values internally based on the other value submitted.
(I'm basically validating one value based on the other... I'm not sure if this is the right way to do this...)
Tracing through, I can see that the value has actually changed as expected both in the Model and in the View, but when it displays on my screen after the "Post", the value does not display as it was changed. Instead it is what it was set to originally.
Here's my simplified example:
The View shows a:
Drop-down with items from a SelectList (pre-selected as "Other")
a Read-only Text Box (with a pre-loaded value of 0)
Submit Button
User should pick a new value from the Drop-Down and click submit. The "Post" method in the controller picks up the new value from the Drop-Down and changes the Value in the Read-only text-box and re-displays.
(Yes, I'll eventually be doing this with JQuery, too...)
Here's my sample Model class:
public class SampleSubmission
{
public string Name { get; set; }
public int Volume { get; set; }
public readonly SortedList<string, int> NameVolumeList = new SortedList<string, int>();
// Standard Constructor
public SampleSubmission()
{
NameVolumeList.Add("Sample1", 10);
NameVolumeList.Add("Sample2", 20);
NameVolumeList.Add("Sample3", 50);
NameVolumeList.Add("Other", 0);
this.Name = NameVolumeList.Keys[0];
this.Volume = NameVolumeList[Name];
}
// Copy Constructor
public SampleSubmission(SampleSubmission samSub) : this()
{
this.Name = samSub.Name;
this.Volume = NameVolumeList[Name];
}
}
Here's the Controller:
public class SampleSubmissionController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
SampleSubmission sampleSub = new SampleSubmission();
return View(sampleSub);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(SampleSubmission sampleSub)
{
SampleSubmission samSub = new SampleSubmission(sampleSub);
return View(samSub);
}
}
Here's the View:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MvcModelBindTest.Models.SampleSubmission>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<% using (Html.BeginForm()) { %>
<%= Html.DropDownList("Name", new SelectList(Model.NameVolumeList.Keys.ToList())) %>
<%= Html.TextBox("Volume",Model.Volume) %>
<input type="submit" name="pick" id="pick" value="Pick" /> <% } %>
</asp:Content>
Any ideas as to why the new value does not display?
EDIT:
In order to fix the problem, I read the link given by "jfar" and made a 1-line change.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(SampleSubmission sampleSub)
{
SampleSubmission samSub = new SampleSubmission(sampleSub);
// Reset Model Value
ModelState.SetModelValue("Volume", new ValueProviderResult(
samSub.Volume, "", System.Globalization.CultureInfo.CurrentCulture));
return View(samSub);
}
This definitely works. Unfortunately, this feels like a gross hack to me. What if I had to update the values of multiple fields? There must be a better (simpler?) way of doing this.
EDIT2: Found my answer. See below...
From: How to clear textboxes defined with MVC HTML helpers
"The HTMLHelper's first look at the
ModelState and ViewData to see if any
values match their key and then
finally use whatever value you provide
them.
If you need to reset the textboxe's
value you also need to clear the
ModelState entry with the matching
key. Another alternative is
redirecting to the same page instead
of simply rendering a view via
javascript or with MVC.
I figured out the answer to my own question when I stumbled upon another variable that needed to be reset. As I was looking at the data structure, I realized what I wanted was the pristine state where there were no Keys in the ModelState.
ModelState.Remove(key);
Where "key" is the value you're trying to reset.
Another simple workaround is instead of
<%= Html.TextBox("Volume",Model.Volume) %>
Use HTML input tag
<input id="Volume" name ="Volume" value="#Model.Volume" />

how to render a full view using Ajax.BeginForm

I have a partial view which has a Ajax.BeginForm, with a UpdateTargetID set. When the validation on the form fails the update target id is replaced with the validation errors, but when there are no validation errors users should be redirected to a new page.
The code in my Partial view is
<div id="div_UID">
<% using (Ajax.BeginForm("FindChildByUID", new AjaxOptions { UpdateTargetId = "div_UID" } ))
{%>
<p>
<label>UID:</label>
<%= Html.TextBox("UID") %>
</p>
<input type="submit" value="Continue" />
<% } %>
</div>
</pre>
The code in my controller is as follows
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult FindChildByUID(Student student)
{
Student matchingStudent = _studentService.FindChildByUID(student.UID);
if (matchingStudent == null)
{
ModelState.AddModelError("UID", String.Format("No matching child found for the entered UID: {0}", student.UID));
return PartialView();
}
else
{
// full view
return RedirectToAction("ConfirmChildDetails", matchingStudent);
}
}
So, for I have been unsuccessful to display the full view on it's own, as it always seems to dipslay the full view in the UpdateTargetID div specfied in the Ajax.BeginForm.
Any suggestions on how I can get this to work?
Thanks
What your AJAX post is doing is making a request and waiting on a response that contains html to input onto the page. The configuration is such that whatever html is returned will be injected into the div you've named "div_UID".
I typically avoid scenarios like this and use traditional posting if a redirect is required upon a successful outcome of the POST.
I imagine you could do it like this using jQuery to submit rather than the Ajax.BeginForm (or just set a callback function for your Ajax.BeginForm):
function SubmitForm(form) {
$(form).ajaxSubmit({ target: "#div_to_update", success: CheckValidity });
}
function CheckValidity(responseText) {
var value = $("#did_process_succeed").val();
if (value == "True") {
window.location.replace("url_of_new_action_here");
}
}
You just have to have a hidden field in your partial view called "did_process_succeed" and set the value of True or False based on some logic in your controller.
There are likely other ways as well. Perhaps someone else will chime in. I hope this helps for now.

asp.net MVC partial view controller action

I'm very new to web app development and I thought I would start with recent technology and so I'm trying to learn asp.net as-well as the MVC framework at once. This is probably a very simple question for you, MVC professionals.
My question is should a partial view have an associated action, and if so, does this action get invoked whenever a normal page uses RenderPartial() on the partial view?
While you can have an action that returns a partial view, you don't need an action to render a partial view. RenderPartial takes the partial view and renders it, using the given model and view data if supplied, into the current (parent) view.
You might want an action that returns a partial view if you are using AJAX to load/reload part of a page. In that case, returning the full view is not desired since you only want to reload part of the page. In this case you can have the action just return the partial view that corresponds to that section of the page.
Standard mechanism
Making use of partial view within a normal view (no action needed)
...some html...
<% Html.RenderPartial( "Partial", Model.PartialModel ); %>
...more html..
Ajax mechanism
Reloading part of a page via AJAX (note partial is rendered inline in initial page load)
...some html...
<div id="partial">
<% Html.RenderPartial( "Partial", Model.PartialModel ); %>
</div>
...more html...
<script type="text/javascript">
$(function() {
$('#someButton').click( function() {
$.ajax({
url: '/controller/action',
data: ...some data for action...,
dataType: 'html',
success: function(data) {
$('#partial').html(data);
},
...
});
});
});
</script>
Controller for AJAX
public ActionResult Action(...)
{
var model = ...
...
if (Request.IsAjaxRequest())
{
return PartialView( "Partial", model.PartialModel );
}
else
{
return View( model );
}
}
The accepted answer is completely correct, but I want to add that you can load your partial view using jQuery load. Less configuration needed, if you don't want to consider concurrency.
$("#Your-Container").load("/controller/action/id");
I was able to achieve something similar with this logic.
Within the .cshtml
#Html.Action("ActionMethodName", "ControllerName");
Within the controller
[Route("some-action")]
public ActionResult ActionMethodName()
{
var someModel = new SomeModel();
...
return PartialView("SomeView.cshtml", someModel);
}
And that's it.
If you need to pass values from the .cshtml to the action method then that is possible to.
The answer is no. But sometimes you need some controller action behind a partial view. Then you can create an actionMethod wich returns a partial view. This actionMethod can be called within another view:
#Html.Action("StockWarningsPartial", "Stores")
The actionmethod can look like:
public ActionResult StockWarningsPartial()
{
....
return View("StockWarningsPartial", warnings);
}
and the view 'StockWarningsPartial.cshtml' starts with:
#{
Layout = null;
}
to make it not render your surrounding layout again.
public ActionResult GetStateList(int country_id)
{
List<stateDTO> stateList = new List<stateDTO>();
stateList = bll.GetState(country_id);
ViewBag.sList = new SelectList(stateList, "state_id", "State_Name");
return PartialView("DisplayStates");
}

Render an action that returns a partial view in a view

Suppose I have an action that returns an rendered asp.net mvc control and send it as a response for AJAX request.
I want to have the response of that action during the whole page is rendering in a view.
public class Controller
{
....
public ActionResult AjaxAction(string parameter)
{
return PartialView("~/Views/Controls/Control.ascx",parameter);
}
}
now in view that renders the whole page I want something like:
<%var par = "1";%>
<%= AjaxAction(par) %>
Depending on what you want to achieve partial requests may work for you. This is typically useful where your control is some form of 'widget'.
I would use the jQuery load function, fired when the document is ready, and load the partial view into a div.
$(function() {
$('#partialResult').load( '<%= Url.Action( "AjaxAction", "Controller", new { parameter = "1" } ) %>' );
}
<div id="partialResult">
</div>

Resources