I have Gender attribute as tiny int in Db for employee. When user create new employee i want him to choose male/female (which is working properly) by clicking on radio button. Everything is working fine (create and edit) but i want to display in form (for index, details and delete) not 1 or 2, but male/female. there should be some if statement in view but i'm not sure where to put it or how to write correct one ...
any idea?
Thanks!
this is part of code from model:
This one is from details.cshtml:
If you want to avoid having extra properties on your model or adding stuff to your viewbag you can write it inline using razor syntax like below..
<div class="display-field">
#if (model.GENDER == 0){ #Html.Raw("Male") }
#else if (model.GENDER == 1){ #Html.Raw("Female") }
</div>
That's off the top of my head so you might need to check the exact syntax but i think that's close. It will also just dump "Male" or "Female" inside the div, you might want to put it in a label or p tag at least.
This however isn't the approach I would use in a production app, throughout the code i would use a gender enum to give meaning to your bit value and extend enum to include a description that you can parse for presentation purposes.
I think from what u have said u can write it inline using the razor syntax like below in ur details.cshtml
<div class="display-field">
#if(model.GENDER ==0)
{
<label>Male</label>
}
else if(model.Gender==1)
{
<label>Female</label>
}
</div>
I think this must be enough for displaying the Gender in details page.plz comment if u need any help
Use a condition ? true : false selector
int gender = 1; // assumed male
String genderDesc = (gender == 1) ? "Male" : "Female";
You Could Make this a Drop Down field? In your controller do:
ViewBag.Gender = new[]
{
new SelectListItem { Text = "Male", Value = "1" },
new SelectListItem { Text = "Female", Value = "2" }
}.WithEmpty();
The WithEmpty() will give you a blank option or without it will select the top one.
#Html.DropDownListFor(m=> m.Gender, (Ienumarable<SelectListItem>)ViewBag.Gender);
This way the user will see Male and Female but the value will be bound to your model using the value which is 1 or 2.
I'd advise that you create a ViewModel class to represent the Employee entity in a View-friendly format decoupled from your database model and present it in a strongly typed view so you can return it from the controller.
Hint: Have the Gender property represented as a string in the ViewModel and do the conversion from byte to the string representation in your controller
You may put the code in your controller as e.g:
public ActionResult EmployeeDetails(int id)
{
//retrieve the entity from the DB
//set other employee properties here.
//I'm assuming you have set males to 2 and females to 1
...
employeeViewObject.Gender = employeeObjectFromDB.Gender.Value==2?"Male":"Female";
return View(employeeObjectFromDB);
}
Your strongly typed view will not have trouble displaying the gender while saving you the dirt of mixing code and mark-up as:
<p>model.Gender</p>
or
Html.DisplayFor(model=>model.Gender)
Related
I was using asp-items="#Html.GetEnumSelectList(typeof(Salary))" in my Razor view with a select tag, to populate the list values based on the enum Salary.
However, my enum contains some items which I would like to have spaces within. E.g. one of the items is PaidMonthly, but when I display this using Html.GetEnumSelectList, I would like it to be displayed as "Paid Monthly" (with a space in it)
I tried using the Description attribute over each member in the enum, however when the select box renders it uses the raw value only.
Can anyone please help me out with this matter?
(My Code sample) -> Using ASP.NET Core 1.0
Razor View:
<select asp-for="PersonSalary" asp-items="#Html.GetEnumSelectList(typeof(Enums.Salary))">
</select>
Enum Salary:
public enum Salary
{
[Description("Paid Monthly")]
PaidMonthly = 1,
PaidYearly = 2
}
I managed to solve it. I just had to use the other method of GetEnumSelectList<>, and in the Razor view we need to use the Display attribute.
Here is the code:
Razor View:
<select asp-for="PersonSalary" asp-items="Html.GetEnumSelectList<Enums.Salary>()"></select>
Enum Salary:
public enum Salary
{
[Display(Name="Paid Monthly")]
PaidMonthly = 1,
PaidYearly = 2
}
I am new to MVC and trying a test application to get my feet wet. Part of this application is to generate a form with a drop down box. I use the
#Html.DropDownListFor() to generate this, and on the create form the drop down works fine. But when I go to the edit form the model value is not passing to the drop down.
SelectList Item
public static string[] OnOffList()
{
var ret = new string[] { "On", "Off" };
return ret;
}
Form code
#Html.DropDownListFor(model => model.ServiceCondition, new SelectList(OnOffDropDownHelper.OnOffList()))
For this instance assume that model.ServiceCondition = "Off".
For some reason whenever I call this form the dropdown value is always "On", it seems to be completely ignoring the model value.
I have also tried this
#Html.DropDownListFor(model => model.ServiceCondition, new SelectList(OnOffDropDownHelper.OnOffList(), "Off"))
to mandate the "Off" value, but it is still coming up as "On" as the selected value in the drop down.
I would like to reiterate, I do know that the model value is "Off", and I created an identical "Create" form using the same #Html.DropDownListFor() and it was able to pass the value to the model just fine.
Like I said, I am new to MVC so any help would be greatly appreciated.
Thanks.
I think you have to set the IsSelected property. This always works for me:
First, just put a property in your model to tidy up the View code:
public List<SelectListItem> OnOffDDL
{
get
{
return OnOffDropDownHelper.OnOffList()
.Select(s => new SelectListItem
{
Text = s,
Value = s,
Selected = ServiceCondition == s
})
.ToList();
}
}
Then do:
#Html.DropDownListFor(model => model.ServiceCondition, model.OnOffDDL)
This may be a little overkill, but is helpful if your model could have different options based on the model itself (even though for now it is just On and Off). Like in the future if certain items could have a "Standby" mode, etc, where you would be getting the actual options from a database for that particular item.
Use a SelectList for the source, so your Model could have:
public List<SelectListItem> OnOffList{ get; set; }
Then populating the Model in your controller like:
model.OnOffList.Add(new SelectListItem()
{
Text = "On",
Value = "On"
});
...etc.
Then you can set the selected item like:
#Html.DropDownListFor(m => m.ServiceCondition, new SelectList(Model.OnOffList(), "Value", "Text", Model.ServiceCondition))
Turns out to be a rookie mistake on my part.
Who ever designed the databese had the field ServiceCondition as nchar(8) leaving white space at the end of the "on ", "Off " values.
A .Trim() in the field in question fixed the issue.
Thanks a ton for the help.
I'm having problems with the HtmlHelper, RadioButtonFor and an enum in my model. I have a strongly typed view, and I want the checkboxes to toggle my enum property.
Enum.cs
public enum Values{
Value1,
Value2
}
Model.cs
public class Model{
public Values MyProp{ get; set; }
;
View.cshtml
#Html.RadioButtonFor(model => model.MyPropi, Values.Values1)
Controller.cs
public ActionResult WizardFirstStep()
{
var model = new Model();
return View(model);
}
If I set the MyProperty value in the controller, the RadioButton is checked as expected. But after a post to the next wizard step, which gets the model as parameter, the property isn't set.
If it will help you to understand what I mean: If it would be C# and WPF I would use a IValueConverter.
btw: I use a HtmlHelper.ActionLink to get the model to the controller.
Thanks in advance
Try this, it should work as I have done the same thing before:
#Html.RadioButtonFor(model => model.MyProp, (int)Values.Values1, model.MyProp == Values.Values1)
Notice the cast to int, it ensures the correct value is used for html.
EDIT: Sorry, I think you also need the third parameter to ensure the correct radio button is set when loading the view.
I also assumed MyPropi was a typo and changed it to MyProp, please ensure this matches up correctly at your end
Sorry for any inconvenience. After posting here, I found the solution very quickly. My ActionLink was not submitting the #Html.BeginForm form. So i changed my radiobutton to:
#Html.RadioButtonFor(model => model.MyPropi, Values.Values1, new{ onClick = "this.form.submit();" })
which submits the correct value to my controller. For the moment this is okay. Maybe the ActionLink can post back the form data.
For Aspx pages:
<%:Html.RadioButtonFor(m => m.YourProp, Selected value of your enum like : demo1.enum1.value2)
Hi I am quiet new on MVC 3 with C#. I am using entity framework and database first approach to generate code automatically. But the problem is, I tried to find information about inserting checkboxes in MVC3 using C# code but I could not get helpful website.
I can insert the check box using HTML tags:
<input type="checkbox" name="Science" id="s1" value="Science" />
<input type="checkbox" name="Biology" id="b1" value="Biology" />
<input type="checkbox" name="Chemistry" id="c1" value="Chemistry" />
But how do I insert the check box value inside the database and validate that only one single checkbox is selected?
e.g I have a table named Paper where I have:
Paper_Title - textbox
Paper_Details - textbox
Category - Checkboxes (e.g. Science, biology, chemistry)
Comments - textbox.
Submit-button
Use radio button and then have an enum for Categories(say enumCategories). Have a model Category of type enumCategories and then in the postback set the model based on which radio button is checked.
Hope this gives you an elaborate idea on the approach.
I don't think that checkboxes are what you need here, they're more used for multi-selectable items. Either radio buttons or a dropdown would be better suited. Personally, I'd say a dropdown is better for you as there's already an editor template built for it, example:
Model:
I have added the following to properties
public string Category { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
In the load method I have put two sample categories in there:
Categories = new List<SelectListItem>
{
new SelectListItem
{
Selected = false,
Text = "Chemistry",
Value = "Chemistry"
},
new SelectListItem
{
Selected = false,
Text = "Science",
Value = "Science"
}
};
View:
#Html.DropDownListFor(m => Model.Category, Model.Categories)
This maybe very simple but I cant seem to sort it out on my own.
I have created a simple db and entity modal that looks like this
I am trying to create an Create form that allows me to add a new Order. I have a total of 3 tables so what I am trying to do is have the form allowing the person to enter Order date and also has a dropdown list that allows me to select a product from the product table
I want to be able to create a Add or Edit view that allow me to insert the OrderDate into the OrderTable and also insert the OrderID and selected ProductID into OrderProduct.
What steps do I need to do here.
I have created an OrderController and ticked the "Add Actions" and than added a Create View which looks like this
#model Test.OrderProduct
#{
ViewBag.Title = "Create2";
}
<h2>Create2</h2>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>OrderProduct</legend>
<div class="editor-label">
#Html.LabelFor(model => model.OrderID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OrderID)
#Html.ValidationMessageFor(model => model.OrderID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ProductID)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ProductID)
#Html.ValidationMessageFor(model => model.ProductID)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
This creates the view that contains a textbox for both OrderID and ProductID however no date.
My controller CreatePost hasnt been changed
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
var data = collection;
// TODO: Add insert logic here
// db.Orders.AddObject(collection);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
My questions are,
1.How do I swap out ProductID textbox to be a dropdown which is populated from Product
2.How do I get the data from FormCollection collection? I thought of just a foreach however I dont know how to get the strongly typed name
Any help for a newbie would be very helpful.
Thank you!
First thing's first, don't bind to the Order entity. Never bind to an EF object, always try and use a ViewModel. Makes life simpler for the View, and that is the goal here.
So, have a ViewModel like this:
public class CreateOrderViewModel
{
public int OrderId { get; set; }
public DateTime OrderDate { get; set; }
public int SelectedProductId { get; set; }
public IEnumerable<SelectListItem> Products { get; set; }
}
That's it right now.
Return that to your View in your [HttpGet] controller action:
[HttpGet]
public ActionResult Create()
{
var model = new CreateOrderViewModel
{
Products = db.Products
.ToList() // this will fire a query, basically SELECT * FROM Products
.Select(x => new SelectListItem
{
Text = x.ProductName,
Value = x.ProductId
});
};
return View(model);
}
Then to render out the list of Products: (basic HTML excluded)
#model WebApplication.Models.CreateOrderViewModel
#Html.DropDownListFor(model => model.SelectedProductId, Model.Products)
The only thing i don't know how to do is bind to the DateTime field. I'm guessing you would need an extension method (HTML Helper) which renders out a Date Picker or something. For this View (creating a new order), just default to DateTime.Now.
Now, onto the [HttpPost] controller action:
[HttpPost]
public ActionResult Create(CreateOrderViewModel model)
{
try
{
// TODO: this manual stitching should be replaced with AutoMapper
var newOrder = new Order
{
OrderDate = DateTime.Now,
OrderProduct = new OrderProduct
{
ProductId = SelectedProductId
}
};
db.Orders.AddObject(newOrder);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Now, i also think your EF model needs work.
To me (in English terms), a Product can have many orders, and an Order can have many Products.
So, it should be a many-to-many. Currently it's a 1-1 with a redundant join table. Did you generate that from a DB? If so, your DB possibly needs work.
You should have a navigational property called Products on the Order entity, which references a collection of Product, made possible by a silent join to the join table in the many-to-many.
This also means you no longer have a DropDownList, but a MultiSelectDropDownList.
Thanks Craig. Your few days (as at time of posting) of MVC have solved my few days of trying to get the selected value back from DropDownListFor.
I had no problem in the Create view in getting the selected value of the DDLF, but the Edit view was a completely different matter - nothing I tried would get the selected value back in the Post. I noticed the selected value was lurking in the AttemptedValue of the ModelState, and so Dr.Google referred me here.
I had this in my view
#Html.DropDownList(model => model.ContentKeyID, Model.ContentKeys, Model.ContentKeyName)
where ContentKeys is a SelectList populated from the DB via a ViewModel, and ContentKeyName is the curently selected name.
The wierd thing is, I have another DDL on the view populated in an identical manner. This one works. Why, I don't know. It is the second DDL on the form, but I can't see that making a difference.
I read somewhere else it might have been that I was using Guids as the Id, but that didn't seem to make a difference - I changed to Int32, but don't think I had to - I think it's enums that disagree with DDLF. Nullables seemd to make no difference either.
Now that I've added the form collection to my Post ActionResult, and get the selected value using
-view
#Html.DropDownList("ContentKey", Model.ContentKeys)
-in controller (Post)
contentKeyId = int.Parse(form.GetValue("ContentKey").AttemptedValue);
all is good, and I can get on with more exciting things. Why is that the simplest things can hold you up for so long?
I have been struggling with this over the last day or so too. I'll share my limited knowledge in the hope that it will help someone else.
Note that I use a singleton with a pre-populated list to keep my example application small (i.e. no EF or DB interaction).
To show the ProductList you will need to have a ViewBag or ViewData item which contains the ProductList.
You can set this up in the Controller with something like
ViewData["ProductList"] = new SelectList(Models.MVCProduct.Instance.ProductList, "Id", "Name", 1);
Then update your View to something like:
<div class="editor-field">#Html.DropDownList("ProductList")</div>
For the Post/Create/Update step you need to look into the FormCollection to get your results. Reading other posts it sounds like there used to be a bug in here, but it's fixed now so ensure you have the latest. For my example I have a DropDownList for Product so I just get the selected Id and then go searching for that Product in my list.
[HttpPost]
public ActionResult Create(FormCollection form )//Models.MVCOrder newOrder)
{
MVC.Models.MVCOrder ord = Models.MVCOrder.Instance.CreateBlankOrder();
//Update order with simple types (e.g. Quantity)
if (TryUpdateModel<MVC.Models.MVCOrder>(ord, form.ToValueProvider()))
{
ord.Product = Models.MVCProduct.Instance.ProductList.Find(p => p.Id == int.Parse(form.GetValue("ProductList").AttemptedValue));
ord.Attribute = Models.MVCAttribute.Instance.AttributeList.Find(a => a.Id == int.Parse(form.GetValue("attributeId").AttemptedValue));
UpdateModel(ord);
return RedirectToAction("Index");
}
else
{
return View(ord);
}
}
I've only been working on MVC3 for the last few days, so any advice on improving the above would be appreciated.