updated According to angularjs passing parameters through directive and ng-repeat non-compile version is working now. But the main question is still valid: to compile or not to compile
I'm trying to make dynamic formfields (my app needs lots of forms with lots of fields)
so I created a controller as:
KPNControllers.controller('panelAccountCtrl', ['$scope',
function panelAccountCtrl($scope) {
$scope.panelAccountTabItems = [
{"title" : "Personal Data",
"contentUrl":"partials/panel/account/personal.html",
"fields" : [
{"name" : "first_name", "label" : "First name", "required" : "true", "min" : 3, "max":20, "type":"text"},
{"name" : "last_name", "label" : "Last Name", "required" : "true", "min" : 3, "max":20, "type":"text"}
]},
{"title" : "Login", "contentUrl" : "partials/panel/account/login.html"},
{"title" : "Password", "contentUrl" : "partials/panel/account/password.html"}
];
}])
(only first item has fields [] but of course finally all of them will have it)
Then I created html as:
<div class="box all-borders">
<h3 class="special">{{tabItem.title}}</h3>
<form name="mainForm" class="form-horizontal" novalidate>
<form-field ng-repeat="field in tabItem.fields" form="mainForm" label="{{field.label}}" field-type="{{field.type}}" field-id="{{field.id}}"></form-field>
</form>
</div>
(not all attrs are set - but this is only for example)
So now it's a time for a directive.
I found two solutions:
With Compile: (not edited after update)
KPNDirectives.directive("formField", function () {
return {
restrict: 'E',
replace: true,
compile: function (element, attrs) {
var type = attrs.type || 'text';
var required = attrs.hasOwnProperty('required') ? "required" : "";
var formName = 'Form';
var fqFieldName = formName + '.' + attrs.fieldId;
var inlineErrorRequired = attrs.hasOwnProperty('required') ? '<span class="help-block" ng-show="' +fqFieldName+ '.$error.required">Required</span>' : "";
var htmlText =
'<div>' +
'<div class="form-group" ng-class="{true: \'has-error\', false: \'has-success\'}['+ fqFieldName + '.$invalid]">'+
'<label class="control-label col-sm-2" for=' +attrs.fieldId + '">' +attrs.label+ '</label>' +
'<div class="col-sm-6">' +
'<input type="' + type+ '" class="form-control" id="' +attrs.fieldId + '" name="' +attrs.fieldId + '" ng-model="'+ attrs.ngModel + '" '+ required + ' />' +
inlineErrorRequired +
'</div>' +
'</div>' +
'</div>';
element.replaceWith(htmlText);
}
};
})
And without Compile: edited after update
KPNDirectives.directive("formField", function () {
return {
restrict: 'E',
replace: true,
scope: {
fieldModel: '=',
fieldLabel: '=',
fieldType: '=',
fieldName: '='
},
templateUrl: 'templates/formField.html'
};
})
with template:
<div class="form-group" ng-form="form" ng-class="{true: 'has-error', false: 'has-success'}[form.fieldName.$invalid]">
<label class="control-label col-sm-2" for="fieldName">{{fieldLabel}}</label>
<div class="col-sm-6">
<input class="form-control" type="{{fieldType}}" placeholder="wprowadź aktualny email" name="fieldName" ng-model="fieldModel" ng-minlength=6 ng-maxlength=20 required/>
<span class="help-block">
<span ng-show="form.fieldName.$error.required">Wymagane</span>
<span ng-show="form.fieldName.$error.minlength">Zbyt mało znaków (minimalna liczba to 6)</span>
<span ng-show="form.fieldName.$error.maxlength">Zbyt dużo znaków (maxymalna liczba to 20)</span>
</span>
</div>
</div>
I want to know which method is the best or more angularish.
Here is a plunker with compile: http://plnkr.co/edit/BDIn5weqima5ve3G0Q2l?p=preview And here is a plunker without compile: http://plnkr.co/edit/8cP5YMKUGu6LfBCsRxAZ?p=preview