ASP.Net MVC 3 CheckBoxList from database - asp.net-mvc

i have a table called
tb_role
id role
1 admin
2 user
3 viewer
and for the View is like this :
<div style="width:50%; float:right;">
<legend>User Role</legend>
<table>
<tr>
<th>Role</th>
</tr>
<tr>
<td align="center"><input type="checkbox" id="CBRole"/></td>
</tr>
</table>
</div>
I want to ask, how to list my checkbox(CBRole) from my table? so my CBRole is listed from my table.
thanks a lot
EDIT
assumed that i have Roles table like this :
tb_role
RoleId Role_Name
1 SalesCreate
2 SalesEdit
3 AgentCreate
4 AgentEdit
i want to list role for Sales in checkbox (SalesCreate and SalesEdit, so its only have 2 checboxes), how to do that ?
thanks

From your controller you populate your view model with these properties:
Your RoleViewModel
public IList<int> RolesSelected { get; set; }
public MultiSelectList Roles { get; set; }
From controller that handles the Get call (/roles/edit/1 for example)
model.RolesSelected = new List<int>();
//here the code to populate the eventually already selected roles (update case)
model.Roles = new MultiSelectList(repository.GetRoles(), "Id", "Name", model.SettoriSelected);
then in your view (inside a form tag) you will do something like this
#foreach (var item in Model.Roles)
{
<div class="MyClass">
<label for="#item.Value" class="MyClassForCheck">
<input type="checkbox" id="#item.Value" name="RolesSelected" value="#item.Value" #(item.Selected ? "checked" : "") />#item.Text</label>
</div>
}
in the controller that answer the Post part you will access the RolesSelected with the IDs checked
In the example I have put a div, but yuo can change it to what you like obviously. Hope it helps

You probably want to have something that looks like the following post on StackOverflow, Enum to CheckBox

Related

MVC Form returns null model back to controller [duplicate]

This question already has answers here:
Submit a List from View to Controller
(2 answers)
Closed 5 years ago.
View has a list of items, each with a checkbox. Purpose of the form is to check the boxes then return the list to the db. I expect to see the PickList model in the ViewModel populated with the hidden seedid and the checkbox values, but the form always submits with the PickList as null.
#model Inventory.ViewModels.ExtractionViewModel
<div class="col-md-4">
<button class="btn btn-primary" type="submit" form="pick-list-form">Update Pick List</button>
</div>
#using (Html.BeginForm("UpdatePickList", "Extraction", FormMethod.Post, new { #id = "pick-list-form" }))
{
<table class="table">
<tr>
<th>
Seed Reference
</th>
<th>Extracted?</th>
</tr>
#foreach (var item in Model.PickList)
{
<tr>
<td>
#Html.HiddenFor(modelItem => item.ExtractionId)
#Html.HiddenFor(modelItem => item.SeedId)
#Html.DisplayFor(modelItem => item.SeedId)
</td>
<td>
#Html.CheckBoxFor(modelItem => item.IsExtracted)
</td>
</tr>
}
</table>
}
View Model
public class ExtractionViewModel
{
public ExtractionDTO Extraction{ get; set; }
public List<PickListDTO> PickList { get; set; }
}
Pick list model
public class PickListDTO
{
public int ExtractionId { get; set; }
public int SeedId { get; set; }
public bool IsExtracted { get; set; }
}
Using #Html.DisplayFormay cause the model to be sent back as NULL. You can use #Html.TextBoxFor.
And just to remind:
Use HiddenFor when you want to provide posted data that the user does not need to be aware of.
Use DisplayFor when you want to show records but not allow them to be editted.
Use TextBoxFor when you want to allow user input or allow the user to edit a field.
I hope it helps you!

CheckBoxList ASP.Net MVC 3 from database

