Passing form data back to a controller - asp.net-mvc

I am running into an issue with a parameter not getting the value from the form data. It is showing the correct number of items (i.e. if the user select 5 options, the list contains 5 items) in the List but all values are zero. Below is my from my HTML view:
#using (Html.BeginForm())
{
#Html.HiddenFor(s => s.SOWId)
foreach (LabelTable.Domain.Entities.Option option in ViewBag.Options)
{
<div class="wizard-section" id=#option.Level>
#Html.RadioButton("["+(option.Level-1)+"].OptionId", option.OptionId) #option.OptionName
</div>
}
<div class="buttons">
<input type="submit", value="Continue", class="button"/>
</div>
}
Here is my controller method:
[HttpPost]
public ViewResult Wizard(StatementOfWork SOW, List<int> OptionIds)
{
//do something
}
OptionIds contains the following upon posting:
[0] = 0
[1] = 0
[2] = 0
and so on...
What I am trying to do is create a form where the user is presented with some options to select from (this form is one section of a wizard).
There are 5 level (or more) of options. All data for the form is sent to the view via the ViewBag.Options. All levels are hidden except level 1. Upon making a selection on level 1 the next level shows and so on. The form only posts back the options selected via each level. Originally I was doing this with mulitple post backs to the server but I did not like that (to many round trips)
I plan to add the options selected in each level to the SOW model which I am passing from view to view of the wizard.

Your View code is a bit confusing, but as far as I understand, you want the ModelBinder to bind your radiobutton values to the OptionIds list upon posting. In that case, the names of your radiobuttons should be OptionIds[0], OptionIds[1], etc. So again, I am not sure what the Level property is, but I assume you want something like this:
#Html.RadioButton("OptionIds["+(option.Level-1)+"]", option.OptionId)

Try replacing :
#Html.RadioButton("["+(option.Level-1)+"].OptionId", option.OptionId)
with:
#Html.RadioButton("["+(option.Level-1)+"]", option.OptionId)

Related

Partial Views on mvc create view that use a dropdown list to populate the partial view's view bag is this possible in mvc?

