Angularjs with ng-repeat to print data separate by , - angularjs

I have data in json format, which I would like to display the item on the different data cell based on its first element. If more than one element in the cell, multiple item should be shown separable by "," or .
For example, if my json is:
data = {{"Mon","012"},{"Tue","123"},{"Mon","112"},{"Mon","032"},...}
<table>
<tr>
<td id="Mon"> 012 , 112 , 032 </td>
<td> id="TUe"> 123 </td>
</tr>
</table>
or
<pre>
<table>
<tr>
<td id="Mon"> <div>012</div> <div> 112 </div> <div>032</div> </td>
<td id="TUe"> <div>123</div> </td>
</tr>
</table>
</pre>
I was investigating the doc for ng-repeat with $odd and $index etc., but could not find the right way to get my result.

Your JSON is invalid, so I reformated it a bit to answer the format question.
CSS should do the formatting. You can define a delimiter if there are multiple <span> elements.
td span+span:before {
content: ", ";
}
angular.module('app', [])
.run(function($rootScope) {
$rootScope.dataOrdered = [{
key: "Mon",
values: ["012", "112", "032"]
}, {
key: "Tue",
values: ["123"]
}];
});
table,
th,
td {
border: 1px solid black;
padding: 2px;
}
td span+span:before {
content: ", ";
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<table ng-app="app">
<tr>
<td ng-repeat="item in dataOrdered" id="{item.id}}"><span ng-repeat="value in item.values" ng-bind="value"></span>
</td>
</tr>
</table>

Related

How to update the number of columns in an angular table

I want to change the number of columns on modifying a boolean variable.
Check my example (in plnkr):
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('myCtrl', function($scope, $log) {
$scope.debug = {};
$scope.fields = [{
header: "first",
hideField: !$scope.debug.flag
},
{
header: "second"
},
{
header: "third"
},
{
header: "fourth"
},
];
$scope.entries = [{
first: "hello1",
second: "hello2",
third: "hello3",
fourth: "hello4"
}, ]
$scope.myBool = true;
});
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div ng-controller="myCtrl">
<button id="testButton" class='btn btn-danger' ng-click='debug.flag = !debug.flag'><i class="glyphicon glyphicon-hand-right"></i> refreshFields! debug.flag = {{!!debug.flag}}</button>
<hr>
<h2 class="label label-info">table 1 with property.hideField = true</h2>
<table class="table table-hover">
<tr>
<!-- Headers of list-->
<th ng-repeat="property in fields" ng-if="!property.hideField">{{property.header}}
</th>
</tr>
<tbody>
<tr ng-repeat="entry in entries">
<td ng-repeat="property in fields" ng-if="!property.hideField">
{{entry[property.header]}} {{!!debug.flag}}
</td>
</tr>
</tbody>
</table>
<h4 class="label label-info">table 2 with ng-if => property.hideField = false</h4>
<table class="table table-hover">
<tr>
<!-- Headers of list-->
<th ng-repeat="property in fields" ng-if="property.hideField">{{property.header}}
</th>
</tr>
<tbody>
<tr ng-repeat="entry in entries">
<td ng-repeat="property in fields" ng-if="property.hideField">
{{entry[property.header]}} {{!!debug.flag}}
</td>
</tr>
</tbody>
</table>
<h2 class="label label-info">table 3 without ng-if</h2>
<table class="table table-hover">
<tr>
<!-- Headers of list-->
<th ng-repeat="property in fields">{{property.header}}
</th>
</tr>
<tbody>
<tr ng-repeat="entry in entries">
<td ng-repeat="property in fields">
{{entry[property.header]}} {{!!debug.flag}}
</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
How to reproduce it:
Click on the red button and the flag will toggle from false to true.
Expected behavior:
Table 1 starts with 3 columns. It should show four after clicking.
Table 2 starts with 1 column. It should show 0 columns after clicking.
Table 3 is just a control table with all the data.
Your heading would become visible if you modified the value of its hideField property. But you're not doing that. You're modifying the value of $scope.debug.flag.
The fact that hideField was initialized with the value of $scope.debug.flag won't magically change hideField every time you change $scope.debug.flag.
Just like if you do
var a = 1;
var b = a;
a = 42;
The value of b will still be 1. Not 42.
Changing the value of $scope.debug.flag won't change the value of hideField. Because, it has already been initialized at the time of controller load. The workaround you can apply here is bind that hideField to a method and evaluate that in your ng-if. Sample below.
JS:
$scope.fields = [{
header: "first",
hideField: function() {
return !$scope.debug.flag;
}
}, {
header: "second"
}, {
header: "third"
}, {
header: "fourth"
}, ];
HTML:
<h2 class="label label-info">table 1 with property.hideField = true</h2>
<table class="table table-hover">
<tr>
<!-- Headers of list-->
<th ng-repeat="property in fields" ng-if="!property.hideField()">{{property.header}}
</th>
</tr>
<tbody>
<tr ng-repeat="entry in entries">
<td ng-repeat="property in fields" ng-if="!property.hideField()">
{{entry[property.header]}} {{!!debug.flag}}
</td>
</tr>
</tbody>
</table>
This is not a clean solution though. But, still will solve your problem.

angularjs date time sorting not working properly on table

I have the sample data set (below) from my backend and I am passing it into an angularjs table. When I sort the date column, it is taking the formatted (by using date filter) date string for sorting instead of taking the real long date to sort.
JSON Data
{
"_id": ObjectId("57e21d452679a426808caa09"),
"name": "John",
"createdOn": NumberLong(1474436421360)
}
HTML
<table>
<thead>
<tr>
<th>Name</th>
<th>Created Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users">
<td>{{ user.name }}</td>
<td>{{ user.createdOn | date : 'dd/MM/yy HH:mm' : timezone }}</td>
</tr>
</tbody>
</table>
You need to implement sorting
Check the below example.
angular
.module('demo', [])
.controller('DefaultController', DefaultController);
function DefaultController() {
var vm = this;
vm.users = [
{ id: 1, name: 'John', date: 1474436481360 },
{ id: 2, name: 'Dale', date: 1444936421360 },
{ id: 3, name: 'Torres', date: 1464445481360 }
];
}
table {
border-collapse: collapse;
}
th {
cursor: pointer;
background-color: #4CAF50;
color: white;
}
th:hover {
text-decoration: underline;
}
th, td {
padding: 15px;
text-align: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo">
<div ng-controller="DefaultController as ctrl">
<table border="1">
<thead>
<tr>
<th ng-click="ctrl.sortBy = 'name'; ctrl.sortOrder = !ctrl.sortOrder">Name</th>
<th ng-click="ctrl.sortBy = 'date'; ctrl.sortOrder = !ctrl.sortOrder">Created On</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in ctrl.users | orderBy: ctrl.sortBy : ctrl.sortOrder">
<td ng-bind="user.name"></td>
<td ng-bind="user.date | date : 'dd/MM/yy HH:mm'"></td>
</tr>
</tbody>
</table>
</div>
</div>

how to have a popup child tr for every tr element on ng-click

I have a table which using ng-repeat
<table>
<thead>
<tr>
<th>Assets</th>
<th>Location</th>
<th>Size</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr id="parent" data-ng-repeat="assets in vm.employees"
data-toggle="collapse" id="row{{$index}}" data-target=".row{{$index}}">
<td class="name">
<i class="mdi mdi-plus s16" ng-click="childRowToggle($event)"></i>
{{assets.name}}
<span class="secondary-text">{{assets.code}}</span>
</td>
<td>{{assets.location}}</td>
<td>{{assets.size}}</td>
<td>{{assets.price}}</td>
</tr>
<tr id="child" data-ng-repeat="assets in vm.employees" class="collapse row{{$index}}">
<div>i' have to be shown under every tr element when clicks
</tr>
</tbody>
</table>
If i click on the i element which is in parent tr, i want the child tr popup under that tr element. i already tried something like this
$scope.childRowToggle = function($event){
$('#childrow').remove();
var $this = $($event.target);
var $obj =$this.parent().parent();
console.log($obj.attr('class'));
$("<tr id='childrow'><td colspan='5'>Dummy Data</td></tr>").insertAfter($obj);
}
Here is a working version: https://jsfiddle.net/Shitsu/c6bj75mp/.
angular.module('myApp', []).controller('Ctrl',
function($scope) {
$scope.employees = [{
name: "lala",
location: "loc",
size: 10,
price: 44
}, {
name: "lala",
location: "loc",
size: 10,
price: 44
}, {
name: "lala",
location: "loc",
size: 10,
price: 44
}, {
name: "lala",
location: "loc",
size: 10,
price: 44
}, {
name: "lala",
location: "loc",
size: 10,
price: 44
}];
});
.noPadding {
padding: 0 !important;
}
td p {
padding: 10px;
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="Ctrl">
<table class="table table-condensed" style="border-collapse:collapse;">
<thead>
<tr>
<th>Assets</th>
<th>Location</th>
<th>Size</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="assets in employees track by $index" data-toggle="collapse" data-target="#row-{{$index}}" class="accordion-toggle">
<td class="name">
<i class="mdi mdi-plus s16">{{assets.name}}</i>
<span class="secondary-text">{{assets.code}}</span>
</td>
<td>{{assets.location}}</td>
<td>{{assets.size}}</td>
<td>{{assets.price}}</td>
</tr>
<tr ng-repeat-end>
<td colspan="5" class="noPadding">
<div class="accordian-body collapse collapsible" id="row-{{$index}}">
<p>
Collapsed datas
</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
Have you thought of using tooltips ? UI-Bootstrap has really nice tooltips which would do exactly what you want. You can choose if you trigger the tooltip on hover or on click. Have a look at this fiddle.
HTML:
<!doctype html>
<html ng-app="App">
<body ng-controller="Ctrl">
<table>
<tr ng-repeat="a in assets">
<td tooltip-html-unsafe="{{a}}<br />blabla" tooltip-placement="bottom">{{a}}</td>
</tr>
</table>
</body>
</html>
JS:
angular.module('App', ['ui.bootstrap'])
.controller('Ctrl', function($scope) {
$scope.assets = ['a', 'b', 'c'];
});

How to truncate text without affect filtering

In this fiddle the table can be filtered :
http://jsfiddle.net/eBcaB/232/
I have added a truncate function which will truncate text :
$scope.truncate = function(item){
return item.substring(0,2);
}
But I'm unsure how to integrate this function to truncate items and not affect the filtering of results. How to truncate text and also maintain filtering functionality, so the any text that is removed as part of truncation can still be filtered ?
fiddle src :
<div ng-app>
<div ng-controller="ShoppingCartCtrl">
<br />
<div><strong>Filter Results</strong></div>
<table>
<tr>
<td>By Any: </td>
<td><input type="text" ng-model="search.$" /></td>
</tr>
</table>
<br />
<table border="1">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in items | orderBy:mySortFunction | filter:search">
<td>{{item.Name}}</td>
<td>{{item.Price | currency}}</td>
<td>{{item.Quantity}}</td>
</tr>
</tbody>
</table>
<br />
</div>
</div>
.bold { font-weight:bold; }
table td{
padding: 10px;
}
table th{
font-weight: bold;
text-align: center;
}
function ShoppingCartCtrl($scope) {
$scope.items = [
{Name: "Soap", Price: "25", Quantity: "10"},
{Name: "Shaving cream", Price: "50", Quantity: "15"},
{Name: "Shampoo", Price: "100", Quantity: "5"}
];
$scope.truncate = function(item){
return item.substring(0,2);
}
}

ng-repeat is not working for the json value

I have a code like this:
<tr ng-repeat="tagJson in tagList">
<div ng-repeat="(key, value) in tagJson">
<td width="48%" ng-class-odd="'evn'" ng-class-even="'odd'">
{{key}}
</td>
<td width="48%" ng-class-odd="'evn'" ng-class-even="'odd'">
{{value}}
</td>
</div>
</tr>
where tagList is :
[{a:1},{a:1}]
But the key and value are empty! Not sure why thats the case. If i try to print tagJson in the html like:
{{tagJson}}
it does print:
{a:1}
{a:1}
but key and value doesnt work!
Where I'm making the mistakes?
See here:
http://jsfiddle.net/Vwsej/126/
The actual reason why you don't see anything is, as akonsu posted, because you're producing invalid html.
To keep the values in seperate table cells, you can use ng-repeat-start/end, e.g.:
var MainCtrl = function () {
this.tagList = [{a:1}, {b:2}];
};
angular
.module('app', [])
.controller('Main', MainCtrl)
;
table {
border-collapse: collapse;
}
td {
border: 1px solid #ccc;
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.5/angular.min.js"></script>
<div data-ng-app="app" data-ng-controller="Main as main">
<table>
<tr ng-repeat="tagJson in main.tagList">
<td ng-repeat-start="(key, value) in tagJson" width="48%" ng-class-odd="'evn'" ng-class-even="'odd'">
{{key}}
</td>
<td ng-repeat-end width="48%" ng-class-odd="'evn'" ng-class-even="'odd'">
{{value}}
</td>
</tr>
</table>
</div>
You do not see anything because this is invalid markup for the table. You have div elements inside.
maybe this?
<div ng-controller="MyCtrl">
<table>
<tr ng-repeat="tagJson in tagList">
<td ng-repeat="(key, value) in tagJson">
{{key}}={{value}}
</td>
</tr>
</table>
</div>
but to emit the markup that you wanted, I think you need a custom directive for that.

Resources