ng-bind-html not working with my $scope.variable - html

I am trying to add something like dynamic HTML using ng-bind-html but its not working with $scope variable
Here is my Angular code
1)My controller
$scope.name = "Parshuram"
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml("<div>{{name}}</div>");
Also that my string is dynamic
"<div><table class=" + "\"table table - bordered table - responsive table - hover add - lineheight table_scroll\"" + "><thead><tr><td>Name</td><td>Age</td></tr></thead><tbody><tr ng-repeat=" + "\"tr in dyna\"" + "><td>{{tr.name}}</td><td>{{tr.age}}</td></tr></tbody></table></div>"
So i cant replace every variable with $scope
2)- My HTML
<div ng-app="mymodule" ng-controller="myModuleController">
<div ng-bind-html="thisCanBeusedInsideNgBindHtml"></div>
</div>
I got this output
{{name}}
My expected output is
Parshuram
Please can anyone help i am stuck at this point,does that $sce does not bind scope variable?? ..

I've created a working plnkr here: https://plnkr.co/edit/uOdbHjv1B7fr0Ra1kXI3?p=preview
the problem is that ng-bind-html is not bound to the scope.
you should manually compile the content.
a valid and reusable solution should be creating a directive, whitout using any external modules.
function compileTemplate($compile, $parse){
return {
link: function(scope, element, attr){
var parsed = $parse(attr.ngBindHtml);
function getStringValue() { return (parsed(scope) || '').toString(); }
scope.$watch(getStringValue, function() {
$compile(element, null, -9999)(scope);
});
}
}
}
<div ng-app="mymodule" ng-controller="myModuleController">
<div ng-bind-html="thisCanBeusedInsideNgBindHtml" compile-template></div>
</div>

ng-bind-html does what it says on the tin: it binds html. It doesn't bind angular template code into your dom.
You need to do this instead:
$scope.thisCanBeusedInsideNgBindHtml =
$sce.trustAsHtml("<div>"+$sanitize(name)+"</div>");
To do this you'll want to include the module ngSanitize from the javascript angular-sanitize.js. See https://docs.angularjs.org/api/ngSanitize
If you want to insert some html that includes angular directives then you should write your own custom directive to do it.

In your html just use
{{name}}
The {{var}} notation is to be used in the HTML code to evaluate that variable.

You can do :
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml('<div ng-bind="name"></div>');

Sorry I make another answer.
If you have
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml("<div>{{name}}</div>");
Then you can do
var str = "<div>{{name}}</div>";
var output = str.replace('{{name}}', $scope.name);
It seems to be the only option.

Related

How can I use ng-bind-html inside my directive?

