Reputation: 19
I am currently working on creating an MVC4 application where I want controls to be generated automatically from the database rows.
I have the table in my database containing the questions and the control type in which it should be answered by the user.
I am just thinking of a logic like
This is my Controller action:
Public ActionResult Index()
{
// get the rows from the table
foreach(Iterate the rows)
{
if(controllerType1)
{
//stmnts
}
if(controllerType2)
{
//stmnts
}
}
return View();
}
This is just an idea of how can we build the solution. If I am going in the right way please guide me, else I am eager to know the possibilities where I can build my solution in different ways :).
Upvotes: 0
Views: 5048
Reputation: 1384
You can create a editor template and pass the control list as model to the template and in the template you can iterate that list to generate the control. As i have shown below.
1->Create a class for Control Information.
public class ControlInfo
{
public string ControlType { get; set; }
public string ControlID { get; set; }
public string ControlName { get; set; }
public string ControlValue { get; set; }
public string ControlLabel { get; set; }
public bool IsChecked { get; set; }
}
2->Create an Editor Template (Partial view with control name say CustomControl.cshtml) in \Views\Shared\EditorTemplates path.
@model List<MvcApplication2.Models.ControlInfo>
<table>
@foreach (MvcApplication2.Models.ControlInfo ControlInfo in Model)
{
<tr>
<td>@ControlInfo.ControlLabel</td>
<td>
@switch (ControlInfo.ControlType.ToLower())
{
case "textbox":
<input type="text" name="@ControlInfo.ControlName" id="@ControlInfo.ControlID" value="@ControlInfo.ControlValue" />
break;
case "checkbox":
if (ControlInfo.IsChecked)
{
<input type="checkbox" name="@ControlInfo.ControlName" id="@ControlInfo.ControlID" value="@ControlInfo.ControlValue" checked="checked" />
}
else
{
<input type="checkbox" name="@ControlInfo.ControlName" id="@ControlInfo.ControlID" value="@ControlInfo.ControlValue" checked="checked" />
}
break;
default:
break;
}
</td>
</tr>
}
</table>
3->Create a model for main view (say HomeModel).
public class HomeModel
{
public List<ControlInfo> ControlList { get; set; }
public void PolulateControlList()
{
//You can fill this list from database.
// For example i have filled the list manually.
ControlList = new List<ControlInfo>();
ControlList.Add(new ControlInfo() {ControlType="TextBox",ControlName="tbox1", ControlID="tbox1", ControlLabel="Name", ControlValue="Martin" });
ControlList.Add(new ControlInfo() { ControlType = "CheckBox", ControlName = "cbox1", ControlID = "cbox1", ControlLabel="Is Correct", ControlValue = "Yes", IsChecked=true });
}
}
4->Consume the editor template in the main view as.
@model MvcApplication2.Models.HomeModel
@{
ViewBag.Title = "Home Page";
}
@Html.EditorFor(model=>model.ControlList,"CustomControl")
5-> Call the main view in the controller ( Index here).
public ActionResult Index()
{
HomeModel ModelObj = new HomeModel();
ModelObj.PolulateControlList();
return View(ModelObj);
}
Edit 1: For getting the posted value you need to modify the Editor Templates as below. The model properties whose name is equal to the name of the control posted as name value collection , will get automatically binded by the model binder of the mvc frame work, so for each property in the control collection i have created hidden tags and one input tag for the input value.
@model List<MvcApplication2.Models.ControlInfo>
<table>
@{ var index = -1;}
@foreach (MvcApplication2.Models.ControlInfo ControlInfo in Model)
{
index++;
<tr>
<td>@ControlInfo.ControlLabel</td>
<td>
<input type="hidden" name="@("ControlList[" + index + "].ControlID")" value="@ControlInfo.ControlID" />
<input type="hidden" name="@("ControlList[" + index + "].ControlLabel")" value="@ControlInfo.ControlLabel" />
<input type="hidden" name="@("ControlList[" + index + "].ControlName")" value="@ControlInfo.ControlName" />
<input type="hidden" name="@("ControlList[" + index + "].ControlType")" value="@ControlInfo.ControlType" />
@switch (ControlInfo.ControlType.ToLower())
{
case "textbox":
<input type="text" name="@("ControlList["+index+"].ControlValue")" id="@ControlInfo.ControlID" value="@ControlInfo.ControlValue" />
break;
case "checkbox":
<input type="hidden" name="@("ControlList[" + index + "].ControlValue")" value="@ControlInfo.ControlValue" />
if (ControlInfo.IsChecked)
{
<input type="checkbox" name="@("ControlList[" + index + "].IsChecked")" id="@ControlInfo.ControlID" value="true" checked="checked" />
}
else
{
<input type="checkbox" name="@("ControlList[" + index + "].IsChecked")" id="@ControlInfo.ControlID" value="true" />
}
break;
default:
break;
}
</td>
</tr>
}
</table>
And in the main view you need to have form
@model MvcApplication2.Models.HomeModel
@{
ViewBag.Title = "Home Page";
}
@using(Html.BeginForm()){
@Html.EditorFor(model=>model.ControlList,"CustomControl")
<input type="submit" name="name" value="Submit" />
}
And in controller you need to have corresponding post method
[HttpPost]
public ActionResult Index(HomeModel ModelObj)
{
// Your logic..........
return View(ModelObj);
}
This ModelObj will have the posted values.
Upvotes: 2