creating controls dynamically in mvc

4.1k views Asked by At

I want to create controls in view dynamically depending on source if type = text box create text box if it is check box create check box dynamically in MVC. Below is my current code

     @model PayTxn.Miscellaneous.Models.SurveyViewModel
        @using PayTxn.Miscellaneous.Models
 @{ int index = 0;}

            @for (int i = 0; i < Model.ControlsList.Length; i++)
            {

                var control = Model.ControlsList[i];

                if (control.Type == "radio")
                {

                    Html.RenderPartial("~/Views/Shared/EditorTemplates/_RadioBoxViewModel.cshtml", control as RadioBoxViewModel, new ViewDataDictionary { { "index", index } });

                }
                else if (control.Type == "checkbox")
                {
                    Html.RenderPartial("~/Views/Shared/EditorTemplates/_CheckBoxViewModel.cshtml", control as CheckBoxViewModel, new ViewDataDictionary { { "index", index } });
                }
                else if (control.Type == "textbox")
                {
                    Html.RenderPartial("~/Views/Shared/EditorTemplates/_TextBoxViewModel.cshtml", control as TextBoxViewModel, new ViewDataDictionary { { "index", index } });
                }
                else if (control.Type == "rattingbox")
                {
                    Html.RenderPartial("~/Views/Shared/EditorTemplates/_RattingBoxViewModel.cshtml", control as RattingBoxViewModel, new ViewDataDictionary { { "index", index } });
                }
                else if (control.Type == "slider")
                {
                    Html.RenderPartial("~/Views/Shared/EditorTemplates/_SliderViewModel.cshtml", control as SliderViewModel, new ViewDataDictionary { { "index", index } });
                }
                index = index + 1;
            }
    <input type="submit" name="action:Submit1" value="Submit1" />
            <input type="submit" name="action:Reset" value="Reset" />

it works fine but on click of submit1 button my view is not tightly bound to model Model code is

  public class SurveyViewModel
{
    //public List<ControlViewModel> ControlsList { get; set; 
    public ControlViewModel[] ControlsList { get; set; }
}
public abstract class ControlViewModel
{
    public abstract string Type { get; }
    public bool Visible { get; set; }
    public string Label { get; set; }
    public string Name { get; set; }
}

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

public class RadioBoxViewModel : ControlViewModel
{
    public List<string> Options { get; set; }
    public List<string> Values { get; set; }
    public override string Type
    {
        get { return "radio"; }
    }
}

public class CheckBoxViewModel : ControlViewModel
{
    public List<string> Options { get; set; }
    public List<string> Values { get; set; }
    public override string Type
    {
        get { return "checkbox"; }
    }
    public bool Value { get; set; }
}
public class SliderViewModel : ControlViewModel
{
    public override string Type
    {
        get { return "slider"; }
    }
    public string Value { get; set; }
}
public class RattingBoxViewModel : ControlViewModel
{
    public List<string> Titles { get; set; }
    public List<string> Rattings { get; set; }
    public string _rattingType = null;
    public string RattingType
    {
        get
        {
            if (string.IsNullOrEmpty(_rattingType))
                return "star";
            else
                return _rattingType;
        }

        set
        {
            _rattingType = value;
        }
    }
    public override string Type
    {
        get { return "rattingbox"; }
    }
    public bool Value { get; set; }
}
2

There are 2 answers

0
Rutu On BEST ANSWER

Hey i solved this issue by creating custom model binder here is code

    public class ControlModelBinder : DefaultModelBinder
     {
    protected override object CreateModel(ControllerContext controllerContext,             ModelBindingContext bindingContext, Type modelType)
    {
        var datalist = controllerContext.HttpContext.Request.Form.GetEnumerator();
        SurveyViewModel model = new SurveyViewModel();
        model.ControlsList = new List<ControlViewModel>();
        List<string> answers = new List<string>();
        while (datalist.MoveNext())
        {
            string currentKey = datalist.Current.ToString();
            if (currentKey.Contains("TextBoxViewModel"))
            {
                TextBoxViewModel textBoxViewModel = new TextBoxViewModel();
                textBoxViewModel.Value = controllerContext.HttpContext.Request.Form[currentKey];
                model.ControlsList.Add(textBoxViewModel);
            }
            else if (currentKey.Contains("CheckBoxViewModel"))
            {
                CheckBoxViewModel checkboxviewmodel = new CheckBoxViewModel();
                checkboxviewmodel.SelectedValues = controllerContext.HttpContext.Request.Form[currentKey];
                model.ControlsList.Add(checkboxviewmodel);
            }
            else if (currentKey.Contains("RadioBoxViewModel"))
            {
                RadioBoxViewModel radioboxviewmodel = new RadioBoxViewModel();
                radioboxviewmodel.SelectedValue = controllerContext.HttpContext.Request.Form[currentKey];
                model.ControlsList.Add(radioboxviewmodel);
            }
            else if (currentKey.Contains("RattingBoxViewModel"))
            {
                RattingBoxViewModel rattingboxviewmodel = new RattingBoxViewModel();
                rattingboxviewmodel.Score = controllerContext.HttpContext.Request.Form[currentKey];
                model.ControlsList.Add(rattingboxviewmodel);
            }
            else if (currentKey.Contains("SliderViewModel"))
            {
                SliderViewModel sliderviewmodel = new SliderViewModel();
                sliderviewmodel.Value = controllerContext.HttpContext.Request.Form[currentKey];
                model.ControlsList.Add(sliderviewmodel);
            }
        }
        return model;
    }

}
3
Matt Bodily On

an if conditional won't cause any additional issues for you. It just changes what fields to show on the view. Validations and tying to the model won't change

@if(condition1){
<h2>Lorem Ipsum is simply dummy text of the printing and typesetting industry? </h2>
   <ul>
       <li>
           @Html.RadioButtonFor(x => x.r1, "1")
           <label for="r1">Single choice option 1</label>
       </li>
       <li>
           @Html.RadioButtonFor(x => x.r2, "2")
           <label for="r2">Single choice option 2</label>
       </li>
       <li>
           @Html.RadioButtonFor(x => x.r3, "3")
           <label for="r3">Single choice option 3</label>
       </li>
       <li>
           @Html.RadioButtonFor(x => x.r4, "4")
           <label for="r4">Single choice option 4</label>
       </li>
  </ul>
  }else if(condition2){
  <h2>Lorem Ipsum is simply dummy text of the printing and typesetting industry?</h2>
  <ul>
      <li>
          @Html.CheckBoxFor(x => x.cb10)
          <label for="cb10">Multiple choice option 1</label>
      </li>
      <li>
          @Html.CheckBoxFor(x => x.cb11)
          <label for="cb11">Multiple choice option 2</label>
      </li>
      <li>
          @Html.CheckBoxFor(x => x.cb12)
          <label for="cb12">Multiple choice option 3</label>
      </li>
      <li>
          @Html.CheckBoxFor(x => x.cb13)
          <label for="cb13">Multiple choice option 4</label>
     </li>
 </ul>
 }

so if condition 1 is met then only radio buttons will be rendered on the form. If condition 2 is met then check boxes

Update:

based on the code that you changed this will be much more difficult to tie to a model. I would recommend putting names on the fields that you are dynamically generating and doing a

Request.Form["fieldName"].ToString()

for a check box list for example this will return a comma delineated list of the id's that were checked (1,2,3,etc). Good Luck