I'm using templates based on my JSON. So, I can't really use my ng-bind-html like I would normally do.
Seems like the only option I have is to use my sanitized html inside an directive.
Looking for similar questions, I couldn't figure it out how to apply in my case.
Yes, I am pretty newbie into angular.
I'm currently receiving this data from my controller:
$scope.safecontainers = $sanitize($scope.containersmsg);
In my html would normally be like this:
<p ng-bind-html="containersmsg"></p>
But I don't want this, I need to use this ng-bind-html inside a directive!
Some people have talked about $compile, but I couldn't really figure it out how to apply in my case.
EDIT:
Based on comments, i'll add more code to help you guys further understand my goal.
Inside my index.html I'm declaring the controllers needed and calling my
<ng-view></ng-view>
Then, based on what I receive, i'll load one view or another:
<div ng-if='setores[0].SetorTema == "1"'>
<theme-one titulo="{{setores[0].SetorNome}}" logo="
{{setores[0].SetorLogo}}" evento="{{evento[0].EventoNome}}">
</theme-one>
// I omitted some of the parameters because they ain't relevant
</div>
My template is like this: (Just a little part of it to avoid much useless code)
<section class="target">
<div class="col-md-6 col-xs-12">
<div class="" ng-repeat="banner in title">
<div class="target-title">{{ banner.BannerLevelTitulo }}
</div>
<div class="target-desc">{{banner.BannerLevelDescricao}}</div>
</div>
</div>
<div class="col-md-6 col-xs-hidden">
<div class="target-image"><img ng-src="{{targetimage}}" alt="">
</div>
</div>
</section>
This is the controller I want my sanitized code.
hotsite.controller('containerController', function($scope, $http, $sanitize)
{
$scope.containers = [];
$scope.containersmsg = '';
$scope.safecontainers = $sanitize($scope.containersmsg);
$http.get('/Admin/rest/getContainer')
.then(function onSuccess(response) {
var data = response.data;
$scope.containers = data;
$scope.containers = response.data.filter(containers =>
containers.ContainerAtivo);
$scope.containersmsg = $scope.containers[0].ContainerDesc;
})
.catch(function onError(response) {
var data = response.data;
console.log(data);
});
});
This is a piece of my directive:
angular.module('hotsiteDirectives', [])
.directive('themeOne', function($compile) {
var ddo = {};
ddo.restrict = "AE";
ddo.transclude = true;
ddo.scope = {
titulo: '#',
...
(a lot of other scope's)
contimg: '#'
};
ddo.templateUrl = 'app/directives/theme-one.html';
return ddo;
})
And yes, I am calling the ngSanitize
var hotsite = angular.module('hotsite',['ngRoute', 'hotsiteDirectives',
'ngSanitize']);
TL;DR
This is how my code looks like inside a directive, with raw html and not rendered:
This is how it works with ng-bind-html, formatted html
If I do put this inside my view
<p ng-bind-html="containersmsg"></p>
It will be alright, all of it working like it should.
BUT, I need to call this only inside my directive, and I don't know how to do it.
So, with this context:
How can I put my sanitized html inside my directive and template?
You don't even have to trust the html to render it using ngBindHtml because the directive already does it for you. You basically need to create a parameter attribute for your directive to hold the html string, so, inside the directive's template, you use ng-bind-html="myParam".
The following snippet implements a simple demonstration of creating a directive that receives and renders an html input parameter that comes from a controller.
angular.module('app', ['ngSanitize'])
.controller('AppCtrl', function($scope) {
$scope.myHtml = '<div><b>Hello!</b> I\'m an <i>html string</i> being rendered dynamicalli by <code>ngBindHtml</code></div>';
})
.directive('myDirective', function() {
return {
template: '<hr><div ng-bind-html="html"></div><hr>',
scope: {
html: '='
}
};
});
<div ng-app="app" ng-controller="AppCtrl">
<my-directive html="myHtml"></my-directive>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular-sanitize.js"></script>

How to Display value of dynamically created varible using AngularJS

My HTML template code is:
<p>{{"fieldname_"+lang}}</p>
In the controller I have the following:
$scope.lang = "mr";
$scope.fieldname_mr = "Dynamic varible";
I want the result to be Dynamic varible, but it is fieldname_mr.
How can I achieve that?
You can use bracket notation to achieve this:
angular.module('app', [])
.controller('testController',
function testController($scope) {
$scope.lang = "mr";
$scope.dynamicVars = {fieldname_mr : "Dynamic varible"};
});
<body ng-app="app">
<div class="table-responsive" ng-controller="testController">
{{dynamicVars["fieldname_" + lang]}}
</div>
</body>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
that you wnt is not able, i made a middleware solution that mantains all your needed but passed by a function that made the return of var, understand that angular force to made like this
<div ng-controller="MyCtrl">
<span ng-init="">{{getValue('fieldname_'+lang)}}</span>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.lang = "mr"; $scope.fieldname_mr = "Dynamic varible";
$scope.getValue =function(name){
return $scope[name] ||'no existe man';
}
}
Yes you can do it like you set your dynamic variable in angular as follow:
what you want variable name store in variable than follow code:
$scope[dynamic_var]=Value of variable;
when you fetch this value as like:
Use this when you not fix property of scope
alert($scope[dynamic_var])
use when you have fix property name
alert($scope.dynamic_var)

AngularJS increment confusion on keeping code separate MVC

I am learning AngularJS at the moment and I am a little confused about the MVC separation of code throughout the DOM/file structure when using AngularJS.
I learn best when I work on a project. Right now I am working on a simple counter that adds a whole number when a button is pushed. I only have one way working and I am thinking of a better way to do this.
Right now I have this working in the code I am working on from AngularJS documentation itself.
I am probably crazy thinking that this cannot be the best way to do this. From my understanding ng-click is a directive that triggers a specific scope of code within the controller.
Why is Increment code inline within the DOM? As a MVC, should the code be organized to not be all over the place, such as in the main controller.js? I have tried to put the increment += function in a counter object, but could not get it to work, see jsFiddle.
<div ng-controller="MyCtrl">
<button ng-click="char">Charged</button>
<span>Total: {{ count }}</span>
</div>
I get that Apps view information based on expressions, filters, and directives. Directives bind to HTML to change behavior of the HTML. Clicks (with Directive selectors) controllers triggers AngularJS to run functions to update data without the entire page being reloaded.
So the Model is the whole setup.
The View is the expressions, filters, and directives.
Controller is the JS file of code that has objects and functions needed for the HTML Directives.
The example of the documentation has inline controller in the directive ng-click within the button tag…
Does anyone have any advice? Thank you.:)
There is a correct way of doing that in angular via a controller:
http://jsfiddle.net/zhxztysy/1/
Your fiddle was like this
<div ng-controller="MyCtrl">
<button ng-click="char">Charged</button>
<span>Total: {{ count }}</span>
</div>
function MyCtrl($scope) {
$scope.count = 0;
$scope.count = Function (char) {
$scope.count += char;
};}
Changed to this
<div ng-controller="MyCtrl">
<button ng-click="charge(5)">Charged</button>
<span>Total: {{ count }}</span>
</div>
function MyCtrl($scope) {
$scope.count = 0;
$scope.charge = function (char) {
$scope.count += char;
};
}
Can also extended like this
<div ng-controller="MyCtrl">
<button ng-click="charge()">Charged</button>
<span>Total: {{ count }}</span>
</div>
function MyCtrl($scope) {
$scope.count = 0;
$scope.chargingCount = 5;
$scope.charge = function () {
$scope.count += $scope.chargingCount;
};
}
I edited your jsfiddle to work. You have made a syntax error (bound $scope.count to a function and tried to add numbers to it later on)

