I'm trying to simplify how I generate my forms with AngularJS.
My ultimate goal is to be able to write something like:
<form>
<field-div label="Name">
<field which="form.name"></field>
</field-div>
<field-div label="Language">
<field which="form.language"></field>
</field-div>
</form>
For this, I'm working with two directives (fieldDiv and field) and two JavaScript objects: one that represents the data being edited in the form, and another that represents the form definition (field type, field options...).
See this JSFIDDLE for the code: http://jsfiddle.net/vincedo/9Uf6C/
After banging my head against the wall a few times, I think I got it working. The main difficulty was to get Angular to treat a string -- that I got from my form definition object (e.g. "entity.name") -- as a scope property with two-way data binding.
I still have two questions:
scope.$watch per field, and I'm afraid it might affect performance.<option> values whereas my code uses string keys such as en, fr... But after trying to wrap my head around $wrap and $parse for so many hours, I don't see it. :-)Thanks!
You can do this with an ng-switch tag (http://docs.angularjs.org/api/ng.directive:ngSwitch). Something like this.
<div class="control-group" ng-repeat="element in form">
<label class="control-label">{{element.label}}</label>
<div class="controls" ng-switch="element.widget">
<input ng-switch-when="text" type="text" ng-model="entity[element.model]" ng-required="element.required" />
<select ng-switch-when="select" ng-model="entity[element.model]" ng-required="element.required" ng-options="o.key as o.name for o in element.options"></select>
</div>
</div>
Here is a working example of my solution :
http://jsfiddle.net/Galdo/Sqsc7/17/
Please note that I changed entity.name to name in your schema.
With this solution, you will avoid any use of a directive. Pure angular!
For your second question (why the 0, 1, 2, ... instead of 'en', 'fr', etc.), you'll need to use an object instead of an array to bind to the <select> element. I found the answer in another question, but in short, your model becomes { 'en': 'English', 'fr': 'French', 'und':'Undefined'}, and your template's ng-options becomes ng-options="k as v for (k,v) in options"
I updated your Fiddle here: http://jsfiddle.net/StevenLJackson1/9Uf6C/7/
I'm also interested in performance with the multiple watches (i.e., the answer to your first question), since I am doing something similar on my current project.
I created a simple form builder application, source code: https://github.com/Selmanh/angularjs-form-builder
You can see it online here: http://selmanh.github.io/angularjs-form-builder/
My solution was similar to yours, but didn't use watch.
You might also consider looking at this, which creates dynamic angular forms based on simple json definitions: