views:

157

answers:

2

I've got a table that stores a True/False value as a sqlserver bit field (Featured). First, is there a better way to generate a dropdown list for this other than manually?

Second, here's what I've got so far which works but does not add selected="selected" to any items in the DDL.

Edit 1: I've updated this example according to the answer suggested and it results in a run-time error :( Edit 2: Using it like a function works (with and without the cast) but selected="selected" is still not being added.

Model:

//
// View models
public class SpotlightFormViewModel
{

    // props
    public Spotlight Spotlight { get; private set; }
    public SelectList FeaturedMenu { get; private set; }

    static IDictionary<string, int> feature = new Dictionary<string, int>(){
        {"True", 1},
        {"False", 0},
    };

    public IEnumerable<SelectListItem> FeaturedChoices(Spotlight spotlight)
    {
        return feature.Select(f => new SelectListItem
        {
            Text = f.Key,
            Value = f.Value.ToString(),
            Selected = spotlight.Featured,
        });
    }

    // constr
    public SpotlightFormViewModel(Spotlight spotlight)
    {
        Spotlight = spotlight;
        FeaturedMenu = new SelectList(FeaturedChoices(spotlight));
    }
}

Controller:

    public ActionResult Edit(int id)
    {
        Spotlight spotlight = spotlightRepository.GetSpotlight(id);

        return View(new SpotlightFormViewModel(spotlight));
    }

View:

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Spotlight.Featured) %>
        </div>
        <div class="editor-field">
            <%: Html.DropDownListFor(model => model.FeaturedMenu, Model.FeaturedChoices(Model.Spotlight))%>
            <%: Html.ValidationMessageFor(model => model.Spotlight.Featured) %>
        </div>
+2  A: 

I use the dropdowlist in the same that you do. But in your case you could simply use some radio buttons:

 <%: Html.Label("True") %>
 <%: Html.RadioButtonFor(model => model.FeaturedMenu, "1") %>

 <%: Html.Label("False") %>
 <%: Html.RadioButtonFor(model => model.FeaturedMenu, "0") %>

Secondly, you talked about the "selected" value, but you did not use it in "public IEnumerable FeaturedChoices", you could add the selected value like this:

return feature.Select(f => new SelectListItem
{
    Text = f.Key,
    Value = f.Value.ToString(),
    Selected = false
});
Lobsterm
I've updated my code with what needed to happen to make this approach possible. However, it results in CS1928: 'System.Web.Mvc.HtmlHelper<US_Security.Controllers.SpotlightFormViewModel>' does not contain a definition for 'DropDownListFor' and the best extension method overload 'System.Web.Mvc.Html.SelectExtensions.DropDownListFor<TModel,TProperty>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,TProperty>>, System.Collections.Generic.IEnumerable<System.Web.Mvc.SelectListItem>)' has some invalid arguments----For <%: Html.DropDownListFor(...) %>
ryan
Maybe this can solve your problem, replace this line:<%: Html.DropDownListFor(model => model.FeaturedMenu, Model.FeaturedChoices)%>by:<%: Html.DropDownListFor(model => model.FeaturedMenu, (IEnumerable<SelectListItem>)Model.FeaturedChoices)%>Let me know!
Lobsterm
Thanks for looking at this more. CS0428: Cannot convert method group 'FeaturedChoices' to non-delegate type 'System.Collections.Generic.IEnumerable<System.Web.Mvc.SelectListItem>'. Did you intend to invoke the method?
ryan
This might mean that instead of using: Model.FeaturedChoices like a variable you should use it as a method like this: Model.FeaturedChoices(Model.Spotlight). And don't forget to put the "(IEnumerable<SelectListItem>)" before.
Lobsterm
Using it like a function works (with and without the cast) but selected="selected" is still not being added for some reason. Even adding an explicit Selected = true results in selected="selected" still not being added.
ryan
A: 

I finally got this working. Even though my syntax & logic was correct when I was passing variables to public IEnumerable FeaturedChoices(Spotlight spotlight) it wouldn't work regardless, even if I explicitly marked Selected = true. If someone could answer why that is so I would appreciate it

The only way selected="selected" was correctly applied is if I made FeaturedChoices a property with a getter. Full working code below

View model:

//
// View models
public class SpotlightFormViewModel
{

    // props
    public Spotlight Spotlight { get; private set; }
    public SelectList FeaturedMenu { get; private set; }

    static IDictionary<string, int> feature = new Dictionary<string, int>(){
        {"True", 1},
        {"False", 0},
    };

    public IEnumerable<SelectListItem> FeaturedChoices
    {
        get
        {                
            return feature.Select(f => new SelectListItem
            {
                Text = f.Key,
                Value = f.Value.ToString(),
                Selected = IsSelected(this.Spotlight.Featured, f.Key)
            });
        }
    }

    private bool IsSelected(bool featured, string val)
    {
        bool result = false;

        if (String.Compare(val, "True") == 0 && featured)
            result = true;
        else if (String.Compare(val, "False") == 0 && !featured)
            result = true;

        return result;
    }

    // constr
    public SpotlightFormViewModel(Spotlight spotlight)
    {
        Spotlight = spotlight;
    }
}

Controller:

    public ActionResult Edit(int id)
    {
        Spotlight spotlight = spotlightRepository.GetSpotlight(id);

        return View(new SpotlightFormViewModel(spotlight));
    }

View:

        <div class="editor-label">
            <%: Html.LabelFor(model => model.Spotlight.Featured) %>
        </div>
        <div class="editor-field">
            <%: Html.DropDownListFor(model => model.FeaturedMenu, Model.FeaturedChoices)%>
            <%: Html.ValidationMessageFor(model => model.Spotlight.Featured) %>
        </div>
ryan
I am glad you figured it out
Lobsterm
Thanks for the help :). I saw on your blog fixes for implementing a wysiwyg editor with MVC. Going to implement CKEdit once I get through my viewmodels. We'll see what happens
ryan