How to render a HTML tag from json value using angularJs

// json is like this
"_unparsedString": "<p>test<\/p>"
// HTML
<div>Preamble : '{{item2._unparsedString}}'</div>
//Output
Preamble : <p>test<\/p>
but how to render that tag and display it using angular ?
//Output should be like this
Preamble : test
Instead of passing string to view directly, you should use sce.trustAsHtml to pre-process the html.
$scope.bindHTML = $sce.trustAsHtml(item2._unparsedString);
Then in your view template, use ng-bind-html to handle html binding.
<div>Preamble : <div ng-bind-html="bindHTML"></div></div>
As you mentioned you have an array of object, it's not that easy to cast them in your controller, you can bind $sce to your $scope then call trustAsHtml in your view
So in your controller
myapp.controller('mainController', function ($scope, $http, $filter, $sce) {
$scope.$sce = $sce;
...
}
Then in your html view
<div>Preamble {{$index+1}} : <span ng-bind-html="$sce.trustAsHtml(item1.Preamble._unparsedString)"></span></div>
Please check this working example: http://jsfiddle.net/Shital_D/b9qtj56p/6/
Download file - angular-sanitize.js and include it in your app.
var app = angular.module('myApp', ["ngSanitize"]);
app.controller('myController', function($scope,$compile) {
$scope.html = '<p>Your html code</p>';
});
<div ng-app="myApp">
<div ng-controller="myController">
<p ng-bind-html="html"></p>
</div>

Polymer 1.0 - Binding css classes

I'm trying to include classes based on parameters of a json, so if I have the property color, the $= makes the trick to pass it as a class attribute (based on the polymer documentation)
<div class$="{{color}}"></div>
The problem is when I'm trying to add that class along an existing set of classes, for instance:
<div class$="avatar {{color}}"></div>
In that case $= doesn't do the trick. Is any way to accomplish this or each time that I add a class conditionally I have to include the rest of the styles through css selectors instead classes? I know in this example maybe the color could just simple go in the style attribute, it is purely an example to illustrate the problem.
Please, note that this is an issue only in Polymer 1.0.
As of Polymer 1.0, string interpolation is not yet supported (it will be soon as mentioned in the roadmap). However, you can also do this with computed bindings. Example
<dom-module>
<template>
<div class$="{{classColor(color)}}"></div>
</template>
</dom-module>
<script>
Polymer({
...
classColor: function(color) {
return 'avatar '+color;
}
});
<script>
Edit:
As of Polymer 1.2, you can use compound binding. So
<div class$="avatar {{color}}"></div>
now works.
Update
As of Polymer 1.2.0, you can now use Compound Bindings to
combine string literals and bindings in a single property binding or text content binding
like so:
<img src$="https://www.example.com/profiles/{{userId}}.jpg">
<span>Name: {{lastname}}, {{firstname}}</span>
and your example
<div class$="avatar {{color}}"></div>
so this is no longer an issue.
The below answer is now only relevant to versions of polymer prior to 1.2
If you are doing this a lot, until this feature becomes available which is hopefully soon you could just define the function in one place as a property of Polymer.Base which has all of it's properties inherited by all polymer elements
//TODO remove this later then polymer has better template and binding features.
// make sure to find all instances of {{join( in polymer templates to fix them
Polymer.Base.join = function() { return [].join.call(arguments, '');}
and then call it like so:
<div class$="{{join('avatar', ' ', color)}}"></div>
then when it is introduced by polymer properly, just remove that one line, and replace
{{join('avatar', color)}}
with
avatar {{color}}
I use this a lot at the moment, not just for combining classes into one, but also things like path names, joining with a '/', and just general text content, so instead I use the first argument as the glue.
Polymer.Base.join = function() {
var glue = arguments[0];
var strings = [].slice.call(arguments, 1);
return [].join.call(strings, glue);
}
or if you can use es6 features like rest arguments
Polymer.base.join = (glue, ...strings) => strings.join(glue);
for doing stuff like
<div class$="{{join(' ', 'avatar', color)}}"></div>
<img src="{{join('/', path, to, image.jpg)}}">
<span>{{join(' ', 'hi', name)}}</span>
of just the basic
Polymer.Base.join = (...args) => args.join('');
<div class$="{{join('avatar', ' ', color)}}"></div>
<template if="[[icon_img_src]]" is="dom-if">
<img class$="{{echo_class(icon_class)}}" src="[[icon_img_src]]">
</template>
<span class$="{{echo_class(icon_class, 'center-center horizontal layout letter')}}" hidden="[[icon_img_src]]">[[icon_text]]</span>
<iron-icon icon="check"></iron-icon>
</div>
</template>
<script>
Polymer({
echo_class: function(class_A, class_Z) {
return class_A + (class_Z ? " " + class_Z : "");
},