In my AngularJS application, I have different complex inputs everywhere. For example, some inputs have a directive to use autocompletion with Google Places or with autocompletion from Twitter Bootstrap.
I'm searching for a way to make a directive which displays an erase button when we add some text like iOS feature.
I made this one, but the scope.erase
doesn't start, nor does the ng-show
.
Is it possible to add HTML after the text input and "play" with them inside the controller?
My test:
app.directive('eraseBtn', function($parse, $compile){ return { require: 'ngModel', restrict: "A", transclude: true, link : function(scope, element, attrs, model){ element.parent().append('<button ng-click="erase()" ng-show="model.length > 0" class="erase-btn">x</button>'); scope.erase = function(){ console.log('Erase test'); } } } });
I don't want to use a template because all of my inputs' HTML are really different.
What are Directives? At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ( $compile ) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.
The Element.append() method inserts a set of Node objects or string objects after the last child of the Element . String objects are inserted as equivalent Text nodes. Differences from Node.appendChild() : Element.append() allows you to also append string objects, whereas Node.appendChild() only accepts Node objects.
You can create custom inputs inside link function of your directive depending on values of the model. If you want that elements to be bind to model or use directives to build them, you should use $compile
(and don't forget to call compiled template with model):
HTML
<!DOCTYPE html> <html ng-app="demo"> <head> <script data-require="angular.js@*" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.js"></script> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body ng-controller="demoController"> <div demo-directive ng-repeat="input in inputs"></div> </body> </html>
JavaScript
angular.module('demo', []). controller('demoController', function($scope) { $scope.inputs = [{ inputType: 'checkbox', checked: true, label: 'input 1' }, { inputType: 'text', value: 'some text 1', label: 'input 2' }]; $scope.doSomething = function() { alert('button clicked'); }; }). directive('demoDirective', function($compile) { return { template: '<div><label>{{input.label}}: </label></div>', replace: true, link: function(scope, element) { var el = angular.element('<span/>'); switch(scope.input.inputType) { case 'checkbox': el.append('<input type="checkbox" ng-model="input.checked"/><button ng-if="input.checked" ng-click="input.checked=false; doSomething()">X</button>'); break; case 'text': el.append('<input type="text" ng-model="input.value"/><button ng-if="input.value" ng-click="input.value=\'\'; doSomething()">X</button>'); break; } $compile(el)(scope); element.append(el); } } });
Plunker: http://plnkr.co/edit/pzFjgtf9Q4kTI7XGAUCF?p=preview
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With