Reputation: 2184
I'm trying do a small reusable component in AngularJS using directives. I have made good progress but I have a problem with the validations. For example the required validation not working. I think is "binding" issue.
My HTML code: also in http://jsfiddle.net/pQwht/17/
<html ng-app="myApp">
<body>
<form ng-controller="Ctrl"
id="paymentCallForm"
action="#"
name="paymentCallForm">
<table>
<tr tdfield
labelname="Primary Account Number:"
fieldname="primaryAccountNumber"
title="Primary title"
>
</tr>
</table>
My directive script:
angular.module('myApp').directive('tdfield', function() {
return {
restrict: 'A',
replace:false,
transclude: false,
scope: { labelname: '@', fieldname: '@', title: '@'},
templateUrl:'element.html'
};
});
My element.html code:
<td id="lbl_paymentReference" class="formInputLabelWrapper">{{labelname}}</td>
<td class="formInputTextWrapper">
<input id="{{fieldname}}"
name="{{fieldname}}"
title="{{title}}"
class="large empty"
required>
<span data-ng-show="paymentCallForm.{{fieldname}}.$error.required"
class="error">Error</span></td>
Upvotes: 1
Views: 1800
Reputation: 4669
Well, I solved this, but for what a price. There is a number of issues and angular related among them. I may not recall all, so here is the working example https://github.com/yaroslav-ulanovych/soq16245177.
When you define scope
parameter like scope: { labelname: '@', fieldname: '@', title: '@'},
(with an object as a value), that creates an isolated scope, which means not inherited from parent one's. Therefore here ng-show="paymentCallForm.{{fieldname}}.$error.required"
is no access to the form. As a workaround ng-show="$parent.paymentCallForm.{{fieldname}}.$error.required"
, but I didn't check whether your inputs are published in the form in case of the isolated scope. Or scope: true
and inject attributes into the scope manually.
compile: function() {
return {
pre: function (scope, element, attr) {
scope.fieldname = attr.fieldname;
}
}
}
Note on using prelink function, so that it's called before children are linked.
Next ng-show
will actually use not interpolated expression and there is obviously no property named {{fieldname}}
in the form. That is fixed in later versions of Angular, don't know when exactly, cause I'm using master.
But what is not fixed is ngModelController
. It gets it's name very early so publishes itself on the form under wrong one. I had to fix that myself, good that there is only one line to do that, in file src/ng/directive/input.js
.
// add
modelCtrl.$name = attr.name;
// before this
formCtrl.$addControl(modelCtrl);
Upvotes: 2
Reputation: 5891
I believe you need a controller attached to your view. The form object will be attached to property with the id of the form on $scope
object of this controller. Once you add that, I think it will start showing up.
Upvotes: 0