Reputation: 1229
I have a directive that basically generates a label tag for inputs. It replaces the directive with my template as well as ensures the parent and next nodes have the correct attributes and classes I require.
.directive('placeHolder', function() {
return {
restrict: 'E',
replace: true,
template: '<label for="{{input}}" class="placeholder-label">{{label}}</label>',
link: function ($scope, elem, attrs) {
$scope.label = attrs.label;
$scope.input = attrs.input;
//check if the parent element is a div, then set the class to make it's position relative
if(elem.parent().nodeName === 'DIV') {
elem.parent().addClass('placeholder-parent');
}
//check if the next element is an input or textarea
if(elem.next().nodeName === 'INPUT' || elem.next().nodeName === 'TEXTAREA') {
//ensure the id of the input/textarea is the same as the for value in the label, else set it so
if(elem.next().attr('id') === input) {
return
} else {
elem.next().attr('id', input)
}
}
}
};
});
My problem is that I have 2 inputs on the same page, thus two instances of the same directive, and both instances result in the same label visible.
Here is a fiddle http://jsfiddle.net/HB7LU/11330/
Upvotes: 1
Views: 2329
Reputation: 186
You need to use the scope attribute of the directive:
if the name of the attributes are the same:
scope: {
label: '@',
input: '@'
}
or you can define custom ones:
scope: {
myLabel: '=label',
myInput: '=input'
},
Your code sample modified:
app.directive('placeHolder', function() {
return {
restrict: 'E',
replace: true,
template: '<label for="{{input}}" class="placeholder-label">{{label}}</label>',
scope: {
label: '@',
input: '@'
},
link: function ($scope, elem, attrs) {
//check if the parent element is a div, then set the class to make it's position relative
if(elem.parent().nodeName === 'DIV') {
elem.parent().addClass('placeholder-parent');
}
//check if the next element is an input or textarea
if(elem.next().nodeName === 'INPUT' || elem.next().nodeName === 'TEXTAREA') {
//ensure the id of the input/textarea is the same as the for value in the label, else set it so
if(elem.next().attr('id') === input) {
return
} else {
elem.next().attr('id', input)
}
}
}
};
});
To use this modify your directive html to:
<place-holder label="labelText" input="inputId">
Refer to chapter 'Isolating the Scope of a Directive' In AngularJS directive documentation: https://docs.angularjs.org/guide/directive
Upvotes: 3