Append html to an element in directive and make a local function to interact with it
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
Related videos on Youtube
harkor
Updated on July 21, 2022Comments
-
harkor almost 2 years
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 theng-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.
-
Davin Tryon over 10 yearsWhy not use template?
-
harkor over 10 yearsFor example, I have this style of input <input type="text" placeholder="{{lang('placeholderWhere')}}" name="where" id="where-input" ng-model="data.form.where.txt" google-places my-position erase-btn /> and I have this style of input <input type="text" id="what-input" placeholder="{{lang('placeholderWho')}}" name="who" ng-model="data.form.who.txt" typeahead="item for item in autoComplete.list['who'] | filter:$viewValue" autocomplete-api erase-btn /> How can I keep other directives ok with a template ?
-
harkor over 10 yearsSorry for crappy style => pastebin.com/9LeSatGH
-
Sakeer almost 10 yearsgood question. did you got the solution for this?
-
harkor almost 10 yearsNo sorry, I searched a lot of time and I found anything.
-
-
harkor over 10 yearsI don't understand... Your example give me a method with different type attribute... My problem is I call different other directives... I Just want to add a button after the input and can make a controller click inside this directive...
-
Vadim over 10 yearsI have updated the example, but general idea is the same: write directive that displays custom input + close button (on demand). Inputs (checkbox, text) may be any custom input with other directives and not only standard html inputs.
-
irth almost 10 yearsWhat about select options? how to append this within the select element tags.
-
Jakob Jenkov over 9 yearsIn my experience, element.append() does not work inside of a directive. AngularJS's append() version strips out all HTML. This only works if you also include jQuery in your page, in which case AngularJS uses jQuery's append().
-
ESP32 over 7 yearsCan I link the "input" variable to the link function without knowing its name? The directive is not well re-usable if I need to name my variables in the html the same way as in the directive.
-
Vadim over 7 years@Gerfried Sure, in the plnkr.co/edit/1WEY8laNKbwpM6swBYcw?p=preview you can see an example in which
input
is a value taken from isolated scope of directive, which is bound to attributedemo-directive
of the element