assumed that i have Roles table like this :
tb_role
RoleId Role_Name
1 SalesCreate
2 SalesEdit
3 AgentCreate
4 AgentEdit
i want to list role for Sales in checkbox (SalesCreate and SalesEdit, so its only have 2 checboxes). I made my tb_role using aspnet configuration, so it doesn't use entities.
here my Controller:
RegisterModel account = new RegisterModel();
account.Roles = new MultiSelectList(Roles.GetAllRoles());
and my View:
<td><select id="Roles" name="Roles">
<option>Sales</option>
<option>Agent</option>
</select>
</td>
#foreach (var item in Model.Roles)
{
<label for="#item.Value">
<input type="checkbox" id="#item.Value" name="RolesSelected" value="#item.Value" #(item.Selected ? "checked" : "") />#item.Text</label>
}
when i run my project, my checkbox list all of the roles in tb_role. I want that if I choose Sales, my checkbox list all the Roles for Sales (SalesCreate and SalesEdit). how to do that ?
thanks a lot
Couple of ways to do this. One way is this:
Surround the <select> with a <form> tag and do a submit on change.
in your controller:
public ActionResult Index(..., string role)
{
//... rest of your code
RegisterModel account = new RegisterModel();
account.Roles = new MultiSelectList(Roles.GetAllRoles().Where(w => w.StartsWith(role));
//... rest of your code
}

ASP.NET MVC FormCollection TextArea

I have a textarea that represents a description field. The descriptions have commas so when trying to split the field's descriptions the data is not parsed correctly. How can I get each row's description correctly.
var DescList = FormValues["Item.Description"].Split(',').Select(item => item).ToList<string>();
//will not work for obvious reasons. Comma delimited FormCollection has commas to identify separate row data.
It seems like Microsoft designed the FormsCollection without the textarea control in mind. A text area with commas will not work when trying to access each value. What is interesting is that the _entriestables property has it in the perfect format but they chose to make it a private property. Very frustrating.
`
Here is the important part of my viewmodel.
public class TenantViewModel
{
public Tenant Tenant { get; set; }
public Site Site { get; set; }
}
My view is populated like this:
if (Model != null && Model.Tenant != null && Model.Tenant.Site != null && Model.Tenant.Site.Count() > 0)
{<div class="detailsbox_view">
<table id="tblTenantSites">
<tr>
<th>#Html.LabelFor(item => item.Site.Title)</th>
<th>#Html.LabelFor(item => item.Site.Description)</th>
</tr>
#foreach (var Item in Model.Tenant.Sites)
{
<tr>
#Html.HiddenFor(modelItem => Item.SiteId)
<td>
#Html.EditorFor(modelItem => Item.Title)
</td>
<td>
#Html.TextAreaFor(modelItem => Item.Description, new {#width="400" })
</td>
</tr> }
</table>
As you see this site table is a child of Tenant object. This child record does not get automatically updated using this method but the Tenant data does automatically get updated. This is the reason I tried the FormColelction instead.
Is there something I am missing to make this work?
try with this useful function
ValueProviderResult Match=FormCollection.GetValue("ValueProvider");
When you have multiple fields with the same name attribute, they'll come back into your FormCollection as an array. So upon posting a view like this:
<form action="/Home/MyAction">
<textarea id="row_one_description" name="description">
First row's description
</textarea>
<textarea id="row_two_description" name="description">
Second row's description
</textarea>
<input type="submit" value="Submit" />
</form>
you could do something like this in your action
[HttpPost]
public ActionResult MyAction(FormCollection collection)
{
var descriptionArray = collection["description"];
string firstRowDescription = descriptionArray[0];
string secondRowDescription = descriptionArray[1];
}
I must note that this is not the recommended way of dealing with posted data. You should instead be building your view using data from a view model and using strongly typed html helpers to render your controls. That way when you post, your action can take the ViewModel as a parameter. Its properties will be automatically bound and you will have a nice object to play with.
[HttpPost]
public ActionResult MyAction(MyViewModel viewModel)
{
foreach (var row in viewModel.Rows)
{
string description = row.Description;
}
}
EDIT
I'm still assuming a lot about your ViewModel but perhaps try this:
<table id="tblTenantSites">
<tr>
<th>#Html.LabelFor(model => model.Site.Title)</th>
<th>#Html.LabelFor(model => model.Site.Description)</th>
</tr>
#for (var i = i < Model.Tenants.Sites.Count(); i++) {
<tr>
#Html.HiddenFor(model => model.Tenants.Sites[i].SiteId)
<td>
#Html.EditorFor(model => model.Tenants.Sites[i].Title)
</td>
<td>
#Html.TextAreaFor(model => model.Tenants.Sites[i].Description, new { #width="400" } )
</td>
</tr>
}
</table>
You could also try ,
string Match=FormCollection.GetValue("ValueProvider").AttemptedValue;

ASP.NET MVC 3 Save and edit from the same form

We have a form and depending upon the circumstances we want to switch between an add operation and an update operation from the same form. Below is a cut down version of our form.
Effectively the "Order number" textbox is disabled and can never be edited in this form. Now, the scenario is a bit like this:
The first time the user lands on this form, the "Order number" text box is blank.
The user enters a customer name and submits the form.
At this point in the controller action, we get the max value of order number in the database and increment the order number by 1 . We then add that new record in the database.
If that operation is successful, we update the current form and the "Order Number" textbox should now be updated with the order number created in the previous step AND also what should happen is that we are now in Edit mode.
Say the user then updates the "Customer name" and submits the form, the record in the database should be updated in this instance.
Now for some code:
The View:
<%: Html.TextBox("OrderNumber", Model.OrderNumber == 0 ? "" : Model.OrderNumber.ToString(), new { #disabled = "true" })%>
The controller:
public ActionResult Index()
{
var customerOrderModel = new CustomerOrderModel();
return View(customerOrderModel);
}
public ActionResult Add(CustomerOrderModel customerOrderModel, FormCollection values)
{
// We write the logic for either the add or update.
return this.View("Index", customerOrderModel);
}
I have removed the code from the Add action because from putting breakpoints we know that the "// We write the logic for either the add or update." is not the problem.
Now where we are having trouble is this. We can add the new entry in the table following which the "Order Number" field gets updated and is displayed correctly. However, after we change the customer name and try to update, the customerOrderModel passed into the "Add" action shows that the order number being passed is 0(which is our default in the system and which is used to determine if we are performing an add or update operation).
So the question is why is our textbox getting updated, which would seem to indicate that our model is getting updated, but then when we try to submit, the correct model doesn't get passed in? Moreover, why is it that the Index action doesn't get hit after the "Add" action is completed? What do we have to do to get things to work the way we want them to?
Model
namespace Demo.Models
{
public class Order
{
public int OrderId { get; set; }
public string CustomerName { get; set; }
}
public class OrderDb:DbContext
{
public DbSet<Order> Orders { get; set; }
}
}
View
#model Demo.Models.Order
<form action="/" method="post">
<table>
<tr>
<td>#Html.LabelFor(m=>m.OrderId)</td>
<td>
#Html.EditorFor(m => m.OrderId)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m=>m.CustomerName)
</td>
<td>
#Html.EditorFor(m=>m.CustomerName)
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" name="submit" value="submit" />
</td>
</tr>
</table>
</form>
Action
public ActionResult Index(Order o)
{
if (o.CustomerName != null)
{
using (OrderDb db = new OrderDb())
{
db.Entry(o).State = o.OrderId == 0 ? EntityState.Added : EntityState.Modified;
db.SaveChanges();
ModelState.Clear();
}
}
return View(o);
}
This is because HtmlHelpers look to ModelState for values first and then uses the values you explicitly use.
So when you add the entity you get ["Id"]=0 inside your model state.
So solve you have to clear your ModelState with .Clear() after a successful add.

DropDownList setting selected item in asp.net MVC

I noticed what seems to me a bug in asp.net MVC or simply I am doing something wrong. I am currently using 1.0 so maybe this is something that will be addressed in the 2.0 release. But either way, here we go.
When I my view model has a property which is the same name as the declared id for a drop down list, the selected item is ignored and the rendered html has nothing selected.
Not sure if I did something wrong, but changing the name of the id fixes the problem. I simplified the example, hope it is clear, otherwise please let me know.
Here is my view where the declared ID is the same name as my list in the model:
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<%= Html.DropDownList("IsMultipleServicers", Model.IsMultipleServicers) %>
</td>
</tr>
</table>
And the rendered Html
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<select id="IsMultipleServicers" name="IsMultipleServicers">
<option value="false">No</option>
<option value="true">Yes</option>
</select>
</td>
</tr>
</table>
Now lets make a small change. I will change the declared id to be something different.
Here is my View:
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<%= Html.DropDownList("MultipleServicers", Model.IsMultipleServicers) %>
</td>
</tr>
</table>
And now the rendered html:
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<select id="IsMultipleServicers" name="IsMultipleServicers">
<option value="false">No</option>
<option selected="selected" value="true">Yes</option>
</select>
</td>
</tr>
</table>
Notice that now I get a selected option which would be the second element in the List.
Here is my ViewModel just to tie everything together:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCProject.Models.ViewModels.Service
{
public class ServiceViewModel : ViewModel
{
public List<SelectListItem> IsMultipleServicers { get; set; }
}
}
Here is my action:
[AcceptVerbs(HttpVerbs.Get)]
public virtual ActionResult Service()
{
return View(new ServiceViewModel()
{
IsMultipleServicers = BuildBooleanSelectList(true)
};
}
private List<SelectListItem> BuildBooleanSelectList(bool isTrue)
{
List<SelectListItem> list = new List<SelectListItem>();
if (isTrue)
{
list.Add(new SelectListItem() { Selected = false, Text = "No", Value = "false" });
list.Add(new SelectListItem() { Selected = true, Text = "Yes", Value = "true" });
}
else
{
list.Add(new SelectListItem() { Selected = true, Text = "No", Value = "false" });
list.Add(new SelectListItem() { Selected = false, Text = "Yes", Value = "true" });
}
return list;
}
I think the problem is a confusion regarding the DropDownList overloads:
Html.DropDownList(string name) looks for a view model property of name and type IEnumerable<SelectListItem>. It will use the selected item (SelectListItem.Selected == true) from the list, unless there is a form post value of the same name.
Html.DropDownList(string name, IEnumerable<SelectListItem> selectList) uses the items from selectList, but not their selected values. The selected is found by resolving name in the view model (or post data) and matching it against the SelectListItem.Value. Even if the value cannot be found (or is null), it still won't use the selected value from the list of SelectListItems.
Your code uses the second overload, but specifies a "value" property that doesn't exist ("MultipleServicers").
To fix your problem, either use the first overload:
<%= Html.DropDownList("IsMultipleServicers") %>
Or, add a string MultipleServicers property to your view model and populate it in your controller. I'd recommend this solution as it gets around several problems with initial display, post display and mapping the post data to a view/post model:
public class ServiceViewModel : ViewModel
{
public string MultipleServicers { get; set; }
public List<SelectListItem> IsMultipleServicers { get; set; }
}
Then for your HTML:
<%= Html.DropDownList(Model.MultipleServicers, Model.IsMultipleServicers) %>
This technique maps into MVC2, as well:
<%= Html.DropDownListFor(x => x.MultipleServicers, Model.IsMultipleServicers) %>
I encountered this same problem using the Html.DropDownList(string name, IEnumerable selectList) overload. It appears that my model has a property of the same name as the name of the drop down list. This being the case, MVC favored the property value of my Model over the Selected property of each entry in the IEnumerable.
The solution was to use a name for the dropdown list that does not match up to a property name. Another solution would be to write my own extension method that ignores model and view state and instead always honor the selected property.
The DropDownList helper pulls the default value from the model. In the first case, the value in the model corresponding to the name is a SelectList -- this doesn't match any of the items in the list, it is the list, so no value is chosen. In the second example, your model does not include a property with that name so the value from the model can't be used and it defaults to the state indicated in the SelectList itself. Typically, I will have a property on the model for the selected value -- this becomes the default -- and another property representing the potential values for the list.

Resources