Group by column in MVC? - asp.net-mvc

In my ASP.NET MVC 2.0 project, I have a user control that loops through the Model data and displays multiple rows. Here is the code:
<div id="DivMain">
<%
var index = 0;
foreach (var item in Model)
{ %>
<div data_id="<%= item.Id %>" onclick="page.toggleId(<%= item.Id %>)">
<div style="display:none">
<%= Html.Encode(item.Id)%>
</div>
<div>
<%= Html.Encode(item.Question)%>
</div>
</div>
<%
index++;
} %>
</div>
I want the item.Name column to display a master/slave relationship. example - Question1(Question column on the first row) should display a + sign next to it. Clicking on the + sign should list all the Answers associated with that Question. Basically the model data has a one to many relationship between Question and Answers.
How can this be achieved?

Take a look at the Telerik mvc controls, the grid there is fairly easy to use for scenarios like this. And it's free if you do not need support. Samples can be found here.

Related

how to get values in checkbox

I have 4 checkboxes. I want when I update the page the checkboxes is populating the values from database.
My code is
<div class="editor-field">
<%: Html.CheckBox("Any")%> Any
<%: Html.CheckBox("Contract")%> Contract
<%: Html.CheckBox("PartTime") %>Part Time
<%: Html.CheckBox("FullTime") %>Full Time
<%: Html.CheckBox("WorkFromHome") %>Work From Home
</div>
Help me from out this problem..
Can you include details about the data model and the viewdata ? Make sure that the boolean properties representing these checkboxes in your model, and that the model is refreshed from database values ?
I found the solution to this problem.
I take Male and Female fields.
<%: Html.Label("Gender")%>
<div class="editor-field">
<%var male = Model.Male; %>
<%var female = Model.Female; %>
<%if (male.HasValue == true || female.HasValue==true)
{ %>
<%:Html.CheckBox("Male")%>Male
<%:Html.CheckBox("Female")%>Female
<%} else
{%>
<%:Html.CheckBox("Male")%>Male
<%:Html.CheckBox("Female")%>Female
<%} %>
It retrieves the values correctly and when we want to select new one it shows the new checkbox.Hope you all others are useful.

What's the idiomatic way to implement a multi-edit function, allowing edits for multiple simultaneous fields in a list, in .Net MVC?

I'm trying to create an MVC form which will allow a user to edit multiple records at the same time, and submit the changes as a batch update to my data. The code below shows you how I'm displaying the data to be edited. Is this supposed to work out of the box? Should the user be able to click "Submit" and have my "Update" message receive a model containing all of the appropriate changes?
If not, then what's the idiomatic way to implement something like this in .Net MVC?
#using (Html.BeginForm( "Update", "SomeController", Model)) {
<div>
<fieldset>
<ul id="categoryEditor" style="list-style-type: none">
#for (int i = 0; i < Model.AList.Count(); i++) {
#Html.HiddenFor( model => model.AList[i].ID )
#(Model.AList[i].Name)
#Html.EditorFor( model => model.AList[i].Category )
}
</ul>
<p>
<input type="submit" value="Update" />
</p>
</fieldset>
</div>
}

ASP.NET MVC: Binding to multiple models

