I found posts for populating from database, classes, xml, etc but I cannot seem to find one for populating a dropdownlist straight from the web page.
<div class="editor-field">
#Html.DropDownListFor(x => x.Subject, Model.SubjectList)
#Html.ValidationMessageFor(m => m.Subject)
</div>
I just want to add several items to my dropdownlist without using Model.
Is that possible?
I think I understand what you are asking here. If you just want to hardcode values in the view you can do something like this:
#Html.DropDownList("", new List<SelectListItem> {
new SelectListItem { Text = "Option 1", Value="1"},
new SelectListItem{Text="Option 2", Value="1"}})
You could also create the select list in the controller and store it in the ViewBag.
Related
I have an html dropdownlistfor which is being populated from my database, this I was able to do successfully but the issue I am having now is including an additional option not available in the database as an option that can also be selected.it is actually a list of items but I want a give an option ALL which when selected means the user is selecting all the items displayed in the database, my major issue is how to include the ALL option. I have searched and read similar questions but they are not what am trying to achieve. thanks for your help. here is my code
in my controller I have this:
var load = from bh in db.IV_001_ITEM
select bh;
ViewBag.selection = new SelectList(load.ToList(), "item_code", "item_name", glay.vwstring2);
in my view I have this:
<div class="col-sm-2">
#Html.DropDownListFor(m => m.vwstring2, ViewBag.selection as SelectList, "Select", new { #class = "form-control", required = "required", id = "selectc" } )
</div>
You can use the Add method to explicitly add an extra option (SelectListItem)
List<SelectListItem> optionList = db.IV_001_ITEM
.Select(x=>new SelectListItem { Value=x.item.code,
Text=x.itemName}).ToList();
// Now add the item you want
optionList.Add(new SelectListItem { Value="Foo",Text="Bar"});
//use this now
ViewBag.Items = optionList;
// You can set the selected item on your view model property
myViewModelObject.vwstring2 = glay.vwstring2; //For the selected item
return View(myViewModelObject);
In your view,
#Html.DropDownListFor(m => m.vwstring2, ViewBag.Items as List<SelectListItem>,
"Select", new { #class = "form-control"})
It seems impossible and I have tried a few different ways to create a select list and bind a value to it.
Firstly, and more desirably, I want to do it with Razor:
#Html.DropDownList("SelectedTemplate", Model.Templates, new { #data_bind = "value: Template()" })
The options are just an array of strings. When I bind with Razor then it's a List of SelectListItem objects with Text and Value equal to the same string.
So it renders like this:
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
When I bind via Knockout then the Templates is an array of strings:
var Templates ='["A", "B", "C"]';
which I generate in the cshtml file:
var Templates ='#Html.Raw(Json.Encode(Model.Templates.Select(x=> x.Value)))';
Both create the same markup in HTML. This renders the select list correctly. Template() prints out the correct value, for example "B". However, the drop down doesn't pick the option that is equal to Template(). I also tried:
<select name="SelectedTemplate" data-bind="value: Template(), options: JSON.parse(Templates)"></select>
Same problem here. And I tried all kinds of variations:
#Html.DropDownListFor(m => m.SelectedTemplate, Model.Templates, new { #class = "form-control layoutTemplateSelector", #data_bind = "value: Template(), options: JSON.parse(Templates)" })
#Html.DropDownListFor(m => m.SelectedTemplate, Model.Templates, new { #class = "form-control layoutTemplateSelector", #data_bind = "value: Template()" })
#Html.DropDownList("SelectedTemplate", Model.Templates, new { #data_bind = "value: Template(), options: JSON.parse(Templates)" })
Ideally, I want to use DropDownListFor because on post back I want m.SelectedTemplate to be processed.
The postback works well so far for DropDownListFor, but on load it doesn't show the data-bind: value:Template(), which definitely contains the correct value.
I also tried your idea to use observable array with no success:
self.SelectedContent({
Template: ko.observable(content.Template()),
TemplateList: ko.observableArray(JSON.parse(Templates))
});
#Html.DropDownListFor(m => m.Form.Template, Model.Templates, new {#data_bind = "value: Template(), options: TemplateList()" })
Any ideas what could be wrong here? I'm using Knockout 2.3 and MC.
UPDATE
I found the error.
The value returned from the database contained a space: "A "
whereas the values binding the to the drop down didn't have that space.
This caused all the errors.
As far as I can see the simplest of implementations works well now:
#Html.DropDownList("SelectedTemplate", Model.Templates, new { #data_bind = "value: Template()" })
Even though it was entirely my mistake, I hope it helps someone in the future. The error wasn't immediately apparent
I have a basic form allowing users to input details which then gets posted and saved to a database - this works as expected without any issues:
#model R32.Register.Models.RegisterCar
#{
ViewBag.Title = "Edit Your R32";
}
<h2>Edit R32</h2>
<div>
#using (Html.BeginForm("UpdateCar", "Garage", FormMethod.Post))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Enter details</legend>
<ol>
<li>
#Html.LabelFor(m => m.NumberPlate)
#Html.EditorFor(m => m.NumberPlate, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.NumberPlate)
</li>
<li>
#Html.LabelFor(m => m.Edition)
#Html.EnumDropDownListFor(m => m.Edition, "Select an edition:", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Edition)
</li>
<li>
#Html.LabelFor(m => m.Colour)
#Html.EnumDropDownListFor(m => m.Colour, "Select a colour:", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Colour)
</li>
</ol>
<input type="submit" value="Save Changes" />
</fieldset>
}
</div>
Model snippet:
[Required]
[Display(Name="Edition")]
public MkEnum? Edition { get; set; }
Enum:
public enum MkEnum
{
[Display(Name="Mk4")]
Mk4 = 1,
[Display(Name="Mk5")]
Mk5 = 2
}
The control renders as expected, with the Edition dropdownlist having three values: "Select an edition", "Mk4", and "Mk5".
The user is able to select an edition, control is validated, then posted to the controller.
The Post is successful, and all selected values are sent to the controller - the app then persists the data in a database, and so on, without any problems.
The issue is when I pass this model back into the same View to allow the user to edit the saved data, the saved values for the enums are NOT being set as the selected value in the dropdownlist.
I can confirm that any saved string values, such as NumberPlate in this example, are being passed back into the view and loaded into the UI.
Putting a breakpoint on the viewmodel as it renders I can confirm that my #model contains the saved values for enum properties - Edition for example - but the end result is that the "Select an edition:" dropdown list is rendered containing the expected dropdown values, but it's value is the default "Select an edition:" instead of the actual value passed in via. m.Edition.
I have been able to get this working using DropDownListFor - but am having difficulties in understanding why this is not working using EnumDropDownListFor, as this clearly seems like a more elegant solution.
Does anyone have any help/advice for this?
I just ran into this problem myself. This happens because fields of type enum are being passed back to the browser serialized as their enum names, but #Html.EnumDropDownListFor generates its option values as integers. The browser can't match up the two so the dropdown stays at its default selection.
There are 3 ways to get around this.
Get the view model's enum field to serialize properly as an int.
Write a dropdown generator that uses enum names as option values.
Use javascript to manually select the option (includes razor syntax here)
$("#YourDropdownID option").each(function () {
if ($(this).html() == '#(Html.DisplayFor(o => o.YourEnumFieldName))') {
$(this).attr("selected", "selected");
return;
}
});
Ok, so from what I could see the problem was caused by using an ActionLink to pass back the full model of an item being edited. Everything was being sent back in a Query string, so my Enum values were being passed to the controller in the following way: mkEnum=Mk4.
I was then loading the UpdateCar view as seen above in my example - but the query string values were being persisted in the call back to the View.
EnumDropDownListFor is unable to interpret/convert the text value of enums into their actual values - if I manually edited the Query string to mkEnum=1, then the correct value wasloaded into the ViewModel.
In addition to this problem, it was not a good solution passing the full model back to the controller.
I've modified the code to pass back a single Id of the item being edited - the controller then verifies the user has access to that Id, retrieves the Model from the Database then passes it back to the same View as in my above example.
With this change my dropdowns are now being updated with their values without any issues.
TLDR; If you experience this issue check to make sure you don't have model properties, specifically enum values represented by their string values, in a query string when loading your view and using EnumDropDownListFor.
I have a case where I have a page displaying an order and tabs that display the order details. The order details are quite complex and since they are the same layout, I want to use a partial view or editor template that will generate the form.
The problem is the result is multiple duplicate form input id's are generated (one for each order detail. For example, I have:
foreach (var orderDetail in Model.OrderDetils)
{
#Html.EditorFor(model => orderDetail, "WorkOrder", orderDetail)
}
I've read much about this and see solutions where it is recommended to use an editortemplate, but that solution only works when you have the same form to render, but passing it different model properties so the control id's prefixes will differ...ie. like this solution.
In my case, this won't work as the model property I am passing is always the same.
So how else can I create unique Id's in the partial or editor template that will also bind.
I know instead of:
#Html.EditorFor(model => model.WOHdr.Attribute1)
I could do:
#Html.TextBoxFor(model => model.WOHdr.Attribute1, new { id = Model.Id + "_Attribute1" })
But then it won't bind when it passes to the controller.
Thoughts?
Try this
#Html.TextBoxFor(model => model.WOHdr.Attribute1, new { #id = #Model.Id + "_Attribute1" })
Use "#"+dynamic value. Now You will get unique Id's
In EditorFor you can use like this
#Html.EditorFor(model => model.WOHdr.Attribute1, null, "id=" + #Model.Id + "" )
the id will generate like this
id="id_1", id="id_2" and so on..
<input id="Checkbox1_#(test.TestId)" type="checkbox" />
i hope upper code will help you
In MVC3, I've been able to rely on Html.DisplayForModel() to generate display's for my data. Using this method, and various templates, I have a single View for displaying several of my Models. What I'm wondering though, is there a way I can get this to work on Lists for my models?
For example, I have a model called Networks. My view to list out multiple networks looks like this:
#model PagedList<Network>
<div id="networkList">
#Html.Grid(Model).Columns(column => {
column.For(x => Html.ActionLink(x.Id.ToString(), "NetworkDetails", new { id = x.Id })).Named("Network ID");
column.For(x => x.Name);
column.For(x => x.Enabled);
}).Attributes(Style => "text-align: center")
#Html.AjaxPager(Model, new PagerOptions() { PageIndexParameterName="page", ShowDisabledPagerItems = false, AlwaysShowFirstLastPageNumber=true },
new AjaxOptions() { UpdateTargetId = "networkList" })
</div>
I'm wondering if it is possible to use a single template when generating lists for my models. I could rely on attributes to know which properties I would like to generate in my list, ie: [ListItem].
The head scratcher for me is, how can I pass a dynamic model to an extension method? If it's of any help, the Html.Grid extension is from MVCContrib. Has anyone else done something similar? It would be great to rely on a template as it would really chop down on the amount of code.
You can achieve it for EditorFor() using the following (it might be similar with your Grid extension method assuming it can take the template name parameter):
// in the main view
#Html.EditorFor(o => o.InvoiceId, "TemplateName", new { Property = "InvoiceId" })
#Html.EditorFor(o => o.Title, "TemplateName", new { Property = "Title" })
// in the template view
#model object
#{ var property = (string)this.ViewData["Property"]; }
Alternatively you can just pass in the name of the template and use this code in the template
var prefix = ViewData.TemplateInfo.HtmlFieldPrefix;
if (prefix.EndsWith("InvoiceId")) { ... }