Thoughts on reusable forms in AngularJS

576 views
Skip to first unread message

Samuel Richardson

unread,
Oct 8, 2013, 7:03:09 PM10/8/13
to ang...@googlegroups.com
I've built a few AngularJS apps but one thing that's been bothering me is how I handle forms. At the moment I'm designing them as follows:

- The model, generally populated from a $resource / $http
- A directive / template which contains the form fields, maybe a modal window, or just in a template somewhere.
- The form directive itself, usually called as follows:

<form:user data="model" valid-callback="form_valid(valid)"></form:user>

The data attribute links to the $resource model, the valid-callback is used for enabling / disabling controls. E.g. stopping the user from clicking the "create" button in the modal window until all the fields are filled out.

This works really well, however I seem to have a lot of repeated boilerplate code in my form templates. A typical line for entering a value might look like

<div class="form-group" ng:class="{'has-error': !form.name.$valid && form.name.$dirty}">
<label class="control-label" for="form_name">Full name</label>
<input id="form_name" type="text" class="form-control" placeholder="Enter your full name" name="name" ng:model="data.name" required>
<span class="help-block" ng:show="form.name.$error.required && form.name.$dirty">Your full name is required</span>
</div>

A lot of the code is concerned with displaying error messages, validation etc which are repeated for every field.

Has anybody had any experience with Angular either defining form fields via JSON or even introspecting the resource model to generate the form fields?

Rafał Janicki

unread,
Oct 9, 2013, 6:02:18 AM10/9/13
to ang...@googlegroups.com
I've got similar situation and for now I'm trying to resolve it. My first thoughts was to create a few separate elements:

- service, which will be responsible for any logic in the form
- one directive for whole form
- separate directives for any form element may occurs (input, select, checkbox, radiobuttons and so on)

I'd like to communicate between all of these elements via $rootScope: main service receives JSON data, for example:
{
formName: "sample form",
formMethod: "POST",
formAction : url,
fields {
 0 :{
  type: "input",
  value: username.value,
  error: username.error,
  validator: username.validator
 },
 1: {
   ... next field definition as above...
  }
 submit: "Save",
 submitCallback: save,

... other properties for whole form...

}

Then, my service creates each form field depends on items in JSON 'fields' property (field 'type' determines directive for single field, which should be used). Root elements in JSON determines global properties for whole form element (which is another directive).

Every callbacks and other properties I define in controller, then I only have to call component such like:

FormService.init( >JSON< );

In FormService init() method iterating via JSON fields "build" form.

In view, it should looks something like this:

<form-service>
  ... here is the placeholder for inner directives ...
</form-service>

This is just the beginning of my work, so I'll be happy to discuss about details :)

Greetings,

Rafal

Himanshu Ranavat

unread,
Oct 22, 2013, 5:06:28 PM10/22/13
to ang...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages