1

I am creating configurable forms in MVC which will contain dynamic controls base off of this SO post. The controls are all built from my base ControlViewModel which just contains properties for all of the controls

public abstract class ControlViewModel
{
    public abstract string Type { get; }
    public bool Visible { get; set; }
    public string Label { get; set; }
    public string Name { get; set; }
}

Each control type is defined seperately by inheriting ControlViewModel

public class TextBoxViewModel : ControlViewModel
{
    public override string Type
    {
        get { return "textbox"; }
    }
    public string Value { get; set; }
}

I have text boxes, check boxes, and drop downs all defined in a similar manner. The issue I am having is when the controls are displayed on the page, their name and id attributes are not rendering as expected. In my controller I have

public ActionResult Index()
{
    var model = new MyViewModel
    {
        Controls = new ControlViewModel[]
        {
            new TextBoxViewModel 
            { 
                Visible = true,
                Label = "label 1",
                Name = "TextBox1", 
                Value = "value of textbox" 
            }
        }
    }

    return View(model)
}

In my Index.cshtml I render each control like so:

@model DynamicForms.Models.MyViewModel
@using (Html.BeginForm())
{
    for (int i = 0; i < Model.Controls.Length; i++)
    {
        if (Model.Controls[i].Visible)
        {
            <div>
                @Html.HiddenFor(x => x.Controls[i].Type)
                @Html.HiddenFor(x => x.Controls[i].Name)
                @Html.EditorFor(x => x.Controls[i])
            </div>
        }
    }
    <input type="submit" value="OK" />
}

The editor just renders the control and the label

@model DynamicForms.Models.TextBoxViewModel
@Html.LabelFor(x => x.Value, Model.Label)
@Html.TextBoxFor(x => x.Value)

The issue is that when the page renders, the name and id attributes don't render as the actual string values, but instead as the type

<div>
        <input id="Controls_0__Type" name="Controls[0].Type" type="hidden" value="textbox">
        <input id="Controls_0__Name" name="Controls[0].Name" type="hidden" value="TextBox1">
        <label for="Controls_0__Value">label 1</label>

Does anyone know how I can populate the name and id attributes correctly here?

Community
  • 1
  • 1
Barry Tormey
  • 2,966
  • 4
  • 35
  • 55
  • can you try rendering the hidden inputs this way? `` – Dan Schnau Aug 01 '14 at 17:08
  • @dsschnau That seems to be one work around. I am really just wondering why they aren't rendering correctly in the first place. But `` does work. – Barry Tormey Aug 01 '14 at 17:18
  • It might have to do with the abstraction.. try `@Html.HiddenFor(x => x.Controls[i].Type.ToString())` ? – Dan Schnau Aug 01 '14 at 17:24
  • @dsschnau That throws the exception `Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.` I thought that would work as well, but no luck. – Barry Tormey Aug 01 '14 at 17:33
  • The html is being rendered correctly (the name attribute is the name of the property and the value attribute is the value of the property) If it didn't do this then it wouldn't bind correctly. What result are you expecting? –  Aug 01 '14 at 23:24
  • If you couldn't get it to work, you might have better luck using my library FormFactory, with whihc you can get more control over your control models: http://stackoverflow.com/a/38309284/2086 – mcintyre321 Jul 11 '16 at 15:41

0 Answers0