AngularJS - How to get processed HTML output from $compile? - javascript

I have the following function which is fetching custom HTML template and passing some values into the scope to generate 'report table'. Because the template is not visible to the user but processed output is directly sent to another function I used $compile function.
It seems that values passed into the $scope are processed correctly but i am not able to get pure HTML result.
I tried to do it by this way:
var templateUrl = $sce.getTrustedResourceUrl('report.html');
$templateRequest(templateUrl).then(function(template) {
$scope.rows = reportData;
var compTest = $compile(template)($scope);
console.log(compTest); //IT RETURNS A LOT OF VALUES BUT NOT HTML OUPUT OF THE PROCESSED TEMPLATE
}, function() {
// An error has occurred
});
Many thanks for any advice.
Results is following:
HTML content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Report</title>
</head>
<body>
<table>
<thead>
<td>
</td>
<td>
Breakfast
</td>
<td>
Lunch
</td>
<td>
Dinner
</td>
<td>
Snack
</td>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td>TEST</td>
<td>40</td>
<td>20</td>
<td>30</td>
<td>10</td>
</tr>
</tbody>
</table>
</body>
</html>

$compile will return a function which will then be executed by scope which in turn will returns a jQlite wrapped DOM object. So you can use outerHTML to get the Template string
or
You can use $interpolate as shown below
Demo
angular.module('myApp', []);
angular
.module('myApp')
.controller('MyController', MyController);
function MyController($scope, $compile, $interpolate) {
var template = '<a ng-click="handler()">click handler</a>';
this.tmpl = $compile(template)($scope)[0].outerHTML;
this.tmplInt = $interpolate(template)($scope);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyController as MC">
<p><b>using $compile along with outerHTML </b>{{MC.tmpl}}</p>
<p><b>using $interpolate </b>{{MC.tmplInt}}</p>
</div>
</div>

Related

Bind Json Data to HTML TABLE

i am new in angular programming,
i want to bind json data that i get from webservice to the html table,
here is my code :
<!DOCTYPE html>
<html>
<head>
<title>LIST OF USER Sample</title>
<script src="../Scripts/angular.min.js"></script>
<script src="../Scripts/module.js"></script>
<script>
function PeopleCtrl($scope, $http) {
$scope.people = [];
$scope.loadPeople = function () {
var httpRequest = $http
({
method: 'GET',
url: 'http://10.17.44.236:9090/MobileBootcamp.svc/getalluseravailability'
})
.success(function (data, status) {
debugger;
$scope.people = data;
});
};
$scope.loadPeople();
}
</script>
</head>
<body>
<div ng-app="app">
<div ng-controller="PeopleCtrl" ng-init="loadPeople()">
<table>
<tr>
<th>Id</th>
<th>Availibility</th>
</tr>
<tr ng-repeat="x in people.Datalist[0]">
<td>{{x.UserID}}</td>
<td>{{x.Availability}}</td>
</tr>
<tr>
<td>{{people.DataList[0].UserID}}</td>
<td>{{people.DataList[0].Availability}}</td>
</tr>
<tr>
<td>{{people.DataList[1].UserID}}</td>
<td>{{people.DataList[1].Availability}}</td>
</tr>
</table>
</div>
</div>
<script src="cordova.js"></script>
<script src="js/platformOverrides.js"></script>
<script src="js/index.js"></script>
</body>
</html>
and this is the json from the web service
{"Status":true,"Message":"","Data":null,"DataList":[{"ChangeBy":"Admin","ChangeDate":"\/Date(1439437580137+0700)\/","ChangeNo":2,"CreateBy":"Admin","CreateDate":"\/Date(1439437580137+0700)\/","Availability":true,"LastCheckIn":"\/Date(1439437645420+0700)\/","UserID":"Admin"},{"ChangeBy":"ITK_ABD","ChangeDate":"\/Date(1439398800000+0700)\/","ChangeNo":1,"CreateBy":"ITK_ABD","CreateDate":"\/Date(1439398800000+0700)\/","Availability":false,"LastCheckIn":"\/Date(1439398800000+0700)\/","UserID":"ITK_ABD"}]}
i already try the "ng-repeat" but it didnt work,
the data is like Data --> DataList--> [0] --> userid,availability,etc...
thx in advance
You don't need the [0]. Your ng-repeat is here to get all elements of the list. You just have to give your list, not the index and angular will do the job.
<tr ng-repeat="x in people.DataList">
Do as following -
<tr ng-repeat="x in people.Datalist">
<td>{{x.UserID}}</td>
<td>{{x.Availability}}</td>
</tr>
as you have array of objects in Datalist, you should iterate DataList instead of DataList[0]
No need for the [0]. we don't want to loop through your first object, So just people.DataList will do the job. It will loop through all objects inside that array .
<tr ng-repeat="x in people.DataList">
<td>{{x.UserID}}</td>
<td>{{x.Availability}}</td>
</tr>
You are trying to repeat object here:
<tr ng-repeat="x in people.Datalist[0]">
You can repeat only on Array data type. So you must do this like that:
<tr ng-repeat="x in people.Datalist">

AngularJS: modify value within ng-repeat

I have a simple table in Angular:
<table>
<tr ng-repeat="row in $data">
<td>{{row.name}}</td>
<td>{{row.surname}}</td>
</tr>
</table>
that would render something like this:
<table>
<tr>
<td>Johnathan</td>
<td>Smith</td>
</tr>
<tr>
<td>Jane</td>
<td>Doe</td>
</tr>
</table>
but I have a dynamic search function that reloads the table and I need to highlight the search string in results like so (the search word is "John"):
<table>
<tr>
<td><span class="red">John</span>athan</td>
<td>Smith</td>
</tr>
</table>
now I hoped that something like this would work:
<table>
<tr ng-repeat="row in $data">
<td>{{myFunction(row.name)}}</td>
<td>{{row.surname}}</td>
</tr>
</table>
but it doesn't. Any way to make this work?
UPDATE: Solved, solution proposed by #loan works in this case.
As you'll see in the example below, you can do something similar to this.
Example
In your existing loop you can add the custom filter as follows:
<body ng-controller="TestController">
<h1>Hello Plunker!</h1>
<input type="text" ng-model="query" />
<ul>
<li ng-repeat="item in data | filter:query">
<!-- use the custom filter to highlight your queried data -->
<span ng-bind-html="item.name | highlight:query"></span>
</li>
</ul>
</body>
In your JavaScript file you can create the custom filter:
(function() {
'use strict';
angular.module("app", []);
//to produce trusted html you should inject the $sce service
angular.module("app").filter('highlight', ['$sce', function($sce) {
function escapeRegexp(queryToEscape) {
return queryToEscape.replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
}
return function(matchItem, query) {
return $sce.trustAsHtml(query ? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem);
};
}]);
angular.module("app")
.controller('TestController', ['$scope',
function($scope) {
$scope.query = ""; //your scope variable that holds the query
//the dummy data source
$scope.data = [{
name: "foo"
},{
name: "bar"
},
{
name: "foo bar"
}];
}
]);
})();
if you want you can replace the html in the filter with your values:
<strong>$&</strong>
to
<span class="red">$&</span>
use ng-class, so the html for your td becomes
<td ng-class = "{red: row.name == searchStr}">{{row.name}}</td>
There are other formats for ng-class and my html may be dodgy I use haml mostly but check the docs on ng-class
You can use angular-ui's highlight module. You can simply use it like this:
DEMO
HTML
<div>
<input type="text" ng-model="searchText" placeholder="Enter search text" />
</div>
<input type="checkbox" ng-model="caseSensitive" /> Case Sensitive?
<table>
<tbody>
<tr ng-repeat="row in $data">
<td ng-bind-html="row.name | highlight:searchText:caseSensitive"></td>
<td>{{row.surname}}</td>
</tr>
</tbody>
</table>
You can download it via bower, instructions are provided in their github page.
Note: Add angular's ngSanitize to avoid an $sce unsafe error.

ng-repeat not working in angular

I am trying to pass a php Laravel array of objects with the name $event to my javascript part of the app and I am having issues with looping through the results later on.
Basically what I am doing is this
$events = Event::orderBy('id', 'DESC')->orderBy('resolved', 'desc')->get(); //get events
return View::make('events.index', compact('events')); //pass events to view
And then this is my view
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
var myevents = JSON.parse('<?php echo json_encode($events) ?>');
</script>
<div class="col-sm-12" ng-app="myApp2" ng-controller="checkboxController">
<table class="table" id="keywords" cellspacing="0" cellpadding="0">
<tr ng-repeat="event in myevents" >
<td> {{event.category}}</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</div>
</table>
</div>
</div>
<script src="http://dsproject.dev:8000/js/jquery-1.11.1.min.js"></script>
<script src="http://dsproject.dev:8000/js/bootstrap.min.js"></script>
<script src="http://dsproject.dev:8000/js/checkboxes.js"></script>
</body>
</html>
This is my controller
var myApp2 = angular.module('myApp2',[]);
myApp2.controller('checkboxController', ['$scope', function($scope) {
//var events = [];
// $scope.some = 'hehehhehehe';
//events.($scope.event);
$scope.myevents = myevents;
console.log($scope.myevents);
/*$scope.toggle = function(id) {
alert(id);
};*/
}]);
The output I get is just {{event.category}} with no value at all. When I do console.log(myevents) or console.log($scope.myevents) in my controller I get the array of objects displayed in the console like this
What am I doing wrong and how would I fix this?
The {{ curlies are being parsed by laravel, you have to change interpolation in angular.
myApp2.config(function($interpolateProvider){
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
});
and then use {[{ and }]} for the angular part of variables.

angular.js: $sanitize fails on $injector:modulerr using exact code example from angular site

UPDATE:
steps to reproduce:
visit this link :http://docs.angularjs.org/api/ngSanitize.$sanitize
click on 'EDIT' button top right of code sample.
select jsfiddle or plnkr
expected result: will see the html output under the 'rendered' heading
I am trying to implement html binding.
Curiously, I can't get a working example using the exact code from this example:
http://docs.angularjs.org/api/ngSanitize.$sanitize
It works on angular site, but not elsewhere.
I have tried using the edit link to plunk and jsfiddle, with no results.
Running locally I get this error in console:
here is what I get in console:
Uncaught Error: [$injector:modulerr]
HTML:
<!doctype html>
<html ng-app="ngSanitize">
<head>
<script src="http://code.angularjs.org/1.2.10/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-controller="Ctrl">
Snippet: <textarea ng-model="snippet" cols="60" rows="3"></textarea>
<table>
<tr>
<td>Directive</td>
<td>How</td>
<td>Source</td>
<td>Rendered</td>
</tr>
<tr id="bind-html-with-sanitize">
<td>ng-bind-html</td>
<td>Automatically uses $sanitize</td>
<td><pre><div ng-bind-html="snippet"><br/></div></pre></td>
<td><div ng-bind-html="snippet"></div></td>
</tr>
<tr id="bind-html-with-trust">
<td>ng-bind-html</td>
<td>Bypass $sanitize by explicitly trusting the dangerous value</td>
<td>
<pre><div ng-bind-html="deliberatelyTrustDangerousSnippet()">
t;/div></pre>
</td>
<td><div ng-bind-html="deliberatelyTrustDangerousSnippet()"></div></td>
</tr>
<tr id="bind-default">
<td>ng-bind</td>
<td>Automatically escapes</td>
<td><pre><div ng-bind="snippet"><br/></div></pre></td>
<td><div ng-bind="snippet"></div></td>
</tr>
</table>
</div>
</body>
</html>
JS:
function Ctrl($scope, $sce) {
$scope.snippet =
'<p style="color:blue">an html\n' +
'<em onmouseover="this.textContent=\'PWN3D!\'">click here</em>\n' +
'snippet</p>';
$scope.deliberatelyTrustDangerousSnippet = function() {
return $sce.trustAsHtml($scope.snippet);
};
}
There error was self explanatory, you didn't include the angualar.sanitize.js script in the fiddle or plunkr.
I added the below script tag below
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-sanitize.js"></script>
FIDDLE

Angular ng-repeat with input

I have a view like this:
<table class="table">
<tr data-ng-repeat="exercise in exercises x">
<td>
<input type="number" data-ng-model="?????????" />
</td>
<td>
{{exercise.Name}}
</td>
</tr>
</table>
I'm wondering what should I put as data-ng-model so I can use two-way data binding i.e., the input's value, in my controller?
I've tried data-ng-model="{{exercise.Name}}" but that resulted in errors.
Also, how can I reference certain input in the controller? Can I do something like this: $scope.InputOne = ...
Use data-ng-model="exercise.Name" without the {{}} brackets.
I suggest you start at the angular tutorial.
for two-way-bind use ng-model, and one-way-bind use ng-bind or {{}} brackets.
this example demonstrates to use the two ways and how to get information of the object.
ps: the controller should not "see" the view directly.
<body data-ng-app="app">
<div data-ng-controller="TestCtrl">
<table>
<tbody>
<tr data-ng-repeat="exercise in exercises">
<td>
<input type="number" data-ng-model="exercise.Name" />
</td>
<td data-ng-bind="exercise.Name"></td>
<td><button data-ng-click="getInformation($index)">Get information</button></td>
</tr>
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
var app = angular.module('app', []);
app.controller('TestCtrl', function($scope) {
$scope.exercises = [{Name:1},
{Name:2},
{Name:3},
{Name:4}
];
$scope.getInformation = function(index) {
alert($scope.exercises[index].Name);
}
});

Categories

Resources