Dropdownlist client side required validation (without model) - asp.net-mvc

View:
#Html.DropDownList("CategoryItems", null, new { #class = "ddlcs" })
#Html.ValidationMessage("CategoryItems")
Controller:
var cat = from s in db.CategoryDbSet
where s.IsActive == true
orderby s.CatName
select new { s.CatID, s.CatName };
var catListItems = cat.ToList()
.Select(c => new SelectListItem
{
Text = c.CatName,
Value = c.CatID.ToString()
})
.ToList();
catListItems.Insert(0, new SelectListItem
{
Text = "[--Select the category--]",
Value = ""
});
ViewBag.CategoryItems = catListItems;
I wish to enforce the required validation on the dropdown when someone selects the "Select the category" option during the save action. I am new to MVC framework and i am not sure where am i making the mistake ? This dropdown is not tied up with the Model.
Please suggest the soln.

This dropdown is not tied up with the Model.
That's the mistake. Validation in ASP.NET MVC works by decorating your view model properties with the respective attributes. For example if you want to make this dropdown required, you would decorate the corresponding property on your view model with the [Required] attribute.
So add the necessary properties to your existing view model:
public class MyViewModel
{
[Required]
public int? SelectedCategoryId { get; set; }
public IEnumerable<SelectListItem> Categories { get; set; }
... some other properties that your view might need
}
and then in your controller action populate this view model:
var model = new MyViewModel();
model.Categories = cat
.ToList()
.Select(c => new SelectListItem
{
Text = c.CatName,
Value = c.CatID.ToString()
}).ToList();
return View(model);
and in your view use the strongly typed versions of the helpers:
#Html.DropDownListFor(
x => x.SelectedCategoryId,
Model.Categories,
"[--Select the category--]",
new { #class = "ddlcs" }
)
#Html.ValidationMessageFor(x => x.SelectedCategoryId)

If you want only client side validation, you may do this:
$('form').validate({
rules:{
CategoryItems: 'required'
}
});
Working demo.
But I wouldn't suggest doing so as the client side validation is for better user experience and can be easily bypassed. The correct way to do this is described in Darin's answer, using dataannotations and view models.

Related

Formatting a Drop Down List in ASP.NET MVC