can a Partial Views on mvc create view that is using a dropdown list that sends value from the dropdown list to a function that creates a list based on the dropdown list value selection, That is then stored in a view bag for the partial view.. Can this be done in mvc and can it be done on create view of a mvc form?
I can see how something this would work in the edit view because the dropdown list value has already been selected when the page loads.
But on a new Create view record nothing is selected so the list function has a null value
Are partial views only for forms that have data pre-populated in them?
Update:
I have a create view that was created by the visual studio wizard. It has both a post and get under the create. When the user in the create view. I have a dropdown list on the page form with other fields but on load of that new create page it is empty. Unfortunately for me I wanted my partial view to to get populated with a list of data that gets sent to a view bag after the user make a selection from the drop down list.
I think what I am asking to do can only be done with webforms as mvc can handle dynamic data all that well it seems. And since when the page loads the dropdown has no value.. the list can't built so there is a null value error as well as and empty list if I hard code a value in the drop down list.
Here is my Code in these different attempt threads with different veration of my code documenting my many attempts. As I have comcluded it is not possible sadly.
Can a Drop Down List Trigger A Partial View To Update on A Create View Form In mvc?
Null view bag and partial view
Populating Partial Views using mvc
Updating a Partial View in MVC 5
So with help from Matt Bodily You can Populate a Partial View in the create view triggered by a changed value in a drop down list using a view bag and something called Ajax. Here is how I made my code work.
First the partial view code sample you need to check for null data
_WidgetListPartial
#if (#ViewBag.AList != null)
{
<table cellpadding="1" border="1">
<tr>
<th>
Widget Name
</th>
</tr>
#foreach (MvcProgramX.Models.LIST_FULL item in #ViewBag.AList)
{
<tr>
<td>
#item.WidgetName
</td>
</tr>
}
</table>
}
Populating your View Bag in your controller with a function
private List<DB_LIST_FULL> Get_List(int? VID)
{
return db.DB_LIST_FULL.Where(i => i.A_ID == VID).ToList();
}
In your Create controller add a structure like this using the [HttpGet] element
this will send you data and your partial view to the screen placeholder you have on your create screen The VID will be the ID from your Drop down list this function also sends back the Partial View back to the create form screen
[HttpGet]
public ActionResult UpdatePartialViewList(int? VID)
{
ViewBag.AList = Get_List(VID);
return PartialView("_WidgetListPartial",ViewBag.AList);
}
I am not 100% if this is needed but I added to the the following to the ActionResult Create the form Id and the FormCollection so that I could read the value from the drop down. Again the Ajax stuff may be taking care if it but just in case and the application seems to be working with it.
This is in the [HttpPost]
public ActionResult Create(int RES_VID, FormCollection Collection, [Bind(Include = "... other form fields
This is in the [HttpGet] again this too may not be needed. This is reading a value from the form
UpdatePartialViewList(int.Parse(Collection["RES_VID"]));
On Your Create View Screen where you want your partial view to display
<div class="col-sm-6">
<div class="form-horizontal" style="display:none" id="PV_WidgetList">
#{ Html.RenderAction("UpdatePartialViewList");}
</div>
</div>
And finally the Ajax code behind that reads the click from the dropdown list. get the value of the selected item and passed the values back to all of the controller code behind to build the list and send it to update the partial view and if there is data there it pass the partial view with the update list to the create form.
$(document).ready(function () {
$('#RES_VID').change(function ()
{
debugger;
$.ajax(
{
url: '#Url.Action("UpdatePartialViewList")',
type: 'GET',
data: { VID: $('#RES_VID').val() },
success: function (partialView)
{
$('#PV_WidgetList').html(partialView);
$('#PV_WidgetList').show();
}
});
This many not be the best way to do it but this a a complete an tested answer as it work and it is every step of the process in hopes that no one else has to go through the multi-day horror show I had to go through to get something that worked as initially based on the errors I thought this could not be done in mvc and I would have to continue the app in webforms instead. Thanks again to everyone that helped me formulate this solution!
No, partial views do not necessarily have to be strongly typed, if that's your question. You can have a partial view with just html markup.

Unable to use multiple Model in MVC based on any conditions

I am creating a voting mechanism for my MVC application. user will be able to vote only after loged in. I have totally 3 tables tblQuestions(to populate the questions), tblAnswers(to populate the answers), tblQuestionAnswerUserResponses (to populate the user response.)tblAnswers have relation with tblQuestions. I have used the following code in the container in the HttpGet. This is my controller code.
[HttpGet]
[ActionName("VotingResult")]
public ActionResult VotingResult(int personid)
{
List<Voting_Questions> QuesList = EpDObj.PopulateQuestions(); //Populate the list of questions
CountofQuestionsDisplayed = QuesList.Count;
ViewBag.Questions = QuesList; // Storing the list of questions in the viewbag
List<Voting_Answers> Answers = EmcObj.Voting_Answers.ToList(); //Populate the list of answers
return View(Answers);
}
I am using the Voting_Answers as model in my view My view is
#model IEnumerable<EmployeeManagementDAL.Voting_Answers>
<h2>VotingResult</h2>
#using (Html.BeginForm())
{
<div>
#foreach (var a in ViewBag.Questions)
{
<h4>#a.Questions</h4>
<div>
#foreach (var b in Model)
{
if (b.QuestionsID == a.id)
{
#Html.RadioButton(b.AnswersOptions, new {Answerid= b.id, Questionid=a.id }) #b.AnswersOptions
}
}
</div>
}
</div>
<br/>
<div >
<input type="submit" value="Vote Now!!" onclick="return confirm('Are you sure you want to submit your choices?');"/>
</div>
}
When the user go to this page for the very first time there will be no options selected. after selecting the options the values an clicking Save button will save the details to the third table and then he comes out of that page. Now if for the second time he reaches that page for editing, I want my page to render with those values in my tblQuestionAnswerResponses i.e I guess my model class of tblQuestionAnswerResponses to be used. In that case can i use the same page for both cases i.e when the user vists the page for first time and also when second time the page is visited. Can I use multiple Model in MVC based on conditions in my View.
Your ActionName attribute is unnecessary, as you have specified the same name that your action already has.
It would be cleaner to use a ViewModel instead of using the ViewBag. For starters, you'll get strong typing in your view, and it will also lend itself to easier testing.
If you make a ViewModel that represents what you want your view to display, then you can map back and forth between it and your domain models in your controller actions, and let them do the heavy lifing.

Maintain state of a dynamic list of checkboxes in ASP.NET MVC

I have a class called "PropertyFeature" which simply contains PropertyFeatureID and Description. It's a proper model created through LINQ to SQL mapped to an SQL Server database table. An example instance/row would be:
PropertyFeatureID: 2
Description: "Swimming Pool"
The number of rows (PropertyFeatures) can of course grow and shrink, and so I want to dynamically render a list of checkboxes so that the user can select any of them.
I can dynamically render the Checkboxes easily enough, with something like:
<%foreach (var Feature in (ViewData["Features"] as IEnumerable<MySolution.Models.PropertyFeature>)) { %>
<%=Html.CheckBox("Features", new { #id = Feature.PropertyFeatureID, #value = Feature.PropertyFeatureID })%><label for="Feature<%=Feature.PropertyFeatureID%>"><%=Feature.Description%></label>
<%}%>
I specify the ID for each checkbox and render the matching label so that the user can intuitively click the label and toggle the checkbox - that works great.
I set the CheckBox's "name" to "Features" so all the checkboxes render with the same name, and the MVC Model Binder piles them into a single collection called "Features" when the form is posted. This works nicely.
Once the form is submitted, I use the checked values and store them, so I need the actual integer values so I know which PropertyFeature is selected, not just a pile of Booleans and field names. So ideally, I want it as an array or a collection that's easy to work with.
I am able to retrieve the selected values from within my Controller method when the button is clicked because I have specified the parameter as int[] Features.
But the problem is that it doesn't maintain state. That is, when I click the submit button and the page reloads (with the form again displayed) I want all of the dynamic checkboxes to retain their checked status (or not). All of the other fields that I've created with Html.DropDownList and Html.TextBox all maintain their states successfully no problems at all on the same page in the same form.
I have spent hours reading all of the other threads and articles on similar issues and there is a lot of talk about using ICollection and IDictionary to bundle things up and include a Boolean value for each item so that it can maintain the checkbox state. But I don't 100% grasp how to use that in the context of my own personal example. I would like to keep the solution really simple and not have to code up pages of new classes just to maintain my checkbox state.
What is the cleanest and proper way to do this?
I got it working after much playing around with the various different approaches.
In the view:
<%string[] PostFeatures = Request.Form.GetValues("Features");%>
<% foreach (var Feature in (ViewData["AllPropertyFeatures"] as
IEnumerable<MySolution.Models.PropertyFeature>))
{ %>
<input type="checkbox" name="Features"
id="Feature<%=Feature.PropertyFeatureID.ToString()%>"
value="<%=Feature.PropertyFeatureID%>"
<%if(PostFeatures!=null)
{
if(PostFeatures.Contains(Feature.PropertyFeatureID.ToString()))
{
Response.Write("checked=\"checked\"");
}
}
%> />
<label for="Feature<%=Feature.PropertyFeatureID%>">
<%=Feature.Description%></label> <%
} %>
In the receiving controller method:
public ActionResult SearchResults(int[] Features)
This method has a number of advantages:
Allows labels to be clicked to toggle the corresponding checkboxes (usability).
Allows the Controller method to receive a super tidy array of ints, which ONLY contains the ints that have been selected - and not a whole other pile of items which were unselected or containing false/null/blank/0 etc.
Retains the checkbox's checked state when the page reloads containing the form, i.e. the user's selection is retained.
No random/stray type=hidden input fields created from the default ASP.Net MVC Html.CheckBox helper - I know it does those for a good reason, but in this instance, I don't require them as I only want to know about which IDs have been selected and for those to be in a single, tidy int[].
No masses of additional server side bloated classes, helpers and other happy mess required to achieve such a simple thing.
I would recommend this approach for anyone wanting the cleanest / bloat-free solution for a dynamic checkbox list where you need the IDs and you just want to get down to business!
The problem is that when you are rendering your list of checkboxes, you aren't setting any of them as selected. You will need to set your int[] Features in ViewData, and then in your foreach loop, check to see if the ID of that Feature is in the array in ViewData.
something like:
<%=Html.CheckBox("Features",
((int[])ViewData["SelectedFeatures"]).Contains(Feature.PropertyFeatureID),
new { #id = Feature.PropertyFeatureID, #value = Feature.PropertyFeatureID })%
although I didn't test it, so it might not be 100%.

ASP.NET MVC Filtering results in a list/grid

For some reason I'm stuck on this. I need to filter results from a View based on a DropDownList in the same view. The basic idea is this: I have a list of providers that belong to various partners, but the provider list contains ALL the providers together (for all partners). I need to be able to display the providers by partner when someone wants to see just that partner (otherwise, the default listing will be ALL providers). My view currently is the "default" (showing all), but for some reason Im sitting here staring at the monitor (for the last 2 hours!) trying to figure out how to filter these results.
Any suggestions where to start/how to do it?!
EDIT: If you want to do this with jQuery and AJAX (which will provide a better user experience because only the subdivisions list will refresh), see this tutorial.
If I understand correctly, you basically want to do a WebForms-style postback.
Let's say you have a control with countries and country subdivisions (e.g. states, provinces, etc). When the country changes, you want the appropriate subdivisions to display.
So this would be view:
<% using (Html.BeginForm()) { %>
<%=Html.DropDownList("Address.CountryId", new SelectList(Country.GetAll(), "Id", "Name"), new { onchange = "this.form.submit();" })%>
<%=Html.DropDownList("Address.CountrySubdivisionId", new SelectList(CountrySubDivision.GetByCountryId(Model.CountryId), "Id", "Name"))%>
<input type="submit" name="btnSubmit" value="Submit"/>
<%} %>
This is the key to getting the dependent list to filter:
new { onchange = "this.form.submit();" }
And in the controller, you'd have something like this:
[AcceptVerbs(HttpVerbs.Post)]
public ViewResult Index(string btnSubmit)
{
if (btnSubmit == null)
{
// return the view displayed upon GET
}
else
{
// process the submitted data
}
}
In the above code, if the form submission was triggered by changing the value in a dropdown, btnSubmit will be null. Thus, the action you are POSTing to can tell whether or not the user meant to finalize her changes.
To add upon the earlier answers.
To create a drop down (in ASP .NET MVC 3) I did the following:
Add code to Index.cshtml
#using (Html.BeginForm())
{
#Html.DropDownList("EmployeeId", (SelectList)ViewData["EmployeeId"])
<input type="submit" name="btnSubmit" value="Submit"/>
}
Add code to YourModelNameController.cs in the default ActionResult for Index()
public ActionResult Index()
{
//create a selectlist
var employeeList = from el in db.Employee select el;
ViewData["EmployeeId"] = new SelectList(employeeList, "EmployeeId", "TmName");
return View(modelName);
}
There are many ways to skin this cat. Here's one.
Enclose your DropDownList in a form with METHOD=GET.
<form action="" method="get">
<select name="provider">
<option>1</option>
<!-- etc -->
</select>
</form>
Then, in you controller, filter based on the value of provider that was passed in. Remember to treat it as a Nullable parameter so that you can have some kind of behavior when it's empty.
Without posting some of your current code, it's tough to get much more specific than that.
Let's assume that you're probably passing a model to the view and that model is a list or IEnummerable of partners. What you want to do is restrict the list. In order to do that add a drop down list in the view and fill it with some possible partners. This can be done either by putting a list in ViewData or expanding the model passed back to the view. Both have advantages. Now when you change the drop down reload the page but append a parameter which is the filter. In the controller check for that parameter in the action, if it isn't present then return an unfiltered list, if it is then apply a filter and return the list. The view will just dumbly display whatever you give it.
As for the filtering you might want to try using LINQ.
You probably want a parameter to your controller action, maybe a (nullable?) id of the provider, to filter the results already when you get them from DB. Then just use the same view to list them, and request a new list if the dropdownlist changes.
Best solution I know is that one.
http://gridmvc.codeplex.com/SourceControl/latest

How to get the selected value of a dropdown in the MVC View itself

I have a drop down in a MVC View, which is some thing like this:
Html.DropDownList(id, Range(0,10)
.Select(x => new SelectListItem {Text = x, Value = x}))
In the view itself, I need the selected value of this drop down. I know that I can access that in a JavaScript, but I am looking for a way to get it in the view itself from the drop down properties or something like that.
How can I access it? I tried to figure out some thing from intellisense but nothing relavant showed up, help is much appreciated.
Edit: I want the value after a few lines after the declaration of the drop down, I know that I can access it from JavaScript and by posting the form, Is there noway to access it on the view itself ?
Edit2: If its not possible to access it in view, please explain the reason, I am more interested in knowing it.
Thanks.
After reading at your question, it sounds like you want to have the drop down list supply a value for a lower section of the same page.
First and foremost, you will need to place the DropDownList within a form construct, as in:
<% using (Html.BeginForm("ProcessValue", "ThisPage")) { %>
<%= Html.DropDownList("DropID", Range(0, 10).Select(a=>new SelectListItem { Text = x, Value = x }) %>
<input type=submit value="Submit" />
<% } %>
You need to set up a few things ahead of time:
You have to have a submit button, or a similar construct, in order to retrieve the value of the DropID variable.
You need to set up an controller method that will handle the processing of the value, then redirect back to the original page with the selected value in the page's ViewData.
Finally, you need to set up the view so that the post-processing section will only display if you have a valid value in the DropID variable.
It's not as simple as just placing a DropDownList in a view and then using that value later on in the page. You have to get the controller involved to manage the data transport and you have to set up the single view to handle multiple states (ie. before the value is selected and after the selection takes place).
To get the selected value you could use either javascript or a controller action to which the form containing the select box is submitted.
The selected value will be in the FormCollection or QueryString collection with the name of the DropDown's ID in the controller action that receives the form submission from this view. You can either submit the values with a classic POST or GET or via AJAX, but you have to wire up a server-side action that processes that input.
There is a SelectList class as well wich allows you to define wich item will be selected.. and knowing that - you will know selected value..
Also.. if no value is selected explicitly, dropdowns tend to select the first item in the list.

Resources