In view I have and I am not able to validate the below mvc code
#Html.DropDownList("PriorityId", (IEnumerable<SelectListItem>)#ViewBag.Priority, "--Please Select One--", new { #id = "ddlPriority", #class = "dropdown" })
In Controller I have
private void PriorityDropdownList()
{
IEnumerable<SelectListItem> priorityDropdownlist =_PriorityObj.PriorityDropdownlistGet();
if (priorityDropdownlist != null)
{
ViewBag.Priority = priorityDropdownlist;
}
}
Try to avoid using ViewBag / ViewData for sending data to your view. Use strongly typed views & ViewModels with data annotations as required for validation.
public class CreateIssueVM
{
[Required]
public string Name { set;get;}
public List<SelectListItem> Priorities { get; set; }
[Required]
public int SelectedPriority { set;get;}
}
Here i have decorated the Name and SelectedPriority properties with Required attributes. That means, user needs to enter these, otherwise, it will bring up the validation message of form submit.
In your GET action , set the collection property value and send that to the view.
public ActionResult Create()
{
var vm=new CreateIssueVM();
vm.Priorities =GetPriorities();
return View(vm);
}
Assuming GetPriorities method returns a collection of SelectListItem for the priorities.
public List<SelectListItem> GetPriorities()
{
List<SelectListItem> prioList=new List<SelectListItem>();
prioList.Add(new SelectListItem { Text = "High", Value = "1" });
prioList.Add(new SelectListItem { Text = "Low", Value = "2" });
// to do :read from db and add to list instead of hardcoding
return prioList;
}
Now in our view, which is strongly typed to CreateIssueVM
#model CreateIssueVM
#using(Html.BeginForm())
{
#Html.DropDownListFor(x=>x.SelectedPriority,
new SelectList(Model.Priorities ,"Value","Text"),"select")
#Html.ValidationMessageFor(x=>x.SelectedPriority)
<input type="submit" />
}
When you submit the form, you can check the form is valid or not by checking the ModelState.IsValid property.
[HttpPost]
public ActionResult Create(CreateIssueVM model)
{
if(ModelState.IsValid)
{
// save and redirect
}
vm.Priorities =GetPriorities();
return View(vm);
}
If you want to implement client side validation as well, you may simply include the relevant jquery unobtrusive validation scripts in the view and enable the client side validation in web.config.
Related
I have a basic model
public class SpeakerConsent
{
public string FieldLabel { get; set; }
public List<SelectListItem> OptionValues { get; set; }
}
My razor page currently looks like the following
#for (var i = 0; i < Model.OptionValues.Count(); i++)
{
#Html.RadioButtonFor(x => Model.OptionValues[i].Selected, Model.OptionValues[i].Value )
}
I might have 4 or 5 items in my OptionValues.
Question : How can i bind to the Selected property of the SelectListItem so when the model is posted i can identify which on of the radio buttons has been selected?
With your current code, the HTML markup generated for the input element will be like below
<input data-val="true" name="OptionValues[0].Selected" type="radio" value="201">
the name is Selected and the value is a number. The Selected property of the SelectListItem is bool type. Model binding will not work as expected when you post this form data.
IMHO, The easiest way to handle a scenario like this is to use editor templates.
I will first create a class which represents the data I want to use with the radio buttons.
public class MyOption
{
public bool IsSelected { set; get; }
public int Id { set; get; }
public string Text { set; get; }
}
Now in my main view model, I will add a collection type property
public class SpeakerConsent
{
public List<MyOption> Options { set; get; }
}
Now in your ~/Views/Shared/ directory, create a folder called EditorTemplates and then create a view called MyOption.cshtml in that. You can have the HTML markup you want to use to render the radio button in that. Here I am keeping the Id property in a hidden field along with the radio button and label.
#model YourNamespace.MyOption
<div>
<span>#Model.Text</span>
#Html.HiddenFor(g=>g.Id)
#Html.RadioButtonFor(b => b.IsSelected, true)
</div>
Now in your GET action, you can populate this Options property of yout SpeakerConsent view model object and send to the view.
public ActionResult Create()
{
var vm = new SpeakerConsent();
vm.Options = new List<MyOption>
{
new MyOption { Id=1, Text="Seattle"},
new MyOption { Id=2, Text="Detroit"},
new MyOption { Id=31, Text="Kerala"},
};
return View(vm);
}
Now in your main view, you can simply call the EditorFor helper method.
#model YourNamespace.SpeakerConsent
#using (Html.BeginForm("Index", "Home"))
{
#Html.EditorFor(a=>a.Options)
<button type="submit">Save</button>
}
Make sure to check the HTML markup generated by this code. notice the
name attribute value of the inputs.
When the form is submitted, you can read the Options property value, loop through them and read the Id and IsSelected property value and use them as needed
[HttpPost]
public ActionResult Create(SpeakerConsent model)
{
// check model.Options
// to do : return something
}
I've got a view that looks like this:
With this view I'm filtering records which are in a database. Each "filter" is a SearchViewModel which has a class definition like this:
public class SearchViewModel
{
//Property has a property called "SqlColumnName"
public Property Property { get; set; }
public Enums.SearchOperator Operator { get; set; }
public string Value { get; set; }
}
I'm now trying to find a solution how to build a actionlink to this site and passing in a List<SearchViewModel>().
So I'm trying to accomplish something like this:
http://url/Index?property=Typ&Operator=2&Value=4&property=ServerName&Operator=1&Value=server
I've tried to solve my problem with this http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ but this guy is calling the Action with a POST and i need to call it with a GET request.
So how to pass a list of objects to a mvc controller action with an actionlink?
EDIT
I think i need to say, that POST request is not an option because i need that link in an onClick event of a div element.
You could construct a link with the following parameters that should work:
http://url/Index?%5B0%5D0.property=Typ&%5B0%5D0.Operator=2&%5B0%5D0.Value=4&%5B1%5D0.property=ServerName&%5B1%5D0.Operator=1&%5B1%5D0.Value=server
Also notice that there are restrictions in the length of query string parameters. Those restrictions vary between the browsers. So it's probably a better approach to simply generate a link with an id that would allow you to retrieve the corresponding collection on the server (from your datastore):
http://url/Index?id=123
ActionLink helper method renders an anchor tag. It is ok to pass few query string items via a link. Remember Query string has a limit about how much data you can pass and it varies from browser to browser.
What you should be doing is a form posting. You can do a form posting on a click event on a div with the help of a little javascript.
Let's create a new view model for our search page
public class SearchVm
{
public List<SelectListItem> Operators { set; get; }
public List<SearchViewModel> Filters { set; get; }
}
public class SearchViewModel
{
//Property has a property called "SqlColumnName"
public Property Property { get; set; }
public SearchOperator Operator { get; set; }
public string Value { get; set; }
}
So in your GET action, You will send a list of SearchViewModel to the view.
public ActionResult Index()
{
var search = new SearchVm
{
Filters = new List<SearchViewModel>
{
new SearchViewModel {Property = new Property {SqlColumn = "Name"}},
new SearchViewModel {Property = new Property {SqlColumn = "Age"}},
new SearchViewModel {Property = new Property {SqlColumn = "Location"}}
}
};
//Convert the Enums to a List of SelectListItem
search.Operators= Enum.GetValues(typeof(SearchOperator)).Cast<SearchOperator>()
.Select(v => new SelectListItem
{
Text = v.ToString(),
Value = ((int)v).ToString()
}).ToList();
return View(search);
}
And in your view, which is strongly typed to your SearchVm view model, We will manipulate the form field names so that the model binding will work when the form is submitted.
#model SearchVm
#using (Html.BeginForm())
{
var i = 0;
foreach (var criteria in Model.Filters)
{
<label>#criteria.Property.SqlColumn</label>
#Html.HiddenFor(f => f.Filters[i].Property.SqlColumn)
#Html.DropDownList("Filters[" + i+ "].Operator",Model.Operators)
#Html.TextBoxFor(f=>f.Filters[i].Value)
i++;
}
<div id="someDiv">Search button using Div</div>
<input type="submit" value="Search" />
}
And your HttpPost action method to handle the form submit.
[HttpPost]
public ActionResult Index(SearchVm model)
{
foreach(var f in model.Filters)
{
//check f.Property.SqlColumn, f.Value & f.Operator
}
// to do :Return something useful
}
If you want the form to be submitted on the click event on the div, Listen to the click event on the specific div and call the submit method on the form the div resides in.
<script>
$(function () {
$("#someDiv").click(function(e) {
$(this).closest("form").submit();
});
});
</script>
I am trying to setup a listboxfor control that is bound to properties on my model. I can populate the listbox correctly but after making selections, the list that should contain the selected items is always empty. What am i doing wrong? I've spent a few hours changing and trying different things but still doesn't work.
----Model----
public class ManagementModel
{
public IEnumerable<SelectListItem> AssignableEntities { get; set; }
public IEnumerable<EntityDT> AssignedTestEntities { get; set; }
}
-----Get method in Controller-----
[HttpGet()]
public ActionResult Index()
{
ManagementModel model = new ManagementModel();
List<SelectListItem> listItems = new List<SelectListItem>();
foreach (EntityDT entity in atomService.GetAllAssignableLocations())
{
SelectListItem item = new SelectListItem()
{
Selected = false,
Text = entity.EntityName,
Value = entity.EntityID.ToString()
};
listItems.Add(item);
}
model.AssignableEntities = listItems;
return View(model);
}
-----View-----
#using (Html.BeginForm("SaveSetup", "Management"))
{
<div>
#Html.ListBoxFor(model => model.AssignedTestEntities, Model.AssignableEntities, new { style = "height:350px;width:175px;" })
</div>
<input type="submit" id="btnGiftManagementSubmit" value="Save" />
}
-----Form Post Method-----
[HttpPost]
[ValidateInput(false)]
public ActionResult SaveSetup(ManagementModel model)
{
The list is empty when it gets to this method
}
I finally figured out this issue. I'll list the steps below for setting these up
The collection property on your model needs to be of type SelectListItem.
The property on your model to store the selected values from the collection need to be string.
That's it and it'll work every time! I've been able to get a few of these working since i figured it out following this method. Good Luck!
I believe this will create a list in my HomeController. But not sure what calls it or where it goes in the Controller beside maybe the first Add ActionResult (GET method).
public static IEnumerable<SelectListItem> items()
{
using (oesacEntities_compact db = new oesacEntities_compact())
{
var query = from s in db.tblSponsors select new { s.SponsorID, s.BizName };
return query.AsEnumerable()
.Select(x => new SelectListItem
{
Value=x.SponsorID.ToString(),
Text = x.BizName
}).ToList();
}
}
I can't seem to send it to the Add view or to reference it from the Add view:
<div class="editor=field">
#Html.DropDownListFor(model => model.SponsorID,IEnumerable<SelectListItem> SelectList);
</div>
It seems so simple in other coding languages. I want to populate a pulldown with about 200 sponsor ID's for value, BizNames for text. For now at least. God help me after that when I want to show an Edit view with the value selected.
thankyou stackoverflow
You need to pass the SelectList to your view. Ideally your view model should include a property for the SelectList but you can (yuk) use ViewBag, for example
View Model
public class MyViewModel
{
public int SponsorID { get; set; }
// other properties
public SelectList SponsorList { get; set; }
}
Controller
public ActionResult SomeThing()
{
MyViewModel model = new MyViewModel();
// assign the select list
var sponsors = from s in db.tblSponsors;
model.SponsorList = new SelecList(sponsors, "SponsorID", "BizName");
return View(model);
}
View
#Html.DropDownListFor(model => model.SponsorID, Model.SponsorList);
or if you assigned the select list to ViewBag
#Html.DropDownListFor(model => model.SponsorID, (SelectList)ViewBag.SponsorList);
i want to show a dropdownList on a page using Entity Framework in my MVC app, but i am just stuck here to do this using using HTML Helper. so if anyone having knowledge of entity framework, help me...
my dataContext partial class is Entities, in which an entity named MemberInfo have some fields including MemberID & MemberName, so my dropdownList should show the field MemberName & behind this the value should be MemberID,
the code i tried yet--->
#Html.DropDownListFor(Model => Model.MemberID, MemberInfo)
in controller i am returning the Model--->
var MemberNameList = FinanceDBContext.MemberInfoes.Select(x => new { x.MemberID, x.Name });
return View(MemberNameList);
but its not working (errors).
You need to pass in all of your objects as the "model". Best practice is to use a ViewModel which will contain the list of data and a property to store the selected item.
ViewModel
public class MyViewModel
{
// The drop-down list and variable to get selection
public List<Member> Members { get; set; }
public int SelectedMemberId { get; set; }
}
Controller
[HttpGet]
public ActionResult Index()
{
var viewModel = new MyViewModel();
viewModel.Members = FinanceDBContext.MemberInfoes.ToList();
return View(viewModel);
}
[HttpPost]
public ActionResult Index(MyViewModel viewModel)
{
string debug = string.Format("You selected member: {0}", viewModel.SelectedMemberId);
return View(viewModel);
}
Finally, in your view (these lines need to be inside a BeginForm { ... } and ensure your View is strongly typed to MyViewModel
#Html.DropDownList("SelectedMemberId", new SelectList(Model.Members, "MemberID", "Name"))
<input type="submit" value="Save etc..." />
In this example you could put a break-point on the HttpPost action and check the debug string to check the correct Member is returned and proceed as required.