JSFiddle - React, Tailwind, and code Playground
by manikantag
HTML
<!doctype html>
<html>
<head>
<title>dynamic form with array</title>
<script src="http://code.angularjs.org/angular-0.9.14.js" ng:autobind></script>
</head>
<body ng:controller="DynFormCtrl">
<my:form schema="addressSchema" data="address"></my:form>
<div id="model">
address = <pre>{{address}}</pre>
</div>
</body>
</html>
CSS
fieldset {
border: 1px grey solid;
padding: 1em;
width: 60%
}
#model {
position: fixed;
right: 0;
top: 0;
}
JavaScript
function DynFormCtrl() {
// define data we are working with
this.address = {
name: 'John Smith',
contacts: [{type:'phone', value:'0815-1'},
{type:'fax', value:'0815-2'}],
};
// define schema for the data (each attribute except for 'children' translates to
// DOM element attribute of the same name).
// if 'type' is undefined, it is considered to be 'text'
this.addressSchema = [
{ name: 'name'},
{ name: 'contacts',
children: [
{ name: 'type' },
{ name: 'value' }
]
}
]
}
angular.widget('my:form', function(element) {
this.descend(true); // compiler will process children elements
this.directives(true); // compiler will process directives
return function(element) {
var scope = this,
schema = scope.$eval(element.attr('schema')),
data = element.attr('data'),
fieldset = angular.element('<fieldset></fieldset>');
// process every field as specified in the JSON schema definition
angular.forEach(schema, function processField(field) {
var fullyQualifiedName = this.parentName + '.' + field.name,
fieldElStr;
// has hierarchical subforms?
if (field.children) {
var contentChilds = scope.$eval(fullyQualifiedName);
var childElem = field.name + 'Elem';
var subfieldset = angular.element('<fieldset ng:repeat="' + childElem + ' in ' + fullyQualifiedName + '"></fieldset>'); // TODO: auf dieser Ebene ng:repeat fuer kinder
var legend = angular.element('<legend>' + field.name + '</legend>');
subfieldset.append(legend);
// ~~ add
var addButton = angular.element('<a class="btn btn-small" href="" ng:click="' + fullyQualifiedName + '.$add()">(+)</a>');
...