Angularjs - Dynamically change dom with directives or widgets?
The most drop dead easy way I can think of doing this is by just using ng-show and ng-hide.
http://jsfiddle.net/cfchase/Xn7PA/
<select ng-model="selected_type" ng-options="t for t in types">
</select>
<div ng-show="selected_type=='Type1'">
<input type="text" id="text1" ng-model="text1"/>
<input type="text" id="text2" ng-model="text2"/>
</div>
<div ng-show="selected_type=='Type2'">
<input type="number" id="numeric1" ng-model="numeric1"/>
<input type="date" id="date1" ng-model="date1"/>
</div>
Of course you could clean this up without putting any logic in the html, but I didn't want to cloud the issue with extra stuff in the controller.
For validation, refer to the forms documentation. It's likely you will use mostly the AngularJS built in validation with some custom ones you build.
As for directives, the online docs are dense, but it will click after you've experimented for awhile. For a gentler introduction, Jon Lindquist has a hello world tutorial on YouTube. Directives are definitely the way to do DOM manipulation in Angular.
This is how I would do it. Note that this is a just a starting point. There is still a matter of binding to particular values in the corresponding inputs. I hope it helps.
Markup:
<html ng-app="App" ng-controller="MainCtrl">
<body>
<component index="0"></component>
<component index="1"></component>
Current type: {{type}}
<button ng-click="toggleType()">Toggle</button>
</body>
</html>
Directive:
var ngApp = angular.module('App', []).directive('component', function() {
var link = function(scope, element, attrs) {
var render = function() {
var t = scope.layouts[scope.type][attrs.index];
if (t === 'textarea') {
element.html('<' + t + ' /><br>');
}
else {
element.html('<input type="' + t + '"><br>');
}
};
//key point here to watch for changes of the type property
scope.$watch('type', function(newValue, oldValue) {
render();
});
render();
};
return {
restrict : 'E',
link : link
}
});
Controller:
var MainCtrl = function MainCtrl($scope) {
$scope.type = 'Type1';
$scope.types = [ 'Type1', 'Type2' ];
$scope.layouts = {
'Type1' : [ 'textarea', 'textarea' ],
'Type2' : [ 'number', 'text' ]
};
$scope.toggleType = function() {
if ($scope.type === 'Type1') {
$scope.type = 'Type2';
}
else {
$scope.type = 'Type1';
}
};
};