AngularJS How to parse html into directive template - angularjs

How i can parse html in directive template???
app.directive('user', function(){
return {
restrict: 'E',
scope: false,
template: '<div class="clearfix buttons-container" ng-bind-html-unsafe="current_text"></div>'
}
});
//in controller
$scope.current_text = 'Hello <strong>'+current_username+'</strong> !!!'

use $sce.trustAsHtml. this method will create trusted HTML object for ng-bind-html directive.
$sce.trustAsHtml Docs
See below example
var app = angular.module('app', []);
app.controller('ctrl', function($scope, $sce) {
var current_username = "User";
var html = 'Hello <strong>' + current_username + '</strong> !!!';
$scope.current_text = $sce.trustAsHtml(html);
});
app.directive('user', function() {
return {
restrict: 'E',
scope: false,
template: '<div class="clearfix buttons-container" ng-bind-html="current_text"></div>'
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="ctrl">
<user></user>
</div>
</div>

you can do this using isolate-scope
in this way.
app.directive('user', function(){
return {
restrict: 'E',
scope: {
current_text : '#current_text'
},
template: '<div class="clearfix buttons-container" ng-bind-html-unsafe="current_text"></div>'
}
});
//in controller
$scope.currenText = 'Hello <strong>'+current_username+'</strong> !!!'
<div current_text="currenText" > </div> // your directive included here

Related

how to get directive attribute values while using submit button

Here i created sample program using angularJs directive and controller, in directive i m created some attributes like (print-Display="true" is-Silent="false" is-Authentication="false" is-Download="false"), how to get this attribute values while using submit button (Controller)
Thanks in advance
var app = angular.module('myApp', []);
app.directive('telPrint', ['$http',
function($http) {
return {
restrict: 'AEC',
require: 'ngModel',
scope: {
ngModel: '=',
printDisplay: '#',
canShow: '#',
isChecked: '#',
isAuthentication: '#',
isDownload: '#',
},
template: '<span > <input type="checkbox" name="ngModel" ng-checked="checked"> <label > Print </label></span> ',
controller: function($scope, $rootScope) {
$scope.printOption = [];
$scope.Authentication = $scope.isAuthentication;
$scope.Silent = $scope.isSilent;
$scope.Download = $scope.isDownload;
},
link: function(scope, iElement, iAttrs, ngModelController) {
var labelName = iAttrs.getString;
var labelName = labelName.split(",");
var language = labelName[0]; // Language EN or Fr
var fieldlabelName = labelName[1]; // Label Name
var fieldmoduleName = labelName[2]; // Module Name (global or local)
if (iAttrs.isSilent == "true") {
scope.checked = true;
} else if (iAttrs.isSilent == "false") {
scope.checked = false;
}
console.log(iAttrs.printDisplay)
}
};
}
])
app.controller('myCtrl', function($scope) {
$scope.printcontr = function() {
console.log("Inside ")
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<div class="row col-sm-12">
<div class="col-sm-12">
<tel-Print ng-model="taxmaster.print" get-string="lbl,print,common" print-Display="true" is-Silent="true" is-Authentication="false" is-Download="true"></tel-Print>
</div>
<div>
<div class="col-sm-12">
</div>
<div class="col-sm-12">
<input type="submit" value="Save" ng-click="printcontr()" />
</div>
</div>
</body>
By scope.$parent, you can access $scope of the controller:
var app = angular.module('myApp', []);
app.directive('telPrint', ['$http',
function($http) {
return {
restrict: 'AEC',
require: 'ngModel',
scope: {
ngModel: '=',
printDisplay: '#',
canShow: '#',
isChecked: '#',
isAuthentication: '#',
isDownload: '#',
},
template: '<span > <input type="checkbox" name="ngModel" ng-checked="checked"> <label > Print </label></span> ',
controller: function($scope, $rootScope) {
$scope.printOption = [];
$scope.Authentication = $scope.isAuthentication;
$scope.Silent = $scope.isSilent;
$scope.Download = $scope.isDownload;
},
link: function(scope, iElement, iAttrs, ngModelController) {
var labelName = iAttrs.getString;
var labelName = labelName.split(",");
var language = labelName[0]; // Language EN or Fr
var fieldlabelName = labelName[1]; // Label Name
var fieldmoduleName = labelName[2]; // Module Name (global or local)
if (iAttrs.isSilent == "true") {
scope.checked = true;
} else if (iAttrs.isSilent == "false") {
scope.checked = false;
}
console.log(iAttrs.printDisplay);
// Set data
scope.$parent.language = labelName[0];
scope.$parent.fieldlabelName = labelName[1];
scope.$parent.fieldmoduleName = labelName[2];
}
};
}
])
app.controller('myCtrl', function($scope) {
$scope.printcontr = function() {
console.log("Inside ");
//Retrive data
console.info('language=', $scope.language);
console.info('fieldlabelName=', $scope.fieldlabelName);
console.info('fieldmoduleName=', $scope.fieldmoduleName);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<div class="row col-sm-12">
<div class="col-sm-12">
<tel-Print ng-model="taxmaster.print" get-string="lbl,print,common" print-Display="true" is-Silent="true" is-Authentication="false" is-Download="true"></tel-Print>
</div>
<div>
<div class="col-sm-12">
</div>
<div class="col-sm-12">
<input type="submit" value="Save" ng-click="printcontr()" />
</div>
</div>
</div>
</body>
I would suggest if you have a need to fetch directive attributes inside parent controller then while defining directive's scope instead of using '#', use '=' (two way binding) so that whatever you will be changing any attribute in the directive, you will always have those values in the parent controller.
app.directive('telPrint', ['$http',
function($http) {
return {
restrict: 'AEC',
require: 'ngModel',
scope: {
ngModel: '=',
printDisplay: '=',
canShow: '=',
isChecked: '=',
isAuthentication: '=',
isDownload: '=',
}...

AngularJS: ng-click not working in custom input directive

I'm new in AngularJS, currently I'm working on custom input directive with a label.
I refer to one article in stack overflow but encountered problem.
The running code is on fiddle:
http://jsfiddle.net/luneyq/bpN9b/18/
Core code is as below:
<!doctype html>
<html>
<head>
<script src="../common/angular.js"></script>
</head>
<body>
<div ng-app="myApp">
<div ng-controller="MainController">
<my-input type="number" name="valueNumber1" ng-model="valueNumber1" label="Age" ng-change="change()" ng-click="click()"></my-input>
<div id="result">a</div>
</div>
</div>
<script>
var app = angular.module("myApp", []);
app.controller('MainController', function($scope, $window){
$scope.valueNumber1 = 10;
$scope.change = function() {
document.getElementById("result").innerHTML = 'change:' + $scope.valueNumber1;
};
$scope.click = function() {
document.getElementById("result").innerHTML = 'click:' + $scope.valueNumber1;
};
});
app.directive('myInput', function() {
return {
require: '^ngModel',
restrict: 'EA',
scope: {
ngModel: '=',
name: '#name',
label: '#label'
},
replace: true,
transclude: true,
//priority: 10,
template: '<div>' +
'<label for="{{ name }}">{{label}}</label>' +
'<input id="{{ name }}" ng-model="ngModel" />' +
'</div>',
compile: function(tElement, tAttrs, transclude) {
var tInput = tElement.find('input');
// Move the attributed given to 'custom-input' to the real input field
angular.forEach(tAttrs, function(value, key) {
if (key.charAt(0) == '$' || key == "class")
return;
tInput.attr(key, value);
tInput.parent().removeAttr(key);
});
tElement.removeAttr('ng-model');
return;
}
};
})
</script>
</body>
</html>
My problems are:
1. ng-click and ng-change not working on the input
2. ng-model="ngModel" on input element, why ngModel is used here? if I change ngModel to aaa, the initial value for the input disappeared
3. attributes copy in compile function removed the dash(-) signal, ng-click is copied as ngClick.
I'm not sure is this the cause of this problem.
Can anyone help on this problem?
Your problem was click and change methods not in your isolate scope - BUT you are not making use of Angular's two way binding here - instead simply use ng-bind on your result div - here's a fiddle http://jsfiddle.net/bpN9b/20/
var app = angular.module("myApp", []);
app.controller('MainController', function($scope, $window){
$scope.valueNumber1 = 10;
});
app.directive('myInput', function() {
return {
require: '^ngModel',
restrict: 'EA',
scope: {
ngModel: '=',
name: '#name',
label: '#label'
},
replace: true,
priority: 10,
template: '<div class="cbay-input-div">' +
'<label for="{{ name }}">{{label}}</label>' +
'<input id="{{ name }}" ng-model="ngModel" />' +
'</div>',
compile: function(tElement, tAttrs, transclude) {
console.log(tAttrs);
var tInput = tElement.find('input');
// Move the attributed given to 'custom-input' to the real input field
angular.forEach(tAttrs, function(value, key) {
//console.log(key + " = " + value);
if (key.charAt(0) == '$' || key == "class")
return;
tInput.attr(key, value);
tInput.parent().removeAttr(key);
});
tElement.removeAttr('ng-model');
return;
}
};
});
here's the template
<div ng-app="myApp">
<div ng-controller="MainController">
<my-input type="number" name="valueNumber1" ng-model="valueNumber1" label="Age" ng-change="change(this)" ng-click="click(this)"></my-input>
<div id="result" ng-bind="valueNumber1">a</div>
</div>
</div>

ng-switch and manually $compile

I tried to make recursive directive like here
Angularjs: understanding a recursive directive
ng-switch options are all commented, ng-if works fine.
I don't know what is a problem.
Just inspect output of ng-switch
var module = angular.module('myapp', []);
module.controller("TreeCtrl", function($scope) {
$scope.controls = [
{
"label":"Checkbox",
"type":"checkbox"
},
{
"label":"input",
"type":"input"
},
{
"label":"Some group",
"type":"Group",
"controls":[
{
"label":"subcontrol",
"type":"input"
}
]
}
];
});
module.directive("tree", function($compile) {
return {
restrict: "E",
scope: {controls: '='},
template:
'<div ng-switch="control.type">' +
'<label>{{control.label}}</label>'+
'<div ng-switch-when="input"><input type="text" name="ctrl1"></input></div>'+
'<div ng-switch-when="checkbox"><input type="checkbox" "name="ctr2"></input></div>'+
'<div ng-repeat="subcontrol in control.controls">' +
'<tree control="subcontrol"></tree>' +
'</div>' +
'</div>',
compile: function(tElement, tAttr, transclude) {
//We are removing the contents/innerHTML from the element we are going to be applying the
//directive to and saving it to adding it below to the $compile call as the template
var contents = tElement.contents().remove();
var compiledContents;
return function(scope, iElement, iAttr) {
if(!compiledContents) {
compiledContents = $compile(contents, transclude);
}
compiledContents(scope, function(clone, scope) {
iElement.append(clone);
});
};
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
<div ng-controller="TreeCtrl">
<div ng-repeat='control in controls'>
<tree control="control"></tree>
</div>
</div>
</div>

how to call parent method from directive?

I have directive like this
.directive('myModal', function() {
return {
restrict: 'A',
replace: true,
scope: {
myModalId: '#'
},
template: '<div id="{{myModalId}}" class="modal">' +
'<div ng-click="parentMethod()" class="modal-dialog">' +
'...' +
'</div>' +
'</div>'
}
});
js code
function ParentController($scope) {
$scope.parentMethod = function() {
alert('clicked');
}
}
There are several ways you can achieve this. I would do it using attribute binding which allows you to execute an expression in the context of the parent scope. This is how you can use it:
<div my-modal my-modal-id="12312" on-click="parentMethod()"></div>
Then in directive you define scope like this:
scope: {
myModalId: '#',
onClick: '&'
}
and in directive template:
<div ng-click="onClick()" class="modal-dialog">
Demo: http://plnkr.co/edit/UDnJGRVqXqbCGSFEAMMA?p=preview
Another way (not recommended), you can directly refer the parent scope from isolated directive scope:
<div ng-click="$parent.parentMethod()" class="modal-dialog">
<body ng-app="myApp">
<div ng-controller="myCtrl">
<direct movied="movie" call-home="callFromDirect"></direct>
</div>
<script>
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope, $rootScope) {
$scope.callFromDirect = function (param) {
console.log('got call to direct ' + param);
}
});
myApp.directive("direct", function () {
return {
restrict: 'E',
scope: {
callHome: '='
},
template: "<input type=\"button\" value=\"click\" ng-click=\"callHome('movie')\" />"
}
});
</script>

How to modify the controller scope from an ng-repeat in a directive, without using a function?

I would like the ng-click to change the value of the controller scope variable 'controllerLabel'. What's the best way of achieving this without using a controller scope function?
HTML:
<div ng-app="app">
<div ng-controller="Ctrl">
<p>{{controllerLabel}}</p>
<my-template></my-template>
</div>
<!-- my-template.html -->
<script type="text/ng-template" id="my-template.html">
<div ng-repeat="clickLabel in clickLabels">
<label ng-click="controllerLabel = {{clickLabel.text}}">{{clickLabel.text}}</label>
</div>
</script>
</div>
JavaScript:
angular.module('app', [])
.controller('Ctrl', function Ctrl1($scope) {
$scope.controllerLabel = 'Default text';
$scope.clickLabels = [
{'text':'Hello'},
{'text':'World'},
];
})
.directive('myTemplate', function() {
return {
restrict: 'E',
templateUrl: 'my-template.html'
};
});
JSFiddle
You can add link to directive and write like:
.directive('myTemplate', function() {
return {
restrict: 'E',
link: function (scope) {
scope.onClick = function (clickLabel) {
scope.controllerLabel = clickLabel.text;
}
},
templateUrl: 'my-template.html'
};
});
HTML
<script type="text/ng-template" id="my-template.html">
<div ng-repeat="clickLabel in clickLabels">
<label ng-click="onClick(clickLabel)">{{clickLabel.text}}</label>
</div>
</script>
Actually you can write like #Alborz posted but I think to add method into link and call from HTML will be clearer and easy to debug.
Demo Fiddle
I updated your fiddle;
Updated fiddle
You need to use controllerLabel as an object property to have a shared object with controller.
angular.module('app', [])
.controller('Ctrl', function Ctrl1($scope) {
$scope.label = {};
$scope.label.controllerLabel = 'Default text';
$scope.clickLabels = [
{'text':'Hello'},
{'text':'World'},
];
})
.directive('myTemplate', function() {
return {
restrict: 'E',
templateUrl: 'my-template.html'
};
});
Template:
Note to label.controllerLabel = clickLabel.text
<div ng-repeat="clickLabel in clickLabels">
<label ng-click="label.controllerLabel = clickLabel.text">{{clickLabel.text}}</label>
</div>

Resources