Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Append html to an element in directive and make a local function to interact with it

Tags:

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.

like image 478
harkor Avatar asked Jan 30 '14 09:01

harkor


People also ask

What is directive HTML?

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.

What is the use of append in JavaScript?

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.


1 Answers

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

like image 142
Vadim Avatar answered Oct 04 '22 17:10

Vadim