AngularJS rendering html tag as string - angularjs

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>

Related

AngularJS - Controller values not binding

In my MVC program simple angular value controllers values are not binding.
My code is as follows :
_Layout.cshtml
<body data-ng-app="ShoppingCartApp">
<div class="container body-content">
#RenderBody()
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/Scripts/angular.js")
#Scripts.Render("~/Scripts/Custom/App.js")
#Scripts.Render("~/Scripts/Custom/ShoppingCartController.js")
#RenderSection("scripts", required: false)
<hr />
</div>
</body>
App.js
var app = angular.module('ShoppingCartApp', []);
ShoppingCartController.js
app.controller('ShoppingCartController', function ShoppingCartController($scope, $http) {
$scope.ShoppingCartObj.products = [];
$scope.test = "ABC";
// On load events
// $scope.loadValues();
});
My Html Code is follows :
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script></script>
<h2>Index</h2>
Total {{2+2}} // This value workd FINE
<div ng-controller="ShoppingCartController">
<div class="row">
<div class="nav navbar-nav navbar-left">
<h3>Total {{2+2}}</h3> // Not working THIS
</div>
<h1>{{test}}</h1> // Not working THIS
</div>
</div>
When i try to access value in controller or access directive inside controller it's not working. What i miss in here?
Change your controller to:
app.controller('ShoppingCartController', function($scope, $http) {....});
Or create a function named ShoppingCartController and then pass it to controller:
app.controller('ShoppingCartController', ShoppingCartController);
Also change $scope.ShoppingCartObj.products to $scope.ShoppingCartObj = {}; and then add products to that object $scope.ShoppingCartObj.products = []; because, prev you havnt defined what $scope.ShoppingCartObj is, so this object will be undefined.
If you're using Bundler you need to specify the Dependency Injection values
Also - ShoppingCartObj isn't declared anywhere so you can't assign to a property products
app.controller('ShoppingCartController', ['$scope', '$http',
function ShoppingCartController($scope, $http) {
$scope.ShoppingCartObj = {},
$scope.ShoppingCartObj.products = [];
$scope.test = "ABC";
}]);
Here's a working Jsfiddle

ng-click inside ng-repeat doesnt work

I have html which looks like one below, I have 2x ng-click in whole code in both situation I call same function. Both functions are in same controller.
<div class="tagselect tagselect--frameless">
<div class="combobox__body combobox__body--open combobox__body--frameless" ng-show="focus">
<ul class="list-unstyled">
<li class="combobox__item" ng-repeat="pos in listCtrl.positions | filter:query as results"
ng-click="listCtrl.choosePosition(pos)">{{pos.name}}
</li>
</ul>
</div>
</div>
<div class="col-md-2 no-padding">
<button type="button" class="btn btn-success" ng-click="listCtrl.chosenPositions(789456)">Add</button>
</div>
controller looks like:
myApp.controller('ListCtrl', ['$scope', '$cookies', '$http', function ($scope, $cookies, $http) {
var listCtrl = {
candidates: [],
positions: [],
chosenPositions: [],
init: function () {
listCtrl.getCandidates();
listCtrl.getPositions();
},
getCandidates: function () {
$http.get('candidates.json').then(function (res) {
listCtrl.candidates = res.data;
});
},
getPositions: function () {
$http.get('positions.json').then(function (res) {
listCtrl.positions = res.data;
});
},
choosePosition: function (position) {
console.log(position);
}
};
listCtrl.init();
$scope.listCtrl = listCtrl;
}]);
I double check for missspells and make sure its not because of function (I create a new one with simple console log).
Problem is that button click correctly call function but ng-repeat <li ng-click=""> doesnt do anything. I read in angular documentation that ng-repeat create new scope but this should be still okey in my opinion as soon as I use reference to object listCtrlchoosePosition()
Can someone tell me what I am doing wrong?
Thanks
EDIT: Plunker example:
http://plnkr.co/edit/ooUQA2n1Vyj8RZtsQ1Pj?p=preview
ng-blur is doing something weird, so I'm going to suggest you to change the $scope.focus value from the ListCtrl instead of using the ng-blur.
html file
<!-- more html code -->
<!-- input without ng-blur directive -->
<input class="tagselect__input" placeholder="Position" ng-focus="focus=true" ng-model="query">
<!-- more html code -->
<li class="combobox__item" ng-repeat="pos in listCtrl.positions | filter:query as results" ng-click="listCtrl.choosePosition(pos)">{{pos.name}}
<!-- more html code -->
js file
// more code goes here.
choosePosition: function (position) {
//alert('Going to choosen position');
//$scope.query = position.name;
$scope.focus = false; // Hide div options from here.
// rest of your code.
},
// more code goes here.
Working in this plunkr

How do I search JSON data originating on another server using AngularJS

