How to create nice interactive HTML 5 Forms - The Easy Way

Tags: ASP.NET Core Community

In highly data driven application or line of business application developers often come to the point where they need to work with forms as a instrument to take input from the user. In HTML you usually use the form tag to accomplish this. In nowadays modern single page applications you can get support from frameworks like AngularJs to make your forms more functional by writing less code at the same time. But even then you have to wirte a lot of code even for simple forms. 

If you use Angular Schema Form in combination with Fancy.SchemaFormBuilder it is super easy for .NET Developers to create rich HTML forms with a minimun lines of code by reusing existing code on the backend. All you have to do is to annotate your Data Transfer Objects of View Models with attributes provided by Fancy.SchemaFormBuilder. Then you can use Fancy.SchemaFormBuilder to generate a declarative description of your form in JSON. The generated JSON can then be provided to Angular Schema Form via a WebApi. In the browser you bind the objects received from the server to an instance of Angular Schema Form to render the form.  

The following step by step guide leads you through the described procedure. 

Step1 - Create a DTO and annotate it 

In the first Step we create your DTO which containes the properties yout want to get filled by the form. The properties of the DTO which shall show up in form need to be annotated with attributes from the Fancy.SchemaFormBuilder project. The following code snippet shows an example DTO representing an employee. 

/// <summary>
/// A view model for employees with properties which can be edited by the user.
/// </summary>
public class EditEmployeeVm
{
    /// <summary>
    /// Gets or sets the first name.
    /// </summary>
    /// <value>
    /// The first name.
    /// </value>
    [FormTitle("First Name")]
    [FormRequired]
    [FormSection("Name")]
    [FormDisplay(DisplayWidth = DisplayWidth.Half)]
    public string FirstName { get; set; }

    /// <summary>
    /// Gets or sets the last name.
    /// </summary>
    /// <value>
    /// The last name.
    /// </value>
    [FormTitle("Last Name")]
    [FormRequired]
    [FormSection("Name")]
    [FormDisplay(DisplayWidth = DisplayWidth.Half)]
    public string LastName { get; set; }

    /// <summary>
    /// Gets or sets the e mail.
    /// </summary>
    /// <value>
    /// The e mail.
    /// </value>
    [FormTitle("E-Mail")]
    [FormSection("ContactData", SectionType = SectionType.Fieldset, Title = "Contact Data")]
    public string EMail { get; set; }

    /// <summary>
    /// Gets or sets the phone.
    /// </summary>
    /// <value>
    /// The phone.
    /// </value>
    [FormTitle("Phone")]
    [FormSection("ContactData")]
    public string Phone { get; set; }

    /// <summary>
    /// Gets or sets the mobile.
    /// </summary>
    /// <value>
    /// The mobile.
    /// </value>
    [FormTitle("Mobile")]
    [FormSection("ContactData")]
    public string Mobile { get; set; }
}

Step 2 - Implement Web API Controller 

The next step is to implement a REST endpoit to provide the form description to the angular app running the Angular Schema Form module. To generate the form description we can use the default implementation of the ISchemaFormBuilder, the DefaultSchemaFormBuilder class. After the form is shown and filled in the browser it can be submitted back to the server. Therefore we need to add a PUT method to the WebAPI controller to be able to receive the data from the form. The following code snippet shows a controller which can provide the necessary metadata and can receive submitted form data(of cource in a more real world example the controller would have some more operations e. g. operations like get an employee by id). 

/// <summary>
/// A controller to work with employee resources.
/// </summary>
public class EmployeesController : Controller
{
    /// <summary>
    /// The schema form builder.
    /// </summary>
    private readonly ISchemaFormBuilder _schemaFormBuilder = new DefaultSchemaFormBuilder();

    /// <summary>
    /// A static list of employees. This simulates the database/persitance in this sample.
    /// </summary>
    private static readonly List<fullemployeevm> _employees = new List<fullemployeevm>();

    /// <summary>
    /// Creates a new empty employee resource with metadata.
    /// </summary>
    /// <returns>An empty employee with metadata to render a form.</returns>
    [Route("[controller]/create")]
    public IActionResult Create()
    {
        // Create the metadata info for the type
        SchemaFormInfo schemaFormInfo = _schemaFormBuilder.CreateSchemaForm(typeof(FullEmployeeVm));

        // Create a response which contains the metadata and an empty resource
        return Json(new { schemaFormInfo.Form, schemaFormInfo.Schema, Data = new EditEmployeeVm() });
    }

    /// <summary>
    /// Creates a new employee.
    /// </summary>
    ///<param name="editEmployeeVm" />The edit employee vm.
    /// <returns>The id of the created employee.</returns>
    [HttpPut]
    [Route("[controller]")]
    public IActionResult CreateNewEmployee([FromBody] EditEmployeeVm editEmployeeVm)
    {
        FullEmployeeVm newEmployee = new FullEmployeeVm();
        newEmployee.Id = _employees.Count == 0 ? 1 : _employees.Max(e =&gt; e.Id) + 1;
        newEmployee.Update(editEmployeeVm);
        _employees.Add(newEmployee);
        return Json(newEmployee.Id);
    }
}

Step 3 - Create AngularJs App 

When the backend is ready to provide the form description and receive data then we have to care about the client side running in the browser. There we have to create an AngularJS app wich loads the angular-schema-form module. To show the form for our DTO we create an AngularJS controller to load the form description (the metadata) from the WebAPI and to send back the filled in data to the WebAPI. The following code snippet shows the complete declaration of the AngularJs app and the controller. 

// Create a new angular app -> don't forget to specify a dependency to the "schemaForm" module
var myApp = angular.module("fancy.schema-form-builder-sample", ["schemaForm"]);

// Create the main controller for the sample app
myApp.controller("MainController", ["$http", "$scope", function($http, $scope) {

	// Load the metadata for a new employee
	$http.get("employees/create").success(function(data) {
		$scope.formInfo = data;
	});

	// This function gets called by the form on submission
	$scope.submitForm = function(form) {
		// First we broadcast an event to trigger validation of all fields
		$scope.$broadcast('schemaFormValidate');
		// Then we check if the form is valid
		if (form.$valid) {
			// Send employee to the server
			$http.put("employees", $scope.formInfo.Data).success(function() {
				// Done! Employee was sent to the server
			});
			// Reset the form to an empty employee
			$scope.formInfo.Data = {};
		}
	};
}]);

Step 4 - Create HTML to render the form 

In the last step we have to create some lines of HTML to render the form. The following code snippet shows a body tag bound the AngularJs app and a div tag bound the the AngularJS controller. The div tag contains a form tag which is bound the variables provieded by the AngularJs controller. Thats all you have to do to render the form. Of course there are some parts missing in the HTML like loading of css and scripts. 

<body ng-app="fancy.schema-form-builder-sample">
<!-- Apply the controller of the app to this div scope -->
<div ng-controller="MainController">

    <h3>Employee Form</h3>
    <hr />

    <!-- Render the form using the metadata retrieved by the controller -->
    <form name="employeeForm"
            sf-schema="formInfo.Schema"
            sf-form="formInfo.Form"
            sf-model="formInfo.Data"></form>
</div>
</body>

That's it!

This walkthrough was reduced to the absolute minimun necessary to bring a form to live with FancySchemaFormBuilder. You can find the complete example code here at GitHub with some more features implemented in ASP.NET Core 1.0. Also have in mind there is the Schema Form Builder Studio where you can develop and test you DTOs with a live preview of the resulting form.

Hope it helps!

No Comments

Add a Comment