I'm playing with an ASP.NET MVC application and I've run into a bit of a problem. I am pretty new to ASP.NET MVC and just barely understand the basics to get things to work at this point.
I have a PersonModel, a PersonController, and a bunch of views that let a user add a new person, edit a person and search for people.
I am not using a DataBase in the back end. Everything I'm doing depends on an external DLL that returns "person" structures (that I turn into PersonModels).
In order to search for people, I have to provide a person-structure that acts as search criteria to a method in the external DLL. The method returns a collection of person-structures that match the search criteria. If I want to retrieve all of the people in the system I supply an empty person-structure to the method.
So, I have the "retrieve all people" function working.....but I'd like to provide an advanced search.
My Search View is bound to a class that contains 2 properties:
Public Class PersonSearchModel
Private _searchCriteria As PersonModel
Private _searchResults As List(Of PersonModel)
Public Property SearchCriteria As PersonModel
Get
return _searchCriteria
End Get
Set(ByVal value As PersonModel)
_searchCriteria = value
End Set
End Property
Public Property SearchResults As List(Of PersonModel)
Get
return _searchResults
End Get
Set(ByVal value As List(Of PersonModel))
_searchResults = value
End Set
End Property
End Class
Now the Search View binds to this PersonSearchModel and I have 2 sections...a section where the user can provide search criteria and a section that displays the search results.
I am having a problem binding the PersonSearchModel.SearchCriteria to the controls used to display/gather the Person search criteria.
I cannot retrieve the search criteria.
This what I have in my view for the search criteria:
<fieldset>
<legend>Search Criteria</legend>
<%
With Model.SearchCriteria
%>
<div style="float:left">
<p>
<label for="FirstName">
FirstName:</label>
<%=Html.TextBox("FirstName", Html.Encode(.FirstName))%>
<%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
<label for="LastName">
LastName:</label>
<%=Html.TextBox("LastName", Html.Encode(.LastName))%>
<%= Html.ValidationMessage("LastName", "*") %>
</p>
<!-- More controls -->
</div>
<% End With%>
</fieldset>
<%=Html.ActionLink("Search", "Search",Model.SearchCriteria)%>
<!-- The Search Results Section-->
The PersonModel passed into the Search method is a new/empty PersonModel Object.
It does not contain the data that the user entered.
What am I doing wrong here?
********** Edit **********
I have tried changing the View to bind differently. I removed the VB "With":
<fieldset>
<legend>Search Criteria</legend>
<div style="float:left">
<p>
<label for="FirstName">
FirstName:</label>
<%=Html.TextBox("FirstName", Html.Encode(.FirstName))%>
<%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
<label for="LastName">
LastName:</label>
<%=Html.TextBox("LastName", Html.Encode(.LastName))%>
<%= Html.ValidationMessage("LastName", "*") %>
</p>
<!-- More controls -->
</div>
</fieldset>
<%=Html.ActionLink("Search", "Search",Model.SearchCriteria)%>
<!-- The Search Results Section-->
But this didn't help.
I also tried:
<fieldset>
<legend>Search Criteria</legend>
<div style="float:left">
<p>
<label for="FirstName">
FirstName:</label>
<%=Html.TextBox("Model.SearchCriteria.FirstName", Html.Encode(Model.SearchCriteria.FirstName))%>
<%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
<label for="LastName">
LastName:</label>
<%=Html.TextBox("Model.SearchCriteria.LastName", Html.Encode(Model.SearchCriteria.LastName))%>
<%= Html.ValidationMessage("LastName", "*") %>
</p>
<!-- More controls -->
</div>
</fieldset>
<%=Html.ActionLink("Search", "Search",Model.SearchCriteria)%>
<!-- The Search Results Section-->
And:
<fieldset>
<legend>Search Criteria</legend>
<div style="float:left">
<p>
<label for="FirstName">
FirstName:</label>
<%=Html.TextBox("SearchCriteria.FirstName")%>
<%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
<label for="LastName">
LastName:</label>
<%=Html.TextBox(".SearchCriteria.LastName")%>
<%= Html.ValidationMessage("LastName", "*") %>
</p>
<!-- More controls -->
</div>
</fieldset>
<%=Html.ActionLink("Search", "Search",Model.SearchCriteria)%>
<!-- The Search Results Section-->
However, I am still getting an empty/new PersonModel passed into the Search method in the controller. I've also checked the PersonSearchModel.SearchCriteria to see if maybe that contained the values entered, but this also has a new/empty PersonModel.
-Frinny
Using reflection is pretty much what the MVC model binders are setup to do, my guess is that you weren't naming your fields correctly so when they posted back to your action they didn't map up to your parameters. Try doing something like:
Function Search(ByVal personSearchModel As PersonSearchModel, ByVal collection As FormCollection) As ActionResult
Then your fields (HTML) should be named like so:
<%= Html.TextBox("personSearchModel.SearchCriteria.FirstName", Html.Encode(Model.SearchCriteria.FirstName)) %>
I think that you're missing the necessary prefixes on the calls to Html.TextBox and Html.ValidationMessage. I recommend not using VB's "With" keyword since it obscures the full name of the member. Both the HTML helpers and model binding (which is what gets used to pass parameters into action methods) need the full name of the property or field in order to retrieve the value.
Try this instead:
<%= Html.TextBox("SearchCriteria.FirstName", SearchCriteria.FirstName) %>
<%= Html.ValidationMessage("SearchCriteria.FirstName", "*") %>
Also, there's no need to call Html.Encode() for the value being passed into the TextBox - it gets automatically encoded anyway.
After much testing and debugging I discovered something interesting: I can retrieve the information entered by the user from the FormCollection passed into the Search Function. Originally my search function took 2 parameters. The first parameter was the PersonModel that was supposed bound to the PersonSearchModel.SearchCriteria, the second parameter was the FormCollection for the view.
I am able to create the PersonModel used for the PersonSearchModel.SearchCriteria based on the FormCollection passed into the Search function. I removed the first parameter (the PersonModel) since it was always a new/empty object.
This is my current Search method:
<AcceptVerbs(HttpVerbs.Post)> _
Function Search(ByVal collection As FormCollection) As ActionResult
Dim searchModel As New SearchPersonsModel
Dim personProperties() As PropertyInfo = GetType(PersonModel).GetProperties
For Each pi As PropertyInfo In personProperties
Dim piName As String = pi.Name
Dim info As String = Array.Find(collection.AllKeys, Function(x) x.Compare(piName, x, true) = 0)
If String.IsNullOrEmpty(info) = False Then
pi.SetValue(searchModel.SearchCriteria, collection.Item(info), Nothing)
End If
Next
'The following code uses the searchModel.searchCriteria to search for People.
End Function
My View (if your curious) looks like:
<% Using Html.BeginForm()%>
<%With Model.SearchCriteria%>
<fieldset>
<legend>Search Criteria</legend>
<div style="float: left">
<p>
<label for="FirstName">FirstName:</label>
<%=Html.TextBox("FirstName", Html.Encode(Model.SearchCriteria.FirstName))%>
<%=Html.ValidationMessage("Model.SearchCriteria.FirstName", "*")%>
</p>
<p>
<label for="LastName">LastName:</label>
<%=Html.TextBox("LastName", Html.Encode(Model.SearchCriteria.LastName))%>
<%=Html.ValidationMessage("Model.SearchCriteria.LastName", "*")%>
</p>
<!---..... more controls .... -->
</div>
</fieldset>
<%End With%>
<input type="submit" value="Search" />
<!-- Search Results Controls -->
<%End Using%>
This solution works but I am really not happy with it.
Why do I have to recreate the PersonModel used as the search criteria?
Why could I not pass this object as a parameter into the Search method?
-Frinny
Seems like UpdateModel() could be your friend here. MVC does not pass objects around web forms style.
Even if your Model consists of two objects, it's perfectly possible to use UpdateModel to retrieve the values for one of them. You just have to specify that object as parameter. E.g.:
Thing t = new Thing();
UpdateModel(t);
You may have to look at parameter names to allow MVC to guess properly.
Also, you may have to whitelist properties for security reasons and/or to escape overly keen model validation.

