Select TagHelper Using List from ViewBag
Asked Answered
T

3

8

I am currently trying to use taghelpers in asp.net 5. I want to use a select tag helper with a list from the ViewBag. Anything I put into the asp-for field gives me an error because it tries to pull it from the model which is IEnumerable instead of the view bag.

I want to replace this:

@model IEnumerable<InvoiceIT.Models.Invoice>
@using (Html.BeginForm())
{
    <p>            
        @Html.DropDownList("Companies", String.Empty)       
        <input type="submit" value="Filter" class="btn btn-default" />
    </p>
}

with this:

@model IEnumerable<InvoiceIT.Models.Invoice>
<form asp-controller="Invoice" asp-action="Index" method="post" class="form-horizontal" role="form">
    <select asp-for="????" asp-items="ViewBag.Companies" class="form-control">
    </select>
    <input type="submit" value="Save" class="btn btn-default" />
</form>

Here is how I populate the select list in the controller:

ViewBag.Companies = new SelectList(await DbContext.Company.ToListAsync(), "CompanyID", "Name");
Tien answered 4/8, 2015 at 8:37 Comment(0)
S
11

If you don't want the asp-for attribute to pull from the Model directly you can override that behavior by providing an @.

Aka:

<select asp-for="@ViewBag.XYZ">
    ...
</select>

Therefore, based on what you said I believe your bit becomes:

@model IEnumerable<InvoiceIT.Models.Invoice>
<form asp-controller="Invoice" asp-action="Index" method="post" class="form-horizontal" role="form">
@{
    SelectList companies = ViewBag.Companies;
    var currentlySelectedIndex = 0; // Currently selected index (usually will come from model)
}
    <select asp-for="@currentlySelectedIndex" asp-items="companies" class="form-control">
    </select>
    <input type="submit" value="Save" class="btn btn-default" />
</form>

Hopefully this helps!

Systematist answered 5/8, 2015 at 8:19 Comment(6)
Using your exact code I get a compile error on the asp-for field: 'an expression tree may not contain a dynamic operation'.Tien
Ahh, good point. Updated response to reflect the proper usage (see added bits inside @{ }).Systematist
This seems to be getting closer as it compiles however it adds a listbox type control instead of a drop down, and it is empty of data. If I change it to asp-for="@companies" asp-items="@ViewBag.Companies" then I get the same listbox but it has the correct data in it. How do I get a dropdown instead?Tien
Sorry @Reafidy, I responded wayyy too quickly and fat fingered a few things. Updated the answer to reflect the proper usage. As for details as to why it works. IF the value provided to asp-for happens to be an IEnumerable (and not a string) then it wont render as a dropdown list. Otherwise it will :)Systematist
Thanks, that works, it's now become a lot more long winded than just using the old fashioned: @Html.DropDownListTien
@N.TaylorMullen I spent lots of time figuring out a solution where I could use ViewBag to fill in the Select Tag Helper in a view while using @model directive in the same view for something else. Your solution helped me achieve such a task - thank you for helping.Gruel
P
3

asp-for just needs to be the property with the current selected value and asp-items needs to be an

IEnumerable<SelectListItem>

this snippet is from working code in my project:

<select id="CompanyCountry" asp-for="CompanyCountry"
           asp-items="Model.AvailableCountries" class="form-control"></select>

in my model I'm using

IList<SelectListItem> 

for AvailableCountries

Peptone answered 4/8, 2015 at 15:38 Comment(5)
so for your example looks like ViewBag.CompanyID should be on asp-for and asp-items should be the list of selectlist items representing companiesPeptone
Hey Joe, I have updated the question. When I place companyID in the asp-for field I get an error: 'IEnumerable<Invoice> does not contain a definition for companyID'. I believe this is because I am trying to use the viewbag as a source and companyid only exists in the viewbag source and not in the model.Tien
did you try using @ViewBag.companyID? I do think asp-for is for model binding whereas viewbag is for display. asp-for should be a property of the model that contains a value that corresponds to a value in the selectlistitems. the idea is on get the current value for the property will be selected, if the user selects a different value and submits the form, the new selected value will be bound to the model property automatically for you on post of the form so you can save the model with the new selected valuePeptone
Yes I did and I get a compile error: 'an expression tree may not contain a dynamic operation'. The select list I want to use is a filter drop-down for the pages table. It has nothing to do with editing the model so companyid is not suppose to be in the model.Tien
Maybe you don't need to set asp-for at all in that scenario, just asp-items.Peptone
O
0

you can try like this ...

@Html.DropDownListFor(model => model.Id_TourCategory, new SelectList(ViewBag.TourCate, "Value", "Text"))

 public ActionResult TourPackage()
    {
        List<TourCategory> lst = new List<TourCategory>();
        lst = db.TourCategories.ToList();
        ViewBag.TourCate = new SelectList(lst, "Id", "CategoryName");          
        return View();
    }
Ophiuchus answered 4/8, 2015 at 8:59 Comment(1)
Umm thanks but the code I have works for a DropDownList, the point is I am trying to use a taghelper.Tien

© 2022 - 2024 — McMap. All rights reserved.