Angular JS: table with dynamic number of titles - javascript

I tried to create a table with a dynamic number of titles and sub titles. It should look like this:
Each title has 3 sub titles. But I can not know in advance how much headline I will have.
So in HTML it looks like:
<table class="table table-hover col-xs-12">
<thead>
<tr>
<th rowspan="2">Type ID</th>
<th colspan="3" ng-repeat="val in ctrl.vals">
<div class="val">
<span title="{{val}}">{{val}}</span> <!-- this is title -->
</div>
</th>
</tr>
<tr>
<th class="row-header" ng-repeat="val in ctrl.getNumberColumn() track by $index">{{ $index%3 == 0 ? "subtitle1" : $index%3 == 1 ? "subtitle2" : "subtitle3" }}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="key in ctrl.keys">
<td class="row-key">{{key}}</td>
<td class="row-value" ng-repeat="val in ctrl.getNumberColumn() track by $index">
<div class="list-group" ng-init="data = ctrl.getDataByIndex($index, ctrl.items[key])">
<a class="list-group-item" ng-if="$index%3 == 0">{{data.avg_fps}} </a>
<a class="list-group-item" ng-if="$index%3 == 1">{{data.avg_cpu}} </a>
<a class="list-group-item" ng-if="$index%3 == 2">{{data.session}} </a>
</div>
</td>
</tr>
</tbody>
</table>
I understand that it looks confusing - so I would like to ask - is there an option for more simply constructing such a table?

