Showing posts with label Razor. Show all posts
Showing posts with label Razor. Show all posts

Dynamically Load Form in MVC Razor View Engine

One part of my project gives user the ability to create forms and render it dynamically. Here's how I render the  form definition from an XML container in Razor view engine.

The View
@model MyProject.Models.DynaForm
@using (Html.BeginForm("ViewForm","FormManagement"FormMethod.Post))  
{
   var sectionCollection = from s in Model.XmlForm.Descendants("section"select s;
   foreach(System.Xml.Linq.XElement section in sectionCollection) // get sections
   {
   var fieldCollection = from f in section.Descendants("field"select f; // get fields
   <fieldset>
     <legend>Section @(section.Attribute("id").Value)</legend>
     @foreach (System.Xml.Linq.XElement field in fieldCollection) // iterate over each field
        {
        <div>
          <div>@field.Attribute("name").Value</div>
         <div>@Html.TextBox(field.Attribute("name").Value, field.Value, new { @class = field.Attribute("inputtype").Value }) </div>
        </div>
        }
    </fieldset>
    }
  <input type="submit" name="submit" value="save" />
  <input type="submit" name="submit" value="cancel" />
}

The Controller
public class ViewFormController : Controller
{
    Models.DynaForm oWorkflow = new Models.DynaForm();
    public ActionResult ViewForm()
    {
        oDynaform.ID = 1;
        oDynaform.XmlForm = XDocument.Load(Server.MapPath("~/App_Data/myform.xml"));                 return View("ExecuteRequest", oWorkflow); // pass this to view for rendering
    }
 
    [HttpPost// POST handler
    public ActionResult ViewForm(string submit)
    {
        switch (submit)
        {
            case "save":
                // delegate sending to another controller action
                return (Save());
            case "cancel":
                // call another action to perform the cancellation
                return (CancelRequest());
            default:
                // If they've submitted the form without a submitButton, 
                // just return the view again.
                return (View());
        }
    }
 
    private ActionResult CancelRequest()
    {
        return (PartialView()); // return to same page
    }
 
    private ActionResult Save()
    {
        oDynaForm.ID = 2;
        return (PartialView("ViewForm", oDynaForm));    }
}



The XML field template.
<dynamicform name="yourform" id="1">
  <section id="1">
    <field type="text" name="First name" inputtype="textbox" />
    <field type="text" name="Last name" inputtype="textbox" />
    <field type="text" name="Email" inputtype="textbox" />
  </section>
  <section id="2">
    <field type="text" name="Other information" inputtype="textarea" >  Other info here </field>
  </section>
  <section id="3">
    <field type="text" name="Input 1" inputtype="textarea" />
    <field type="text" name="Input 2" inputtype="textarea" />
    <field type="text" name="Input 3" inputtype="textarea" />
  </section>
</dynamicform>