1

I have a simple custom Editor Template for a drop down list, which shows a list of countries (country name, numeric ID). I pass a numeric ID to the View via ViewModel1, so that the specific country is already selected in the dropdown. And the country id does not get selected, even though the model contains CountryID.

Using option 3 (see template code) it does pre-select the country, but MVC changes the id and name of the dropdown, example- if the name passed to the editor template (property name) is "CountryID", MVC sets id="*CountryID_CountryID*" and name="CountryID.CountryID". Of course that would mess up binding when the value is posted as in the View Model property name is just CountryID.

Question: What do I need to do in custom Editor Template code so that country is pre-selected in the country list dropdown? The model passed to the view contains the CountryID of the country.

EDITOR TEMPLATE CODE:

@model short

@using PSP.Lib;

@{
    SelectList TheSelectList = null;
    string FieldName = ViewData.ModelMetadata.PropertyName;  //FieldName only used when I tried the commented out option.

    TheSelectList = DLists.GetCountriesList();  //just gets list of countries and a numeric id for each.
}


        <div class="editor-label">
            @Html.LabelFor(model => model)
        </div>
        <div class="editor-field">
            @Html.DropDownList("", TheSelectList)  //==1. country id passed thru model does not get selected on list.
         @* @Html.DropDownListFor(model => model, TheSelectList)  *@   //==2. as above, does not work.
         @* @Html.DropDownList(FieldName, TheSelectList) *@  //==3. country id passed thru model DOES get selected BUT, id and name parameters get changed.
        </div>

THE VIEW: Only relevant code shown

@model PSP.ViewModels.ViewModel1

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>EventList</legend>

            @Html.EditorFor(model => model.CountryID)
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>

VIEWMODEL1: Only relevant code shown

namespace PSP.ViewModels
{
    public class ViewModel1
    {
        public short CountryID { get; set; }
    }
}

COUNTRIES LIST:

public static SelectList GetCountriesList()
        {
            AccDBEntities db = new AccDBEntities();
            var ls = (from ct in db.Countries
                      select new { Text = ct.NameText, Value = ct.ID, Selected = false }).ToList();
            return new SelectList(ls, "Value", "Text");
        }

CONTROLLER: only relevant code shown

        public ActionResult Create()
        {

            ViewModel1 VM1 = new ViewModel1();
            VM1.CountryID = 50;    //just pre-selecting a country id in the dropdown list

            return View(VM1);
        }
2
  • Can you post the code for DLists.GetCountriesList() and your Controller Action? Commented Aug 22, 2013 at 14:47
  • as requested, I have posted the code, thanks. Commented Aug 23, 2013 at 10:04

1 Answer 1

0

First of all, you should not create a static method to get the list of countries. Add the list of countries to your ViewModel like this:

namespace PSP.ViewModels
{
    public class ViewModel1 // Choose a more meaningful name for your ViewModel
    {
        public short CountryID { get; set; }
        public IEnumerable<Country> CountriesList { get; set; }
    }
}

Then, in your Controller Action, you'll have:

public ActionResult Create()
{

    ViewModel1 VM1 = new ViewModel1();
    VM1.CountryID = 50;    //just pre-selecting a country id in the dropdown list
    using(AccDBEntities db = new AccDBEntities())
    {
        VM1.CountriesList = (from ct in db.Countries
                             select ct).ToList(); 
    }

    return View(VM1);
}

And, in your View, you'll have (you don't need an EditorTemplate):

@model PSP.ViewModels.ViewModel1

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>EventList</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.CountryID)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.CountryID, 
              new SelectList(Model.Countries, "ID", "NameText", Model.CountryID))  
        </div> 
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

UPDATE:

If you want to use an EditorTemplate, you'll have to use the UIHint attribute in your ViewModel, like below:

namespace PSP.ViewModels
{
    public class ViewModel1 // Choose a more meaningful name for your ViewModel
    {
        [UIHint("CountryID")]
        public short CountryID { get; set; }
        public IEnumerable<Country> CountriesList { get; set; }
    }
}

Then, you create a PartialView like below, name it CountryID.cshtml, and place it under Views\Shared\EditorTemplates.

@model short

<div class="editor-label">
    @Html.LabelFor(model => model)
</div>
<div class="editor-field">
    @Html.DropDownList("", 
      new SelectList(ViewBag.Countries, "ID", "NameText", Model)
</div>

And, in your main View, you'll have:

@model PSP.ViewModels.ViewModel1

@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>EventList</legend>

        @Html.EditorFor(model => model.CountryID, Model.Countries)

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
Sign up to request clarification or add additional context in comments.

1 Comment

I think you missed my question entirely. The names above are just for reference here, I have better names in my code, that is not my issue. For various reasons, I DO want to use an Editor Template. I know how to make it work without it. Can you tell me how to make the Editor Template work? (that is my question).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.