How to append scope.value as HTML? - javascript

I am currently writing an AngularJS application, and I would like to append or make the value under $scope as an HTML tag value instead of a regular value.
HTML:
<div gridster="gridsterOptions">
<ul>
<li gridster-item="widget" ng-repeat="widget in dashboard.widgets" class="main-dashboard-container">
<div class="box" ng-controller="CustomWidgetCtrl">
<div class="box-header main-dashboard-header">
<h4>{{ widget.name }}</h4>
<div class="box-header-btns pull-right">
<a title="settings" ng-click="openSettings(widget)"><i class="glyphicon glyphicon-cog"></i></a>
<a title="Remove widget" ng-click="remove(widget)"><i class="glyphicon glyphicon-trash"></i></a>
</div>
</div>
<div class="box-content main-dashboard-content">{{ widget.content }}</div>
</div>
</li>
</ul>
</div>
AngularJS Code:
$scope.dashboards = {
'1': {
id: '1',
name: 'Home',
widgets: [{
col: 0,
row: 0,
sizeY: 1,
sizeX: 1,
name: "URL Filter",
content:'<div class="table-responsive " ng-controller="URLFilterCategoriesController as viewAll"><table class="table table-hover"><thead><tr><td>Categories</td><td>Hits</td></tr></thead><tbody><tr ng-repeat="urlfil in viewAll.urlfiltercat"><td>{{urlfil.category}}</td><td>{{urlfil.hit}}</td></tr></tbody></table></div>'
}, {
col: 2,
row: 1,
sizeY: 1,
sizeX: 1,
name: "Widget 2"
}]
},
As you can see under the AngularJS code, I've added series of html codes and that I would like it to be appended/added as HTML inside my HTML codes. Thanks!

Use the ng-bind-html directive
You might want to look at these two links:
https://docs.angularjs.org/api/ng/directive/ngBindHtml
With ng-bind-html-unsafe removed, how do I inject HTML?

Related

Optimize the number of ng-repeat |angularJS

I want to separate everything in my code according to predefined levels given , from level 1 to level 6 , now my JSON reads
$scope.myJson=[{
id: 1,
level: 1,
name: "any name"
},
{
id: 2,
level: 2,
name: "any name"
},
{
id: 3,
level: 2,
name: "any name"
}....]
now in my HTML I have written something like
<div>level 1
<div ng-repeat="prod in myJson" ng-if="prod.level==1">{{prod.name}}
</div>
</div>
<div>level 2
<div ng-repeat="prod in myJson" ng-if="prod.level==2">{{prod.name}}
</div>
</div>
and so on , I want to use only one ng-repeat to filter all the results in HTML on basis of the levels , as the results number in thousands the app is taking too much of time to respond
You could try a switch case in your ng repeat, for example :
<div ng-repeat="prod in myJson">
<div ng-switch-on = "prod.level">
<div ng-switch-when="1">
Level 1 {{prod.name}}
</div>
<div ng-switch-when="2">
Level 2 {{prod.name}}
</div>
<div ng-switch-default>
Another level {{prod.name}}
</div>
</div>
</div>
So you will only do one run over your data.
To make it more generic, groupBy will solve this for you.
Demo:
angular.module('app', ['angular.filter'])
.controller('myCtrl', function($scope) {
$scope.myJson = [{
id: 1,
level: 1,
name: "any name level1"
}, {
id: 2,
level: 2,
name: "any name level2"
}, {
id: 3,
level: 2,
name: "any name level2"
}, {
id: 4,
level: 2,
name: "any name level2"
}, {
id: 5,
level: 1,
name: "any name level1"
}, {
id: 6,
level: 3,
name: "any name level3"
}]
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.4.7/angular-filter.js"></script>
</head>
<body>
<div ng-controller="myCtrl">
<ul ng-repeat="(key, value) in myJson | groupBy: 'level'">
Level- {{ key }}
<li ng-repeat="item in value">
{{ item.name }}
</li>
</ul>
</div>
</body>
</html>

ui-grid is blank when opening a bootstrap accordion a few seconds after the page loads?

So I'm currently attempting to dynamically create accordions which expand to a ui-grid containing some data. The issue is that if I do not expand the accordions within a few seconds of the page loading the ui-grid is blank. The outline of where the table should be exists but there is no data being displayed. I say being displayed because the data itself is in the html. It seems like its hidden by the accordion? When I resize the browser window the data appears though. Sorry if this is not detailed enough or I missed obvious debugging steps, I'm new to js/angular and to html. Below is my HTML code
<div ng-controller="TestController as test">
<script type="text/ng-template" id="group-template.html">
<div class="panel-heading">
<h4 class="panel-title" style="color:#fa39c3">
<a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading">
<span uib-accordion-header ng-class="{'text-muted': isDisabled}">
TEST
</span>
</a>
</h4>
</div>
<div class="panel-collapse collapse" uib-collapse="!isOpen">
<div class="panel-body" style="text-align: right" ng-transclude></div>
</div>
</script>
<uib-accordion close-others="oneAtATime">
<div ng-repeat="model in myData" track by $index>
<div uib-accordion-group class="panel-default" is-open="isOpen">
<uib-accordion-heading>
Test Model {{$index}} <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': isOpen, 'glyphicon-chevron-right': !isOpen}"></i>
</uib-accordion-heading>
<div id="grid[$index]" ui-grid="gridOptions[$index]" ui-grid-edit class="grid" style="clear:both"></div>
<br />
<strong>Last Cell Edited:</strong>{{msg[$index]}}<br />
<button>Commit Changes</button>
</div>
</div>
</uib-accordion>
and my angular
(function () {
var app = angular
.module('testApp', ['ui.grid', 'ui.grid.edit', 'ui.bootstrap', 'ngAnimate'])
.controller('TestController', TestController);
TestController.$inject = ['$scope', 'uiGridConstants'];
function TestController ($scope, uiGridConstants) {
$scope.oneAtATime = false;
$scope.myData = myData;
$scope.msg = [];
$scope.gridOptions = [];
$scope.getGridOptions = function (index) {
$scope.gridOptions[index] ={
showColumnFooter: true,
columnDefs: [
{ field: 'ticker', enableCellEdit: false, width: '33%' },
{ field: 'current_w', aggregationType: uiGridConstants.aggregationTypes.sum, enableCellEdit: false, width: '33%' },
{ field: 'new_w', aggregationType: uiGridConstants.aggregationTypes.sum, width: '33%' }
],
data: myData[index],
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
gridApi.edit.on.afterCellEdit($scope, function (rowEntity, colDef, newValue, oldValue) {
$scope.msg[index] = 'Edited Ticker:' + rowEntity.ticker + ' Column:' + colDef.name + ' newValue:' + newValue + ' oldValue:' + oldValue;
$scope.$apply();
})
}
}
};
for (i = 0; i < Object.keys($scope.myData).length; i++) {
$scope.getGridOptions(i);
console.log($scope.gridOptions[i]);
};
console.log($scope.gridOptions[1]);
};
var myData = [
[{ ticker: 'TICKER', current_w: 5, new_w: 4, },
{ ticker: 'TICKER 2', current_w: 3, new_w: 2, },
{ ticker: 'TICKER 3', current_w: 7, new_w: 0, }],
[{ ticker: 'TICKER', current_w: 5, new_w: 4, },
{ ticker: 'TICKER 2', current_w: 3, new_w: 2, },
{ ticker: 'TICKER 3', current_w: 7, new_w: 5, }]
];
})();
I would take a stab at this and say that you may want to add a ng-if="isOpen" to the ui-grid. So something like below should fix your problem.
<div id="grid[$index]" ui-grid="gridOptions[$index]" ui-grid-edit class="grid" style="clear:both" ng-if="isOpen"></div>
I was having issues with my grid displaying as well, and ensuring that the grid only appears when it is absolutely ready fixed the problem. The ui-grid documentation goes over this concept of a hidden grid at http://ui-grid.info/docs/#/tutorial/108_hidden_grids. They also have a plnkr that you can follow at http://plnkr.co/edit/LtpFnDUTofuxitb4Vh9x?p=preview. I hope this helps!

Knockout.js {{each}} not listing items in javascript template

I've created a simple app that should iist each item from a model in a list, created using a javascrit template.
Fiddle
Html:
<div id="tagsList" class="box">
<div class="box-head">
<h2 class="left">Tags</h2>
</div>
<div class="box-content">
<input type="text" placeholder="Add New Tag" />
<button>+ Add</button>
<div data-bind="template: 'tagsTempl'"></div>
</div>
</div>
<script id="tagsTempl" type="text/html">
<ul>
{{each tags}}
<li class="tagItem">
<span>${Name}</span>
<div>
Edit
Delete
</div>
</li>
{{/each}}
</ul>
</script>
Javascript:
$(function () {
//$("#tagDialog").hide();
var data = [
{ Id: 1, Name: "Ball Handling" },
{ Id: 2, Name: "Passing" },
{ Id: 3, Name: "Shooting" },
{ Id: 4, Name: "Rebounding" },
{ Id: 5, Name: "Transition" },
{ Id: 6, Name: "Defense" },
{ Id: 7, Name: "Team Offense" },
{ Id: 8, Name: "Team Defense" }
];
var viewModel = {
tags: ko.observableArray(data),
tagToAdd: ko.observable(""),
addTag: function() {
this.tags.push({ Name: this.tagToAdd() });
}
}
ko.applyBindings(viewModel)
});
Output of list:
{{each tags}}
${Name}
Edit Delete
{{/each}}
The scripts file is accessible through viewing source. I'm not sure where my error is. Any help?
I updated your fiddle. Now it is working like you want it to: The list of tags is being rendered using the knockout standard method as described in the docs.
HTML
<ul data-bind="template: {name: 'tagsTempl', foreach: tags}"></ul>
Template
<script id="tagsTempl" type="text/html">
<li class="tagItem">
<span data-bind="text: Name"></span>
<div>
Edit
Delete
</div>
</li>
</script>
Also I connected the viewmodel to the view.
For example:
<button data-bind="click: addTag">+ Add</button>
You simply forgot most of it. I suggest you follow the interactive tutorials on how to do this.

ng-repeat on bootstrap tab-content/tab-pane

I am having trouble getting my tab content to appear properly on page load. What I have is a factory of Objects called apiList, I then use two ng-repeats, one which hits each object in the apiList, then the next one which iterates through that object and puts all of its data on the page. I use #tab{{$index}} to keep my data-toggles aligned between the buttons and tab-panes.
The problem seems to be with how I use the active attribute on my tab-pane.
I have three known test cases so far.
I can only get information from the first Object by using the condition ng-class="{ 'active': $index == 0}" as in..
<div ng-repeat="(key, data) in apiList[0]" class="tab-pane active" id="tab{{$index}}" ng-class="{ 'active': $index == 0}">
If I remove the conditional from the line then nothing appears
And if I just add active to the pane value (with no condition)
(i.e. <div ng-repeat="(key, data) in apiList[0]" class="tab-pane active" id="tab{{$index}}"> They all appear.
So my problem seems to be with how I need to turn on/off my active for the ng-repeat and I am just getting lost.
Also, clicking on accounts/customers does not update the tabs. They both have the right data-toggle ID's (0 and 1) in respect to the tab-panes so I assume it is part of the active issue. And whenever I click on my tab panes, they do expand just fine.
Here is my Factory, ng-repeat(s), and the code that was my original setup (functional).
Factory
.factory('APIMethodService', [function() {
var Head = "api.verifyvalid";
return {
apis: [
{
accounts: [
{
parameters : [
{
name : "Accounts",
version : "1.0"
}
],
uri: Head + "/v1/accounts/account_number",
methods : [
{
name: "Account Number",
desc: "Returns the account number."
}, {
name: "Account Money",
desc: "Returns the monetary amount within the account."
}
]
},
{
parameters : [
{
name : "Accounts",
version : "2.0"
}
],
uri: Head + "/v2/accounts/account_number",
methods: [
{
name: "Account Number",
desc: "Returns the account number."
}, {
name: "Account Money",
desc: "Returns the monetary amount within the account."
}, {
name: "Account Token",
desc: "Returns the account's token."
}
]
}
],
customers:[
{
parameters : [
{
name : "Customers",
version : "1.0"
}
],
uri: Head + "/v1/customers/customer_number",
methods : [
{
name: "Customer Name",
desc: "Returns the customer's name."
}, {
name: "Customer ID",
desc: "Returns the customer's ID."
}
]
},
{
parameters : [
{
name : "Customers",
version : "2.0"
}
],
uri : Head + "/v2/customers/customer_number",
methods: [
{
name: "Customer Name",
desc: "Returns the customer's name."
}, {
name: "Customer ID",
desc: "Returns the customer's ID."
}, {
name: "Customer Email",
desc: "Returns the customer's email."
}
]
}
]
}
]
};
ng-repeat (just the right-hand tabs)
<div class="col-md-9">
<div class="tab-content">
<div ng-repeat="(key, data) in apiList[0]" class="tab-pane active" id="tab{{$index}}">
<div ng-repeat="api in apiList[0][key]">
<div class="panel panel-info" id="panel{{$index}}">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-target="#collapse{{key}}{{$index}}" class="collapsed">
{{api.uri}}<i class="newTab" ng-click="apiTab(api)">(Open in new tab)</i>
</a>
</h4>
</div>
<div id="collapse{{key}}{{$index}}" class="panel-collapse collapse">
<div class="panel-body">
<table class="table">
<tr ng-repeat="method in api.methods">
<td>{{method.name}}</td>
<td>{{method.desc}}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The following code is what I originally had, before trying to crunch it down more
<div class="col-md-9" style="display:none">
<div class="tab-content">
<!-- Accounts -->
<div class="tab-pane active" id="tab0">
<div ng-repeat="api in apiList[0].accounts">
<div class="panel panel-info" id="panel0">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-target="#collapseAccountsV{{$index}}" class="collapsed">
{{api.uri}}
</a>
<i class="newTab" ng-click="apiTab(api)">(Open in new tab)</i>
</h4>
</div>
<div id="collapseAccountsV{{$index}}" class="panel-collapse collapse">
<div class="panel-body">
<table class="table">
<tr ng-repeat="method in api.methods">
<td>{{method.name}}</td>
<td>{{method.desc}}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Customers -->
<div class="tab-pane" id="tab1">
<div ng-repeat="api in apiList[0].customers">
<div class="panel panel-info" id="panel1">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-target="#collapseCustomersV{{$index}}" class="collapsed">
{{api.uri}}<i class="newTab" ng-click="apiTab(api)">(Open in new tab)</i>
</a>
</h4>
</div>
<div id="collapseCustomersV{{$index}}" class="panel-collapse collapse">
<div class="panel-body">
<table class="table">
<tr ng-repeat="method in api.methods">
<td>{{method.name}}</td>
<td>{{method.desc}}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Other -->
<div class="tab-pane fade" id="tab3">
<!-- TBA -->
</div>
</div>
</div>
Noob mistake, everything works fine! I was using my old code as the base outline on the same page and had set that old code to style="display:hidden" but this still meant that the ID's were apart of the DOM, hence why I couldn't change my tab's properly (duplicate/conflicting ID's).

How to render JSON data in HTML page Using Angular JS

I have a Json data like this
Object {Science: Array[3], Accounts: Array[3], History: Array[3], Mathematics: Array[3]}
Accounts: Array[3]
0: Object
1: Object
2: Object
length: 3
History: Array[3]
Mathematics: Array[3]
Science: Array[3]
Now to render this data in HTML page like this
<h1> Accounts</h1>
<div> Object </div>
<div> Object </div>
..................
You can use ng-repeat directive with JSON Data like this example:
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<div data-ng-app="" data-ng-init="names=['Jani','Hege','Kai']">
<p>Looping with ng-repeat:</p>
<ul>
<li data-ng-repeat="x in names">
{{ x }}
</li>
</ul>
</div>
Fiddle Demo With Array
And You can even show your nested objects using ng-repeat directive like this:
<ul ng:controller="Cntl">
<li ng:repeat="item in data">
{{item.name}} has children:
<ul>
<li ng:repeat="child in item.children">{{child.name}} has grant-children:
<ul><li ng:repeat="gch in child.children">{{gch.name}}</li></ul>
</li>
</ul>
</li>
</ul>
<script>
function Cntl() {
this.data = [{
name: '1',
children: [{
name: '11',
children: [{
name: '111'}, {
name: '112'}]}, {
name: '12',
children: [{
name: '121'}, {
name: '122'}]}]}, {
name: '2',
children: [{
name: '21'}, {
name: '22'}]
}];
}
</script>
Fiddle Demo With Nested Objets
Got my answer
<div class="panel" ng-repeat="(subject, activities) in Activities">
<h3 class="panel-title followMeBar">{{subject}}</h3>
<div class="panel-body">
<ul class="list-group">
<div class="row list-group-item" ng-repeat="activity in activities">
<div class="col-xs-4">
<img class="scale-notebook-image" src={{activity.fileTypeImg}}>
</div>
<div class="col-xs-8">
<div>{{activity.fileTitle}}</div>
<div>by {{activity.createdBy}}</div>
</div>
</div>
</ul>
</div>
</div>

Categories