How to get all input fields within a form (AngularJS directive)
Solution 1
Warning: This is just an idea that works in a trivial example. I'm not saying it's wrong (this is open to discussion, though) but I have NOT used it in a more complicated context.
So... you can actually create a second input
directive and have it applied only when another directive (let's say myDirective
) has been applied to the enclosing form.
Suppose you have 2 forms:
<body>
<form name="myForm1" ng-controller="MainCtrl">
Name: <input id="name1" type="text" ng-model="data.name" /><br/>
Surname: <input id="surname1" type="text" ng-model="data.surname" />
<pre>{{data}}</pre>
</form>
<br/>
<form name="myForm2" ng-controller="MainCtrl" my-directive>
Name: <input id="name2" type="text" ng-model="data.name" /><br/>
Surname: <input id="surname2" type="text" ng-model="data.surname" />
<pre>{{data}}</pre>
</form>
</body>
Only the second form is tagged with my-directive
. Now, your directives could look like:
app.directive("myDirective", function(){
return {
restrict: 'A',
require: ['form'],
controller: function() {
// nothing here
},
link: function(scope, ele, attrs, controllers){
var formCtrl = controllers[0];
console.log("myDirective applied to form:", formCtrl.$name);
}
};
});
app.directive("input", function(){
return {
restrict: 'E',
priority: -1000,
require: '^?myDirective',
link: function(scope, ele, attrs, ctrl){
if (ctrl) {
console.log("applying custom behaviour to input: ", ele.attr('id'));
// ... awesomeness here
}
}
};
});
See it live and check out the logs. The original input
directive lives side-by-side with your own. The proof for that is that the form still works (as you type, the model is updated: that's input
's and then, ngModel
's job).
Your input
directive could also use ngModel to manipulate the input value:
app.directive("input", function(){
return {
restrict: 'E',
priority: -1000,
require: ['?ngModel', '^?myDirective'],
link: function(scope, ele, attrs, ctrls){
var ngModel = ctrls[0];
var myDirective = ctrls[1];
if (myDirective) {
console.log("applying custom behaviour to input: ", ele.attr('id'));
// ... awesomeness here
}
}
};
});
Solution 2
why not use Angular's jqLite (or jQuery if you choose to load it)
angular.forEach(element.find('input'), function(node){
awesomize(node)
});
user2422960
Updated on July 09, 2022Comments
-
user2422960 almost 2 years
I would like to create a directive which does something awesome with all the input fields within a form.
However, i'd be happy if i could apply that directive only once (to the
<form>
itself) instead of having it to bind to all the<input>
'sHow should i determine all of a forms input elements?
I see some possible solutions:
element[0].childNodes // filter all inputs element[0].children element[0].elements // seems to contain nothing but the stuff i want
Maybe i am even to close-minded and don't see the correct solution here.
Any help and opion is appreciated
-
user2422960 over 10 yearsI still shudder when thinking about using jQuery stuff for an Angular application. Nevertheless, i'd give it a try, thank you for pointing out the obvious
-
Vlad Gurovich over 10 yearsyou have to iterate the dom tree under <form> regardless, might as well do it in a semantically pleasant way(that is provided by angular)
-
The DIMM Reaper over 7 yearsI like this approach. It does still have to bind to all the
input
elements, but conveniently, that happens without any additional tags. This wouldn't apply, for example, to atextarea
element. Just something to keep in mind.