angularjs to output html clickable element instead of html as a string - angularjs

I am using a filter to convert any URL or email id from a piece of content. but its getting rendered as a string not as a clickable HTML element.
Filter JS
angular.module('myApp.filters', []).filter('parseUrl', function() {
var urls = /(\b(https?|ftp):\/\/[A-Z0-9+&##\/%?=~_|!:,.;-]*[-A-Z0-9+&##\/%=~_|])/gim
var emails = /(\w+#[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim
return function(text) {
if (text.match(urls)) {
text = text.replace(urls, "$1")
}
if (text.match(emails)) {
text = text.replace(emails, "$1")
}
return text
}
});
this above code output me with a plane text and not clickable HTML elements.
Fiddle

I have updated JS Fidle
HTML:
Added
ng-bind-html
<div ng-app="miniapp">
<div ng-controller="Ctrl">
<h1 ng-bind-html="test | parseUrl">{{test}}</h1>
</div>
</div>
Documentation ngBindHtml

Your filter should make use of the Strict Contextual Escaping $sce to return trusted HTML
angular.module('myApp.filters', []).filter('parseUrl', function ($sce) {
var urls = /(\b(https?|ftp):\/\/[A-Z0-9+&##\/%?=~_|!:,.;-]*[-A-Z0-9+&##\/%=~_|])/gim
var emails = /(\w+#[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim
return function (text) {
if (text.match(urls)) {
text = text.replace(urls, "<a ng-href=\"$1\" target=\"_blank\">$1</a>");
}
if (text.match(emails)) {
text = text.replace(emails, "<a ng-href=\"mailto:$1\">$1</a>");
}
return $sce.trustAsHtml(text);
}
});
Update
It seems your are using an older version of Angular (version 1.0.2) which doesn't have the Strict Contextual Escaping $sce. That explains your usage of ngSanitize module.
Your filter code is correct, but you should bind your text differently using the ng-bind-html.
<div ng-app="miniapp">
<div ng-controller="Ctrl">
<h1 ng-bind-html="test | parseUrl"></h1>
</div>
</div>
JsFiddle : http://jsfiddle.net/fb4meygo/1/

With the help of linky filter we can detect links from text and show them differently. Linky takes text and produces HTML by wrapping all URLs into anchor tags. It supports email address, http, https, and mailto.
HTML:
<div ng-app="myApp" ng-controller="myController">
<div>
<p ng-bind-html="myText | linky :'_blank'"></p>
<textarea ng-model="myText" style="width: 420px; height: 120px"></textarea>
</div>
</div>
Controller:
var myApp = angular.module('myApp', ['ngSanitize'])
.controller('myController', ['$scope', function ($scope) {
$scope.myText = "Some default text is here http:/tothenew.com/";
}]);

Related

how to check that array inside an array has any value (angularjs)

There is an array contentMetaDataList inside another array (content) which contents few field like title, name, etc. so how i can hide heading (smart tags: written inside p tag) when there is no title to display.
Smart Tags :
{{relatedcontent.title}}
You can use ng-show in order to show/hide by condition,
and to check if all the objects in your array includes the title field, you can use Array.every().
If you comment or remove one of those titles in the array, the wrapper <div> which show the titles won't be visible, but stays in the DOM tree. (removing from the DOM tree can be done by ng-if)
var app = angular.module('myApp', []);
app.controller('MainCtrl', ['$scope','$http', function($scope, $http){
$scope.a = 'sdf';
$scope.contentMetaDataList = [
{
title:"legislation_title",
fieldValue:"refund of tax to certain persons",
id:94346
},
{
title:"Enterprise_title",
fieldValue:"refund of tax to certain persons",
id:94346
},
{
title:"Related_title",
fieldValue:"refund of tax to certain persons",
id:94346
}];
$scope.checkTitle = function() {
return $scope.contentMetaDataList.every(item => item.title);
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MainCtrl">
<div>
<div ng-show="checkTitle()">
<p>Smart Tags : </p>
<div ng-repeat="relatedcontent in contentMetaDataList">
<div>
{{relatedcontent.title}}
</div>
</div>
</div>
</div>
</div>
</div>
for more info:
ng-show
Array.every()
ng-if
I would say add a <span> or some tag with a ngIf. *ngIf="relatedcontent.title !== undefined"

Angular JS "<a href='tel:{num} '> call me</a> hyperlink does not work

While trying to render the hyper link using Angular JS it does not generate the hyper link. All other tags like <p> or <h2> work fine, but href fails.
var tempString = "<a href='tel:{mob_number}'>call me support</a>"
actual output - string is displayed but hyperlinked is not rendered. It's not clickable. Inspect page display tag generated as
<a> call me support </a>
Expected output - should display string with hyperlink.
I try to do this by 3 mood "Html, directive, bind-html"
Directive not work stackoverflow, try it on your local
var app = angular.module("app", []);
app.controller("ctrl", [
"$scope", "$sce",
function($scope, sce) {
$scope.mob_number = "123";
var tempString = "call me support";
$scope.asHtmlTemplate = sce.trustAsHtml(tempString);
}
]);
app.directive("mobile", function() {
return {
templateUrl: "mobile.html",
scope: {
content: "#",
mobNumber: "="
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<h4>simple html</h4>
<a ng-href="tel:{{mob_number}}">call me support</a>
<h4>as directive [directive not display in stackoverflow]</h4>
<mobile mob_number="mob_number" content="call me support"></mobile>
<!-- directive not display in stackoverflow ? -->
<h4>as Html template from controller</h4>
<div ng-bind-html="asHtmlTemplate"></div>
<script type="text/ng-template" id="mobile.html">
<a ng-href='tel:{{mobNumber}}'>{{content}}</a>
</script>
</div>

AngularJS ng-attr not working when used with a tag with a dash

I am trying to generate a JS Chart with a value from a $scope but the value does not get updated in that specific tag because it has a dash in it, it works perfectly when I tested it in the div above to replace the width's value of 100 with the $scope and it works but just not with this specific tag. Any ideas?
HTML
<div class="col-md-12 col-sm-12 col-xs-6" ng-controller="HomeCtrl">
<div>
<p>Option1</p>
<div class="">
<div class="progress progress_sm" style="width: 100%;">
<div class="progress-bar bg-green" role="progressbar" ng-attr-data-transitiongoal="{{total | number:0}}"></div>
</div>
</div>
</div>
</div>
This is the code from the controller, the server code for the route (for pulling data from MongoDB) works perfectly because I was able to pull the data and I have been able to use console.log() to print in the route as well:
Script
function HomeCtrl($scope, $http, $filter) {
$scope.total = 0;
var refresh = function() {
$http.get("/homelist").success(function(response) {
$scope.homelist = response;
var homelista = $scope.homelist;
for (var i = 0; i < homelista.length; i++) {
var donedeals = homelista[i];
$scope.total += (Number(donedeals.hgtgt));
}
};
refresh();
}
}
More importantly I am able to use the data in the js file with other html tags, so the server or the controller is not the problem at all but it is either a bug with Angular or something I am missing with the html tag.

how to call controller function from template in angularjs

I am creating an html from controller and appending this html to included html file in template view. but I am unable to call controller function from there when i am clicking on checkbox. I want to get all those values in that function.
This is my test html code:-
<div ng-app>
<div ng-controller="TodoCtrl">
<div id="priceappend"></div> <!-- This div I am using in included html say test1.html -->
<!-- I cannot iterate array over here, As I am appending priceHtml into test1.html which I am including using ng-include -->
</div>
</div>
and this is my controller js code:-
function TodoCtrl($scope,$window) {
$scope.pricerangelist = {
chkbox1:{selected:false,id:'below100',minvalue:'0',maxvalue:'100'},
chkbox2:{selected:false,id:'below400',minvalue:'100',maxvalue:'400'},
};
var priceHtml = '';
priceHtml +='<div class="ui-checkbox ui-checkbox-row"><label for="below100" class="ui-btn ui-corner-all ui-btn-d ui-btn-icon-left">100 and below</label><input type="checkbox" min_value="0" max_value="100" value="100 US$ and below" class="range myinput large custom" ng-change="pricelistAction(pricerangelist)" ng-model="pricerangelist.chkbox1.selected" name="range[]" id="below100"></div>';
priceHtml += '<div class="ui-checkbox ui-checkbox-row"><label for="below400" class="ui-btn ui-corner-all ui-btn-d ui-btn-icon-left">101 and 400</label><input type="checkbox" min_value="101" max_value="400" value="101 US$ and 400 US$" class="range myinput large custom" ng-change="pricelistAction(pricerangelist)" ng-model="pricerangelist.chkbox2.selected" name="range[]" id="below400"></div>';
var myEl = angular.element( document.querySelector( '#priceappend' ) );
myEl.append(priceHtml);
$scope.pricelistAction = function(val){
console.log(val);
//this function is not calling.
};
}
here is the plnkr
You need to compile the newly created HTML so as to use scope.
so replace myEl.append(priceHtml); with myEl.append($compile(priceHtml)($scope));
http://jsfiddle.net/U3pVM/23071/
Add $complie to your controller like this function TodoCtrl($scope,$window, $compile)
Now before appending the html string call $compile, so that the functions in the template string can be bound to $scope.
myEl.append($compile(priceHtml)($scope))

AngularJS rendering html tag as string

There is <ul> <li>..</li> </ul> tag which contains a product description.
I used ngSanitize dependency but it did not work. I also tried ng-bind-html, $sce.trustAsHtml() but it is not working. Result is rendering the tag itself as string like <ul><li>something</li></ul>
I am using angular 1.4.
On browser console it is printing like:
<ul><li>Experience subject to availablity</li>
And on HTML page it is printing like:
<ul> <li> Experience subject to availablity</li>......
First I tried sanitize dependacy with html-bind-unsafe
var app = angular.module('frogo-app', ['ngAnimate', 'ui.bootstrap','ngRoute', 'ngSanitize']);
app.controller('contactController', function($scope, $http, myservice) {
$scope.ysk = data from server;
......
}
HTML
<div ng-bind-html="ysk"></div>
Secondly I tried
app.controller('contactController', function($scope, $http, $sce, myservice) {
$scope.ysk =$sce.trustAsHtml($scope.you_should_know);
......
}
HTML
<div ng-bind-html="ysk"></div>
Third I tried
app.filter('unsafe', function($sce) { return $sce.trustAsHtml;});
HTML
<div ng-bind-html="ysk | unsafe"></div>
I use this filter :
/**
* to interpret html code in the view ( otherwise it display the code without interpret it )
*
* usage : <span ng-bind-html="value | unsafe"></span>
*/
var interfaceApp = angular.module('interfaceApp', []);
interfaceApp.filter('unsafe', function ($sce) {
return function (val) {
return $sce.trustAsHtml(val);
};
});
and call it the html view like this :
<span ng-bind-html="value | unsafe"> </span>
value is the data you want to disply contenaing html tag
I could be totally wrong but it sounds like you are trying to evaluate a string containing HTML from a database query and render it as html...
You would want to do something like this:
In your template:
<div ng-controller="MyCtrl">
Hello, {{name}}!
<div ng-bind-html="my_html | to_trusted"></div>
</div>
And in your js/controller:
var myApp = angular.module('myApp',[]);
angular.module('myApp')
.filter('to_trusted', ['$sce', function($sce){
return function(text) {
return $sce.trustAsHtml(text);
};
}]);
function MyCtrl($scope) {
$scope.name = 'Superhero';
$scope.my_html = '<label><b>Hello </b> <input type="text" value="world !"> </label>';
}
Some from your pseudo-code above with $scope.ysk you would use something like this in your template:
<li><span ng-bind-html="ysk | to_trusted"></span></li>

Resources