MVC more than one form to submit

I have a standard Edit form view within MVC, and I need to place a user control, in this case Create inside the BeginForm, like below:
When the issue is that the Create ascx when the form is submitted does not fire it's action in the controller, what am I doing wrong?
<% using (Html.BeginForm())
{%>
<fieldset>
<legend>Tax</legend>
<p>
<label for="Name">
Name:</label>
<%= Html.TextBox("Name", Model.Tax.Name) %>
<%= Html.ValidationMessage("Name", "*") %>
</p>
<p>
<% Html.RenderAction("Create", "Mileage"); %>
</p>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
Here is the Create.ascx
<% using (Html.BeginForm())
{%>
<fieldset>
<p>
<label for="Distance">
Distance:</label>
<%= Html.TextBox("Distance", Model.Mileage.Distance)%>
<%= Html.ValidationMessage("Distance", "*") %><span class="field-validation-error"
id="field-validation-error-distance">*</span>
</p>
</fieldset>
<% } %>
You have nested forms in your resulting HTML. This will not work as expected. Remove the form from the inner view. The inner view will then be incomplete, so if you were using it as a stand-alone, you should make it shared, and create another view, which will just open the form, render the inner view, and close the form.
As a margin note: you are not using the default binder. You can if you want to, it will work even with nested objects (Html.TextBox("Mileage.Distance"), for example).
Nested form are not supported in HTML. See here: The FORM element
Every form must be enclosed within a FORM element. There can be several forms in a single document, but the FORM element can't be nested.
Either remove the form from your partial view and let the container view provide it, or remove the form from the view and add it to the partial thus making it independent of the parent.

How to select and pass data from the view

I'm starting to develop in ASP.NET and I can't find any example of a very simple use-case:
I've got some model objects displayed on a view.
I added a checkbox so that the user can choose the one he/she wants to see.
Then the user clicks on a link and he/she should see the model objects he/she selected displayed in another view.
1) What's the best way to get the selected items list?
At the moment I decorated my model with an IsSelected property because that's what I'd do in a ViewModel but that may not be the right answer.
2) How to pass the selected data to the next controller?
In all the examples that I've seen, data is "hardcoded" in the link and is per-object.
I haven't seen any example of a user-selection in any sample from the ASP MVC site.
EDIT: I'm afraid it wasn't that clear. What I've got is that:
<table style="width: 100%;">
<% foreach (Vehicle vehicle in Model)
{ %>
<tr>
<td>
<% 'Here be bound checkbox' %>
</td>
<td>
<%= Html.ActionLink("Show", "Index", "Map", vehicle.Name, null) %>
</td>
<td >
<%= Html.Encode(vehicle.Name) %>
</td>
<td >
<%= Html.Encode(vehicle.LastPositionReceived) %>
</td>
<td >
<%= Html.Encode(vehicle.Status) %>
</td>
<td >
<%= Html.Encode(vehicle.LocationDescription) %>
</td>
</tr>
<% } %>
</table>
By clicking on the Show link, I can already show a SINGLE item details.
Now I'd like to have the checkbox bound to a property of my model so that I can then trigger an action (with a link or a button) so that only the SELECTED items are sent to the controller.
This is the part that I haven't seen any examples about.
I could add
<% TempData.Add("Vehicles", Model); %>
somewhere and then the vehicles would be passed to the controller but I still need a way to bind the IsSelected property to the model (I don't want to hook up the Checked event and do it manually).
I hope that makes things a bit clearer.
(Thanks for the quick reply BTW ;) )
Honestly, you are not giving much information for us to give a proper answer. But here is a simple example of how you could accomplish what I think you described.
Suppose this is the part in your view where you are listing the selections to the user :
<%foreach (YourModel m in (List<YourModel>)ViewData["ModelsToList"]) {%>
<p>
<input name="selection" type="radio" value="<%=m.ID%>" id="model-<%=m.ID%>" />
<label for="model-<%=m.ID%>"><%=m.Name%></label>
</p>
<%}%>
Then you post that form to a controller action like this :
public ActionResult ShowSelectedModel(int selection) {
YourModel selectedModel = yourModelRepository.getModel(selection);
return View(selectedModel);
}
Then in your ShowSelectedModel view you can display the user's selection.
Was that what you had in mind?

Resources