I'm trying to use Angular.JS to dynamically add columns to an html table.
It starts with a set of data, and I want to make extra data available on a click. I'm new to Angular, and made this plunker to illustrate what I'm trying to do. I'd like to (obviously) just add a new table header and a new table data based on the number of items in the array, matched to the index number of the same row. Thank you
Controller:
function Ctrl($scope) {
$scope.data = [];
$scope.data[3] = [];
$scope.data[0] = [['New York', 1000,2000],['Los Angeles', 200,400],['Nottingham', 800,400]]
$scope.moredata = [1500, 2500, 4500];
temp = []
$scope.getData = function() {
$scope.moduleArray[1] = $scope.moredata;
}
$scope.moduleArray = $scope.data;
}
HTML:
<div ng-controller="Ctrl">
<button ng-click="getData()">Get more data</button>
<table>
<tr>
<th>Location</th>
<th>Current Data</th>
<th ng-repeat="ba in moduleArray[1]">new data</th>
</tr>
<tr data-ng-repeat="item2 in moduleArray[0]">
<td>2[0]{{item2[0]}}</td>
<td>2[1]{{item2[1]}}</td>
<td data-ng-repeat="bat in moduleArray[1]">{{bat[$parent.$index]}}</td>
</tr>
</table>
Plunkr
Here's very simple set up that toggles single columns on right side.
There are 2 sets of arrays, one for column headers and one for row data.
It uses limitTo filter for ng-repeat.
From there it is a simple increment/decrement of a scope variable colCount to add/remove column
View
<button ng-click="increment('up')">Add Column</button>
<button ng-click="increment('down')">Remove Column</button>
<table class="table table-bordered">
<tr>
<th ng-repeat="col in cols | limitTo: colCount">{{col}}</th>
</tr>
<tr ng-repeat="row in data">
<td ng-repeat="item in row | limitTo: colCount">{{item}}</td>
</tr>
</table>
Controller
// used as limit for ng-repeat limitTo
$scope.colCount = 3;
$scope.increment = function(dir) {
(dir === 'up') ? $scope.colCount++: $scope.colCount--;
}
$scope.cols = // array of column names
$scope.data = // row data arrays
Note that for large tables this may not great for performance due to multiple nested repeaters
DEMO
Related
I am trying to learn AngularJS 1.6 and I am trying to populate a table with rows depending on the amount of rows selected in a dropdown list. It could be anywhere from 1 to 12. So far I have the following code.
<body ng-controller="myController">
<div>
<p>Blue Corner Boxer: </p> <input type="text" ng-model="nameBlue">
<br>
<p>Red Corner Boxer: </p> <input type="text" ng-model="nameRed">
<br>
<p>Number of Rounds:</p> <select ng-model="selectedRounds"><option ng-repeat="x in rounds">{{x}}</option></select>
</div>
<div>
<table class="table table-striped">
<thead>
<tr>
<th style="text-align:center">{{nameBlue}}</th>
<th style="text-align:center">Round</th>
<th style="text-align:center">{{nameRed}}</th>
</tr>
</thead>
<tbody class="tablerows">
<tr ng-repeat="x in selectedRounds">
<td>Test</td>
<td>Test</td>
<td>Test</td>
</tr>
</tbody>
</table>
<h2 style="text-align: center">Final Score: </h2> {{scoreBlue1 + ScoreBlue2}}
</div>
</body>
Then in the js file
//Create the module
var myApp = angular.module("myModule", []);
//Create the controller and register the module in one line
myApp.controller("myController", function ($scope) {
$scope.message = "AngularJS tutorial";
$scope.score = [1,2,3,4,5,6,7,8,9,10];
$scope.rounds = [1,2,3,4,5,6,7,8,9,10,11,12];
});
So far the table will add 1 row on selection of anything 1 to 9, but 10 to 12 adds 2 rows. So I think I am wondering how to create an array length of size "selectedrounds" that will repeat rows with the repeater.
Thanks
If you need an array only for iterating and you don't worry about data in it. You can do something like this:
In your controller:
$scope.selectedRounds = 0;
$scope.getRoundsArray(){
return new Array($scope.selectedRounds);
}
We just create an array with needed length and with all elements are 'undefined'. If you create an array with 3 lenght you will get: ['undefined', 'undefined', 'undefined'].
In view:
<tr ng-repeat="x in getRoundsArray() track by $index">
You need this track by $index cause your array contains only 'undefined' values so to prevent angular arguing about duplicate keys we need to use track by.
I populate brief info about customers in a table from a web api. What i want to achieve is when someone should click on the Customer Name text, the names there should be order in ascending order and on another click it should toggle to descending. By default when the page loads it arranges the list by ID descending
HTML
<table class="table table-striped table-hover">
<tr class="success">
<td><strong>Customer Name</strong></td>
<td><strong>Phone Number</strong></td>
<td><strong>Address</strong></td>
<td><strong>Gender</strong></td>
<td><strong>Email</strong></td>
<td><strong>User Group</strong></td>
</tr>
<tr ng-repeat="item in users_list | orderBy:'-ID'">
<td>{{item.Customer_Name}}</td>
<td>{{item.Phone_Number}}</td>
<td>{{item.Address}}</td>
<td>{{item.gender}}</td>
<td>{{item.email}}</td>
<td>{{item.user_group}}</td>
</tr>
</table>
JS
.controller('app_users_ctrl',function($scope,$http,$location){
$scope.loading=true;
$http.post('http://localhost/calls/app_users.php').success(function(data){
$scope.users_list=data
console.log(JSON.stringify(data));
$scope.loading=false;
})
})
Hi have you tired something like:
<table class="table table-striped table-hover">
<tr class="success">
<td><strong><a clikme('Customer_Name')>Customer Name</a></strong></td>
<td><strong><a clikme('Phone_Number')>Phone Number</a></strong></td>
<td><strong>Address</strong></td>
<td><strong>Gender</strong></td>
<td><strong>Email</strong></td>
<td><strong>User Group</strong></td>
</tr>
<tr ng-repeat="item in users_list | orderBy: myvar">
<td >{{item.Customer_Name}}</td>
<td >{{item.Phone_Number}}</td>
<td>{{item.Address}}</td>
<td>{{item.gender}}</td>
<td>{{item.email}}</td>
<td>{{item.user_group}}</td>
</tr>
</table>
and the in you js:
.controller('app_users_ctrl',function($scope,$http,$location){
$scope.loading=true;
var order = false;
$http.post('http://localhost/calls/app_users.php').success(function(data){
$scope.users_list=data
console.log(JSON.stringify(data));
$scope.loading=false;
})
})
$scope.clikme= function(field){
$scope.myvar= order ? '-' + field : '+' + field;
order=!order;
}
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="orderCtrl">
<ul>
<li ng-repeat="x in cars | orderBy">{{x}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('orderCtrl', function($scope) {
$scope.cars = ["Dodge", "Fiat", "Audi", "Volvo", "BMW", "Ford"];
});
</script>
<p>The array items are displayed alphabetically.</p>
</body>
</html>
As I don't have your JSON data, I added a simple example of sorting in ascending order. All we have to do is, use orderBy filter.
Suppose You are storing your fields in values array so for ascending order and onclick:
values.sort(function(value1,value2){ return value2 - value1; });
For decending order:
values.sort(function(value1,value2){ return value1 - value2; });
Hope it helps.
Also Use a flag inside your function to take care of order in which it is sorted.
https://scotch.io/tutorials/sort-and-filter-a-table-using-angular
Follow that guide. It helped me when I had to do what you have to do!
This is a simple example of using table in angularJS with sorting anf filter
angular.module("myApp", ["ngTable"]);
//This is your controller
var self = this;
var data = [{name: "Deon", age: 22} /*,*/];
self.tableParams = new NgTableParams({}, { dataset: data});
<table ng-table="vm.tableParams" class="table" show-filter="true">
<tr ng-repeat="user in $data">
<td title="'Name'" filter="{ name: 'text'}" sortable="'name'">
{{user.name}}</td>
<td title="'Age'" filter="{ age: 'number'}" sortable="'age'">
{{user.age}}</td>
</tr>
</table>
It's easy, add ng-click="sortType == 'customer-name'" or whatever else you'd like to sort by, on each table heading. BTW, you should fix your table and use thead > th for headings. It's the proper way of formatting it.
Create a scope variable where you store the search criteria. Set the orderBy value to this variable. Change that variable when you want to order by another property.
Create another variable for ascending / descending ordering and add it to the orderBy filter. You can now change that variables to influence the order behaviour.
HTML:
<tr ng-repeat="item in users_list | orderBy: criteria: isDescending">
JS Controller:
$scope.criteria = '-ID';
$scope.isDescending = true;
I have a table sorted by properties "age" and "name" but I have a counter of rows (counterR) that shows the numbers of rows in the table.
I want to exclude this item on OrderBy because is ordered too, I need it would be static and always ordered but I canĀ“t.
There's the Plunker link of my problem: http://plnkr.co/edit/MJYayUANphxksbGkyEcj?p=preview
HTML:
<body ng-controller="MainCtrl">
<table border="0">
<thead>
<tr>
<th>#</th>
<th>ID</th>
<th ng-click="sortType = 'name';sortReverse=!sortReverse">NAME</th>
<th ng-click="sortType = 'age';sortReverse=!sortReverse">AGE</th>
</tr>
</thead>
<tbody>
<tr ng-init="counterR=incrementCounter()" ng-repeat="item in items | orderBy:sortType:sortReverse">
<td>{{counterR}}</td>
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.age}}</td>
</tr>
</tbody>
</table>
JS:
$scope.items = [
{"name":"Jhon","id":"BB1","age":23},
{"name":"Austin","id":"BB2","age":44},
{"name":"Mark","id":"BB3","age":56},
{"name":"Jenn","id":"BB4","age":15}
];
var counterRow = 0;
$scope.incrementCounter = function(){
counterRow = counterRow + 1;
return counterRow;
}
Instead of storing the row number with the data - which doesn't work because the row numbers are not specific to a data row, but rather to a display position - you need to calculate the value "on the fly". In the scope of an ng-repeat you can do this with the special $index variable. That is, instead of
<td>{{counterR}}</td>
which reads a value from the data row, you would use
<td>{{$index+1}}</td>
(assuming sequential numbers starting from 1)
I have json array and i want to create table from this and want to give a heading which is an element of array. Here is fiddle showing the scenario.
<div ng-repeat="products in items">
<div>{{products.IDTYPE}}</div>
<div>
<table border=1>
<thead>
<th>primkey</th>
<th>userid</th>
</thead>
<tbody>
<tr>
<td>{{products.PRIMKEY}}</td>
<td>{{products.USERID}}</td>
</tr>
</tbody>
</table>
</div>
This will create simple table with heading from the IDTYPE . But i want to group the rows with unique IDTYPE. So desired table will be as shown in this link.
So i tried adding a ng-show condition ng-show="$index==0 || items[$index-1].IDTYPE!=items[$index].IDTYPE" but it doesn't work properly as tbody and table will be constructed for every row.This is what i have tried.
So how to generate the table as i desired in the above description?
If you do not wish to change your source data structure to fit better to what you need, you may have to write some extra code to change it from the javascript side. Something like:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.items = [...]; //your original data
// Here the transformation begins...
$scope.newItems = {};
for (var i = 0; i < $scope.items.length; i++) {
// We'll make it look like a map
// Each IDTYPE will have an array associated to it
if (!$scope.newItems[$scope.items[i].IDTYPE]) {
$scope.newItems[$scope.items[i].IDTYPE] = [];
}
$scope.newItems[$scope.items[i].IDTYPE].push($scope.items[i]);
}
}
From the HTML side, you just have to read accordingly to your new data:
<div ng-repeat="products in newItems">
<div>{{products[0].IDTYPE}}</div>
<div>
<table border=1>
<thead>
<th>primkey</th>
<th>userid</th>
</thead>
<tbody>
<tr ng-repeat="productItem in products">
<td>{{productItem.PRIMKEY}}</td>
<td>{{productItem.USERID}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Fiddle: http://jsfiddle.net/5mpgzdem/
I'm trying to sort a table by each column. The table has a different amount of rows and columns each time. The problem is with the predicate. All of the repeated columns are name "i", and I need to be able to sort them individually.
HTML:
<table>
<thead>
<th>name</th>
<th ng-repeat="header in headers">{{header}}</th>
</thead>
<tbody>
<tr ng-repeat="v in columns | orderBy:predicate:reverse">
<td>{{v.value}}</td>
<td ng-repeat="i in v.item">{{i}}</td>
</tr>
</tbody>
</table>
Controller:
function controller($scope) {
$scope.headers = ["col1", "col2", "col3", "col4"];
$scope.columns = [{value:'row1', item:['1','2','3','4']},
{value:'row2', item:['4','5','6','7']},
{value:'row3', item:['8','9','10','11']},
{value:'row4', item:['12','13','14','15']}];
$scope.predicate = 'value';
}
Here is the jsfiddle.
Thanks for the replies.
Change the statement like this
<th ng-repeat="header in headers">
{{header}
</th>
Note: Since the cells are all strings, this will sort all columns as string alphabetically.
Hope it can shed some light on.
Demo