I'm building an app with ASP.NET MVC 4. I'm binding my model to a view. In my view, I need a drop down list. That drop down list needs to show quarters. The quarters should be displayed as "Q1", "Q2", "Q3", and "Q4". My model, only has quarter numbers. They are defined like this:
public List<short> Quarters = new List<short>() { get; set; }
public short? SelectedQuarter = null;
public void Initialize() {
Quarters.Add(1);
Quarters.Add(2);
Quarters.Add(3);
Quarters.Add(4);
}
Somehow, I need to prepend "Q" to each value. However, I'm not sure how to do this in ASP.NET MVC. How does someone do this?
Thanks!
Create a SelectList to be used by DropdownListFor() so that you bind the selected option to property SelectedQuarter, but display the 'friendly' name.
View model
public class MyViewModel
{
[Display(Name = "Quarter")]
[Required]
public short? SelectedQuarter { get; set; } // must be a property, not a field!
IEnumerable<SelectListItem> QuarterList { get; set; }
}
Controller
public ActionResult Edit()
{
MyViewModel model = new MyViewModel();
ConfigureViewModel(model);
return View(model);
}
public ActionResult Edit(MyViewModel model)
{
if(!ModelState.IsValid)
{
ConfigureViewModel(model);
return View(model);
}
// model.SelectedQuarter contains the selected value
}
private void ConfigureViewModel(model)
{
model.SelectedQuarter = new List<SelectListItem>()
{
new SelectListItem() { Value = "1", Text = "Q1" },
new SelectListItem() { Value = "2", Text = "Q2" },
new SelectListItem() { Value = "3", Text = "Q3" },
new SelectListItem() { Value = "4", Text = "Q4" },
}
}
View
#model MyViewModel
#using(Html.BeginForm())
{
#Html.LabelFor(m => m.SelectedQuarter)
#Html.DropDownListFor(m => m.SelectedQuarter, Model.QuarterList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedQuarter)
<input type="submit" />
}
Assuming you have this property:
public List<short> Quarters { get; set; }
Then in your view or any other consuming code you can generate a list of strings with something like:
model.Quarters.Select(q => "Q" + q)
or:
model.Quarters.Select(q => string.Format("Q{0}", q))
However, semantically it really feels like this belongs on a view model and not in consuming code. Ideally the view should only ever need to bind directly to properties on the view model, not transform those properties. Something like this:
public IEnumerable<string> QuartersDisplay
{
get { return Quarters.Select(q => string.Format("Q{0}", q)); }
}
Then consuming code can just bind to that property:
model.QuartersDisplay
(If the model is a domain model then I'd recommend introducing a view model between the domain and the view, since this wouldn't belong on a domain model.)
Thinking about this a little more... Do you want one property with both the displays and the backing values for the drop down list? That would likely be a IDictionary<short, string>, I imagine? Something like this:
public IDictionary<short, string> QuartersOptions
{
get { return Quarters.ToDictionary(q => q, q => string.Format("Q{0}", q)); }
}
In which case you'd bind to that property:
model.QuartersOptions
Keep in mind that a drop down list often binds to two things. The property which holds the list of possible values (which is what we've built here) and the property which holds the selected value (which remains your SelectedQuarter property).

MVC 5 DropDownListFor Database Linq;

Can anyone please tell me how to write Controller for C# (public ActionResult DropList()) for Drop Down List generate Linq I want convert this SELECT DISTINCT CouName FROM Locations; to Linq for my drop down list dynamically generate.
Chtml page how do I write in #Html.DropDownListFor("")
Models.Location
This code will generate a select list from an IQueryable GetAll() method, or you could use it on your entity directly using from c in _context.Set<Location>()
public SelectList GetAsSelectList()
{
var locs = from c in GetAll()
select new
{
Id = c.Id,
Name = c.Name
};
return new SelectList(locs, "Id", "Name");
}
Where Id is the Value field and Name is the Text field of the selectlist options.
This would be assigned to a model property:
var model = new MyModel
{
LocationList = GetAsSelectList();
}
You would pass the model to your View, and use DropDownListFor:
#Html.DropDownListFor(x => x.MyModel.Location, Model.LocationList)
Your model would also have a Location property which you would set to display a default value if you wanted to do that.
Assuming you model is named MyModel
Controller
public ActionResult Edit()
{
var couriers = // get your couriers from the database using your query
// Is better to assign this to a property in your view model, but ViewBag will do for now
ViewBag.CourierList = new SelectList(couriers);
var model = new YourModel();
}
View
#model YourModel
#using(Html.BeginForm())
{
#Html.DropDownListFor(m => m.CouriersName, (SelectList)ViewBag.CourierList)
}
As far as i have understood, you can do something like this:
public ActionResult DropList()
{
List<SelectListItem> objResult = new List<SelectListItem>();
var result = dbContext.Locations.Select(x=>x.CouName).Distinct().ToList();
foreach(var item in result)
{
SelectListItem temp = new SelectListItem();
temp.Text = item;
temp.Value = item;
objResult.Add(temp);
}
ViewBag.DropdownResult = objResult;
return View();
}
Dropdown in view:
#Html.DropDownListFor(m=>m.ModelLocations, ViewBag.DropdownResult as List<SelectListItem>)
Please modify the code as per your need.
using System.Web.Mvc;
...
public static List<SelectListItem> GetItemsForDisplay(string listName)
{
//your data access function should return a list of objects
return DAL.Table.SelectByName(listName)
.Select(x=> new SelectListItem{Text=x.DisplayName, Value=x.ID})
.ToList<SelectListItem>();
}

Display a value other than the one in the model

I have this text box defintion in my view
#Html.TextBoxFor(model => model.MaxNumberOfExtensions == "0" ? "Unlimited" : model.MaxNumberOfExtensions, new { required = "required", id = "maxNumberOfExtensions" })
What I am trying to do is say,
If the value MaxNumberOfExtensions is 0 then display 'Unlimited' in
the text box, otherwise display, the value in the field
MaxNumberOfExtensions
This does not work at runtime. It gives the error
Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
What is the correct way of doing this?
Such complex lambda expressions are not supported by the HTML helpers. They only support property access and indexer access expressions.
The correct way is to use a view model of course. So you would have a property which will already contain the required text based on the value of your domain model.
For example:
public class MyViewModel
{
public string MaxNumberOfExtensions { get; set; }
}
and then in your controller action rendering this view:
public ActionResult SomeAction()
{
SomeDomainModel model = ...
MyViewModel viewModel = new MyViewModel();
viewModel.MaxNumberOfExtensions = model.MaxNumberOfExtensions == "0" ? "Unlimited" : model.MaxNumberOfExtensions;
return View(viewModel);
}
and then in the view:
#model MyViewModel
...
#Html.TextBoxFor(x => x.MaxNumberOfExtensions, new { required = "required", id = "maxNumberOfExtensions" })
Alternatively if your application is currently not following best practices (not using view models) you could write a custom template where you could perform this task.
For example, add the following template in ~/Views/Shared/EditorTemplates/FormattedNumberOfExtensions.cshtml:
#model string
#{
var value = Model == "0" ? "Unlimited" : Model;
}
#Html.TextBox("", value, new { required = "required", id = "maxNumberOfExtensions" })
and then in your view:
#Html.EditorFor(x => x.MaxNumberOfExtensions, "FormattedNumberOfExtensions")

