Create custom input directive in angular
I would like to create a user input that looks like this:
<my-input ng-model="aScopeProperty" placeholder="Enter text"
data-title="This is my title"></my-input>
my-input should receive any property that normal input can receive (like placeholder, etc.).
the output should be like this (myInputTemplate.html):
<div class="my-input">
{{title}}
<input type="text" ng-model="text" />
</div>
I created a directive:
myApp.directive('myInput', function(){
return {
restrict: 'E',
require: 'ngModel',
templateUrl: '/myInput/myInputTemplate.html',
replace: true,
scope: {
text: '=ngModel',
title: '=title'
},
}
});
ng model is now bound ok, my question is : How can I pass attributes (like placeholder, etc.) from my input to the internal input?
I think I approached it wrong, maybe I need to do it like this:
<input my-input ng-model="aScopeProperty" placeholder="Enter text"
data-title="This is my title"></input>
and wrap the input with:
<div class="my-input">
{{title}}
<here will be the original input>
</div>
source to share
the directive call should be like
<my-input ng-model="aScopeProperty" placeholder="'Enter text'" title="'This is my title'"></my-input>
note placeholder="'Enter text'"
Enter text
with help quotes (')
, it means these values ββare strings, so angular won't look for the variable scope
.
and in the directive
myApp.directive('myInput', function(){
return {
restrict: 'E',
require: 'ngModel',
templateUrl: '/myInput/myInputTemplate.html',
replace: true,
scope: {
text: '=ngModel',
title: '=title',
placeholder : '=placeholder'
},
}
});
and template
<div class="my-input">
{{title}}
<input type="text" ng-model="text" placeholder="{{ placeholder }}" />
</div>
here is a demo plunker
source to share
The second approach will work!
final code:
<input my-input ng-model="aScopeProperty" placeholder="Enter text"
data-title="This is my title">
Directive:
app.directive('myInput', function () {
return {
restrict: 'A',
scope: {
title: '=title'
},
link: function ($scope, $element) {
var wrap = angular.element('<div class="my-input-wrapper" />');
$element.addClass('form-control').removeAttr('my-input');
wrap.insertBefore($element);
$element.appendTo(wrap);
if ($scope.title) {
var title = angular.element('<span class="my-title">' + $scope.title + '</span>');
title.appendTo(wrap);
}
},
}
});
I even created my first Plunker for it, unfortunately Plunker doesn't work because it doesn't recognize: insertBefore and appendTo
source to share
You can use ng-attr
like this:
<input type="text" ng-model="text" ng-attr-placeholder="{{placeholder}}"/>
And send the placeholder as an attribute in your scope like this:
scope: {
text: '=ngModel',
title: '=title',
placeholder : '=placeholder'
}
I recommend reading ng-attr-attrName and this helpful answer .
Dynamic attributes
Read my question and the accepted answer.
source to share