angular.module('app', []).controller('ctrl', function($scope) {
$scope.titles = [{
title: 'One',
items: ['Sub1_1', 'Sub1_2']
}, {
title: 'Two',
items: ['Sub2_1']
},{
title: 'Three',
items: []
},
{
title: 'Four',
items: ['Sub4_1', 'Sub4_2', 'Sub4_3']
}];
})
table {
border-collapse: collapse;
}
table,
td,
th {
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<div ng-app='app' ng-controller='ctrl'>
<table>
<thead>
<tr>
<th rowspan="2">TypeId</th>
<th ng-repeat='item in titles' colspan='{{item.items.length}}' rowspan='{{item.items.length > 0 ? 1 : 2}}'>
{{item.title}}
</th>
</tr>
<tr>
<th ng-repeat-start='item in titles' ng-if='false'></th>
<th ng-repeat-end ng-repeat='sub in item.items'>{{sub}}</th>
</tr>
</thead>
</table>
</div>

Related

VueJS Accordion Table - Appears outside of the table

I have a table where the data is fetched using ajax. I'm trying to have a table where each row has an associated hidden row and clicking on the row toggles the display of the hidden row. The hidden row contains an accordion.
The problem is that the accordion is getting all messed up and shows at the bottom of the table, rather than showing below the particular row that it was clicked on.
My code is as follows:
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th v-for="column in columns">
<span v-if="column == 'Predictive Price'">
{{column}}
<i class="fa fa-info-circle" v-tooltip="msg"></i>
</span>
<span v-else-if="column == 'Actual Price'">
{{column}}
<i class="fa fa-info-circle" v-tooltip="tooltip.actual_price"></i>
</span>
<span v-else>
{{column}}
</span>
</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="row in model" #click="showRow">
<td>
{{row.id}}
</td>
<td>
{{row.company_customer.customer_name}}
</td>
<td>
<i class="fa fa-map-marker"></i>
<small>
{{row.pickup_addr.address_1}}, {{row.pickup_addr.city}}, {{row.pickup_addr.postcode}}
</small>
</td>
<td>
<i class="fa fa-map-marker"></i>
<small>
{{row.pickup_addr.address_1}}, {{row.pickup_addr.city}}, {{row.pickup_addr.postcode}}
</small>
</td>
<td>
£{{row.predictive_price}}
</td>
<td>
£{{row.actual_price}}
</td>
<td>
n/a
</td>
<tr>
<td colspan="7" v-if="contentVisible">
<div class="accordian-body">
ACCORDION
</div>
</td>
</tr>
</tr>
</tbody>
</table>
<script>
export default {
methods: {
data() {
return {
msg: 'This is just an estimation!',
tooltip: {
actual_price: 'Click on the price to edit it.'
},
contentVisible: false,
}
},
rowRow() {
this.contentVisible = !this.contentVisible;
}
}
}
</script>
Where can I place the accordion div in order for it to display correctly?
EDIT:
Please see fiddle: https://jsfiddle.net/49gptnad/355/
It sounds like you want an accordion associated with every row, so really, you want two rows for each item of your data.
You can accomplish that by moving your v-for to a template tag that wraps both of your rows.
Additionally, you need to control whether content is visible on a row by row basis, so add a contentVisible property to each data item and use it to control whether your second row is visible or not.
console.clear()
var vm = new Vue({
el: '#vue-instance',
data: {
testing: [{
id: 1,
name: "Customer 1",
contentVisible: false
},
{
id: 2,
name: "Customer 1",
contentVisible: false
},
{
id: 3,
name: "Customer 3",
contentVisible: false
},
],
columns: ["id", "name"]
},
mounted() {
console.log(this.testing);
},
methods: {
showRow(data) {
this.contentVisible = !this.contentVisible;
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script>
<div id="vue-instance">
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th v-for="column in columns">
{{column}}
</th>
</tr>
</thead>
<tbody>
<template v-for="row in testing">
<tr #click="row.contentVisible = !row.contentVisible">
<td>{{row.id}}</td>
<td>{{row.name}}</td>
</tr>
<tr v-if="row.contentVisible">
<td :colspan="columns.length" >
<div class="accordian-body">
afasfafs
</div>
</td>
</tr>
</template>
</tbody>
</table>
</div>
Here is your updated fiddle.

How to get the table row values on click of button Angularjs

I would like to know how to get the table row values for the selected row in the below plunkr. On selecting a row using checkbox in table and click on update button, i need row id, row name, row values. Here is the plunkr - https://plnkr.co/edit/9wWxczEH22aG71RN3B0Q?p=preview
html code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<table style="width:100%;overflow: scroll; border: 2px solid #AAA; ">
<thead style="border-bottom: 1px solid #AAA">
<tr>
<th style="width:50%"> <input type='checkbox'/> catalog</th>
<th style="width:25%">currentVersion</th>
<th style="width:25%">new Version</th>
</tr>
</thead>
<tbody style="color: #007db8;">
<tr id='1' name='MT' >
<td style="width:50%">
<input type='checkbox' /> Multiple
</td>
<td style="width:25%">1.2</td>
<td style="width:25%">1.3</td>
</tr>
</tbody>
</table>
<button style="font-size: 11px;" type="button" class="btn btn-primary" >Update</button>
</body>
</html>
You have many alternatives to get the value of each row, here an option using ng-repeat and ng-model
angular.module('test', [])
.controller('test', function ($scope) {
$scope.itemSelecteds = {};
$scope.dummyModel = {};
$scope.items = [{
id: 1,
name: 'mit',
catalog: 'Multiple',
currentVersion: '1.2',
newVersion: '1.3',
}, {
id: 2,
name: 'mit',
catalog: 'Multiple',
currentVersion: '1.2',
newVersion: '1.3',
}, {
id: 3,
name: 'mit',
catalog: 'Multiple',
currentVersion: '1.2',
newVersion: '1.3',
}];
$scope.selectItem = function (item) {
// If checkbox is checked
if ($scope.dummyModel[item.id]) {
$scope.itemSelecteds[item.id] = item;
} else {
delete $scope.itemSelecteds[item.id];
}
}
$scope.update = function () {
console.log($scope.itemSelecteds);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="test" ng-controller="test">
<table style="width:100%;overflow: scroll; border: 2px solid #AAA; ">
<thead style="border-bottom: 1px solid #AAA">
<tr>
<th style="width:50%"> <input type='checkbox'/> catalog</th>
<th style="width:25%">currentVersion</th>
<th style="width:25%">new Version</th>
</tr>
</thead>
<tbody style="color: #007db8;">
<tr ng-repeat="item in items" ng-attr-id="item.id">
<td style="width:50%">
<input type='checkbox' ng-model="dummyModel[item.id]" ng-change="selectItem(item)"/> {{ item.catalog }}
</td>
<td style="width:25%">{{ item.currentVersion }}</td>
<td style="width:25%">{{ item.newVersion }}</td>
</tr>
</tbody>
</table>
<button style="font-size: 11px;" type="button" class="btn btn-primary" ng-click="update()" >Update</button>
</body>
Use the ng-checked event to get on check event but if you want to process both check and unchecked event try ng-click
Here this will give you input element .From which you can use elemnt.parent.parent to get td or tr and their values
function doSomething(element){
var parent=elemnt.parent.parent;
// do something
}

jQuery reset a single table during onchange

I have a table as follows. How to reset the table using jQuery to its original state during on change(with all th,tds). Not to reload the entire page because I have another tables also. I tried with dataTables but it adds search filters and paginations unnecessarily
<table class="table table-bordered table-hover table-sm" id="t01">
<thead style="text-align:center">
<tr>
<th class="col-md-6" style="text-align:center">Dxx</th>
<th class="col-md-2" style="text-align:center">Rxx/Unit</th>
<th class="col-md-2" style="text-align:center">Txxx</th>
<th class="col-md-2" style="text-align:center">Pxxx</th>
</tr>
</thead>
<tbody>
<tr>
<th>Full</th>
<td id="fp" style="text-align:right">0</td>
<td id="fr" style="text-align:center">0</td>
<td>
<div style="float:left">$</div>
<div style="float:right" id="fpT">0.00</div>
</td>
</tr>
<tr>
<th >Fractional</th>
<td id="fr" style="text-align:right">0</td>
<td id="frN" style="text-align:center">0</td>
<td>
<div style="float:left">$</div>
<div id="frT" style="float:right">0.00</div>
</td>
</tr>
<tr>
<th >Premium</th>
<td id="pRate" style="text-align:right">0</td>
<td id="pNos" style="text-align:center">0%</td>
<td>
<div style="float:left">$</div>
<div id="pTotal" style="float:right">0.00</div>
</td>
</tr>
<tr class="active">
<th>Premium Discount</th>
<td style="text-align:right" id="premium-discount-rate">0</td>
<td style="text-align:center">
<select id="premium-disc-list">
<option value=""></option>
</select>
</td>
<td>
<div style="float:left">$</div>
<div style="float:right" id="premium-discount-total">0.00</div>
</td>
</tr>
</tbody>
</table>
jQuery
var table = $('#t01').dataTable();
//table.clear().draw();
//table.fnClearTable();
//table.fnDraw();
//table.fnDestroy();
//table.fnDraw();
I have 2 options in my mind:
1) You can mark all the elements that could be reset with some 'resetable' class and add data-original-val property, and once you decide to reset it do something like that:
$('.resetable','#t01').each(function(){
var originalVal = $(this).data('original-val');
$(this).html(originalVal);
})
2) Render another copy of the table inside type="text/html" script like this:
<script type="text/html" id="t01-original">
<table class="table table-bordered table-hover table-sm" id="t01">
<thead style="text-align:center">
<tr>
<th class="col-md-6" style="text-align:center">Dxx</th>
<th class="col-md-2" style="text-align:center">Rxx/Unit</th>
<th class="col-md-2" style="text-align:center">Txxx</th>
<th class="col-md-2" style="text-align:center">Pxxx</th>
</tr>
</thead>
...
</table>
</script>
this way all the content of the script tag won't be parsed and you won't have duplicate id issues. On the reset simply replace the content of the table with the one from the script:
//t01-container is the id of div that wraps the table:
$( '#t01-container').html($('#t01-original').html());

orderBy not sorting items in the following ngRepeat table

This is the table:
<table class="table table-striped">
<thead>
<tr>
<th class="col-md-1">Name</th>
</tr>
</thead>
<tbody>
<tr reportrowgroup="" ng-repeat="report in reporttree track by $index | orderBy:sortBy" report="report" rowindex="index" class="ng-scope ng-isolate-scope">
<td>Marcos Dima</td>
(etc...)
This is the dropdown orderBy:
<select class="pull-right" ng-model="sortBy">
<option value="createdAt">Sort by: <strong>Date</strong></option>
<option value="adminRealname">Sort by: <strong>Username</strong></option>
</select>
Content in reporttree (sample):
[
{
"createdAt": "2015-08-12T13:06:54.901Z",
"adminRealname": "Marcos Dima",
},
{
"createdAt": "2015-12-12T13:06:54.901Z",
"adminRealname": "Another name",
},
(etc...)
But when I select adminRealname or createdAt from the dropdown nothing happens. Am I doing something wrong?
EDIT:
The table is a directive and it's in a separate table. Maybe that's the problem?
' </tr>'+
'</thead>'+
' <tbody>'+
' <!-- <tr ng-repeat="report in reporttree track by $index"> -->'+
' <tr reportrowgroup ng-repeat="report in reporttree | orderBy:sortBy" report="report" rowindex="index"></tr>'+
' </tbody>'+
'<!-- </div> -->'+
'</table>'
track by must always be the last expression
You can read up on it here
Please see working jsFiddle
var myApp = angular.module('application',[]);
myApp.controller('TestController', function ($scope) {
$scope.data = [{
createdAt: "2015-08-15T13:06:54.901Z",
adminRealname: "Marcos Dima"
},{
createdAt: "2015-12-15T13:06:54.901Z",
adminRealname: "Another name"
}];
});
And the HTML
<div ng-controller="TestController as vm">
<select class="pull-right" ng-model="sortBy">
<option value="createdAt">Sort by: <strong>Date</strong></option>
<option value="adminRealname">Sort by: <strong>Username</strong></option>
</select>
<table class="table table-striped">
<thead>
<tr>
<th class="col-md-1">Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="dataItem in data | orderBy:sortBy track by $index" report="report">
<td>{{dataItem.adminRealname}}</td>
</tr>
</tbody>
</table>
</div>

smart-table ng-repeat not rendering dynamic columns properly

html
<table st-table="ApplicationData.displayedCollection" class="table table-striped" st-safe-src="ApplicationData.source">
<thead>
<tr ng-repeat="col in ApplicationData.columns">
<td st-sort="{{col.name}}">{{col.caption}}</td>
</tr>
</thead>
js
$scope.ApplicationData = {
source: [],
displayedCollection: [],
columns: [{ name: 'APPLICATION_CODE', caption: 'Code', isSort: true },
{ name: 'APPLICATION_NAME', caption: 'Application', isSort: true }],
};
output
<table st-table="ApplicationData.displayedCollection" class="table table-striped" st-safe-src="ApplicationData.source">
<thead>
<tr ng-repeat="col in ApplicationData.columns" class="ng-scope">
<td class="ng-binding">Code</td></tr>
<tr ng-repeat="col in ApplicationData.columns" class="ng-scope">
<td class="ng-binding">Application</td></tr>
</thead>
</table>
Hi, I am using this html to generate columns dynamically but wvery time I try I am getting dynamically generated rows instead. please review my enclosed code and let me know the issue.
just need to edit the template slightly: move the ng-repeat out of the <tr> and into <td>
change this:
<thead>
<tr ng-repeat="col in ApplicationData.columns">
<td st-sort="{{col.name}}">{{col.caption}}</td>
</tr>
</thead>
to, for example, this:
<thead>
<tr>
<td ng-repeat="col in ApplicationData.columns">{{col.caption}}</td>
</tr>
</thead>
here's a jsfiddle with this code: https://jsfiddle.net/86y3yxmk/1/
additionally, this is a good read for what you might be trying to accomplish: https://www.codementor.io/debugging/4948713248/request-want-to-use-values-in-nested-ng-repeat
GL!

Categories