Html.DropDownList populating

I have a drop down in my MVC project.
#Html.DropDownList("Chart Type", new List<SelectListItem>
{
new SelectListItem{ Text="Horizontal", Value = "Horizontal" },
new SelectListItem{ Text="Vertical", Value = "Vertical" },
new SelectListItem{ Text="Pie", Value = "Pie" }
},
new { #class = "chzn-select", #multiple ="true", #style="width:350px;"} )
This puts hard coded values in the list.
If I want to get the values from a database, what is the best approach?
Can I have the Html.DropDownList reference a sql query or SP for populating the list?
Create a view model with (at least) two properties:
public class ViewModel()
{
public List<SelectListItem> Items { get; set; }
public string SelectedItem { get; set; }
}
In your controller, make the call to your data source and populate the Items property of the view model and pass it to the view.
public ActionResult Index()
{
var viewModel = new ViewModel();
viewModel.Items = database.GetChartTypes();//or however you're accessing your data
return View(viewModel);
}
Then strongly type your view and use the DropDownListFor helper
#model MyProject.ViewModel
...
#Html.DropDownListFor(m => m.SelectedItem,
Items,
"--Select a Chart Type--",
new { #class = "chzn-select",
#multiple ="true",
#style="width:350px;"
});
You do not want the UI making calls to your data layer.
What you would want is the controller either calling a "service" that then calls the repository, or the controller calling the repository to get the list.
Once it has the list, it will pass that to the view using a ViewModel or the ViewBag.

ASP.Net MVC Drop Down List

I am developing an ASP.Net MVC 3 Web application and believe my method of returning a list of items to a drop down list in the View is a bit long winded. Let me explain.
I have a ViewModel which contains an Equipment Entity and a SelectList to display a list of Categories.
public class AddEquipmentViewModel
{
public Equipment equipment { get; set; }
public SelectList categoryList { get; set; }
}
In the GET create method of my Equipment Controller, I return my ViewModel to the view, see below:
//Add new select list item named 'Please select option' to the top of list
var categoryList = categoryService.GetAllCategories();
var categorySelectListItems = categoryList.Select(c => new SelectListItem { Value = c.categoryID.ToString(), Text = c.categoryTitle }).ToList();
categorySelectListItems.Insert(0, new SelectListItem { Text = "Please select option", Value = string.Empty });
AddEquipmentViewModel viewModel = new AddEquipmentViewModel
{
equipment = new Equipment(),
categoryList = new SelectList(categorySelectListItems.ToList(), "Value", "Text")
};
I know I could discard the extra code before I create an instance of my ViewModel and just assign my Category List to the relevant ViewModel property like so
categoryList = new SelectList(categoryService.GetAllCategories(), "categoryID", "categoryTitle")
However, this then just returns a list of categories to my drop down list in my View, whereas, I would like to add a new SelectListItem, ie, "Please select option".
I just feel that my approach to manually adding a new SelectListItem to my SelectList is a bit cumbersome and I would greatly appreciate if someone could share a better method?
Thanks for your time.
<%= Html.DropDownList("name", new SelectList(...), "Your Combobox default message")%>
Hope it helps

Resources