I have data to search through. I am writing a directory app in AngularJS that takes JSON data from one of our servers; an employee list. I need to be able to do a live search on that data, but nothing I have tried seems to work. Specifically, the view does not update.
Code: app.js
var app = angular.module('directory', ['ngRoute']);
app.service('DirectoryService', ['$http', function($http){
var baseURL = "http://xxx.xxx.xxx.xxx/accounts/people/json";
return{
getEmployees: function() {
return $http.get(baseURL).then(function(response){
return response.data;
});
}
}
}]);
app.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/employees', {
templateUrl: '_common/partials/list.html'
})
.otherwise({
redirectTo: '/employees'
});
}]);
app.controller('DirectoryController', ['$scope', 'DirectoryService',
function($scope, DirectoryService){
$scope.searchName = '';
DirectoryService.getEmployees().then(function(data){
$scope.employeeList = data;
console.log(data);
});
}]);
Code: list.html
<div id="searchSection">
<input id="searchValue" type="text" placeholder="Search by Name" ng-
model="searchName" />
</div>
<div id="listView">
<ul>
<li ng-repeat='employee in employeeList | filter: {name:searchName}'>
<p>{{employee.name}}</p>
</li>
</ul>
</div>
When I've added filters I simple add an input with ng-model:
<input class="form-control" ng-model="searchFilter" placeholder="Filter..." />
Then in my ng-repeat:
<tbody ng-repeat="user in usc.users | filter:searchFilter">
<tr>
{{user.name}}
</tr>
</tbody>
That should filter through all the names.
Better to use a factory for your service, have the service hold the data for you, and reference it in your controller. Something along these lines should work:
app.factory('DirectoryService', ['$http', function($http) {
var service = {};
service.data = {
baseURL:"http://xxx.xxx.xxx.xxx/accounts/people/json",
employeeList:[],
searchName:""
}
service.getEmployees = function() {
$http.get(service.data.baseURL).success(function(response) {
service.data.employeeList = response;
})
}
return service;
}])
Then your controller function can reference the service's data, which will dynamically update:
app.controller('DirectoryController', ['$scope', "DirectoryService", function($scope, DirectoryService) {
$scope.ds = DirectoryService.data;
DirectoryService.getEmployees();
}])
So your relevant HTML function should look like this:
<input id="searchValue" type="text" placeholder="Search by Name" ng-model="ds.searchName" />
<li ng-repeat="employee in ds.employeeList | filter:{name:ds.searchName}">
<p>{{employee.name}}</p>
</li>
So while I was trying your problem on fiddle I came across a problem and that is ng-model="searchName" is not binding to the model value.
And the reason was there was a space between
ng-[space]model. //also ng-model should be in red in your code above but it is in red and black..:P
So it might be possible that this could be the issue with this.
One more this do not use any other parameter with filter like you did here
use this simple form.
<li ng-repeat="employee in ds.employeeList | filter : searchName">
Here is my fiddle with the working solution Fiddle Solution
<div ng-app="directory" id="searchSection" ng-controller="DirectoryController">
<input id="searchValue" type="text" ng-model="searchName" />
<div id="listView">
<ul>
{{searchName}}
<li ng-repeat="employee in employeeList | filter: searchName">
<p>{{employee.name}}</p>
</li>
</ul>
</div>
</div>
js:
var app = angular.module('directory', []);
app.controller('DirectoryController', ['$scope',
function($scope){
$scope.searchName = 'Fi';
$scope.employeeList = [{name : "First Employee", salary : 100}, {name : "Second Employee", salary : 200}];
}]);
You can not because the mechanism json is limited to the domain you belong. To do this you must use the jsonp

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

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/";
}]);

How to pass scope variable through ng-click function?

Here when i click on cartDetails the dynamic scope variable x.SmId value need to be passed to the bellow function and in alert box need to display the parameter .How can we do this one in angular js?
<div ng-app="" ng-controller="MyCtrl">
<div ng-repeat="x in names">
<div ng-click="cartDetails('{{x.SmId}}')">
<div>{{x.name}}</div>
</div>
</div>
</div>
<script>
angular.module('MyApp', [])
.controller('MyCtrl', ['$scope', '$http', function($scope, $http) {
$scope.search = function(param) {
$http.get('AngularJs-Response.jsp?mid='+param).success(function(response) {
$scope.names = response;
});
};
$scope.cartDetails = function(smid) {
alert(smid);
};
}]);
</script>
Use simple:-
ng-click="cartDetails(x.SmId)"
I tried to use:
ng-click="cartDetails(x.SmId)"
but it simply x.SmId as string, its not replaced by value. After reading few more articles, I found a solution like below:
<div ng-click="cartDetails('{{x.SmId}}')">
Its a working solution in AngularJS v1.3.9

Resources