How to show only one row in angular datatable? - angularjs

I am new to angularjs, i have 25 rows to show, but for first time loading i am trying to show only one row, there will be one expand button to show remaining rows, then on click of expand i want to show all the rows.
Here is the code.
<table>
<tbody>
<tr ng-repeat="x in names">
<td>{{x}}</td>
</tr>
</tbody>
</table>

You can use:
<div ng-repeat="x in names | limitTo: limit">
<p>{{x}}</p>
</div>
$scope.limit = 1;
and on ng-click you can set your limit like: ng-click='limit = names.length'

This is what you can try.
<div ng-init="limit= 1">
<button ng-click="limit=names.length">View</button>
<table>
<tbody>
<tr ng-repeat="x in names | limitTo: limit">
<td>{{x}}</td>
</tr>
</tbody>
</table>
</div>
https://jsfiddle.net/alpeshprajapati/7MhLd/2252/

Try limitTo filter :
The limitTo filter returns an array or a string containing only a specified number of elements.
Syntax :
{{ object | limitTo : limit }}
As per the requirement :
Js :
var app = angular.module('myApp', []);
app.controller('MyCtrl',function($scope) {
$scope.elements = ["1", "2", "3", "4", "5"];
$scope.limit = 1;
});
Html :
<button ng-click="limit=elements.length">Expand More</button>
<table>
<tr ng-repeat="item in elements | limitTo: limit">
<td>{{item}}</td>
</tr>
</table>
Working fiddle : https://jsfiddle.net/rohitjindal/vcxvvecr/2/

// Angular `slice` filter for arrays
var app = angular.module('myApp', []);
app.filter('slice', function() {
return function(arr, start, end) {
return arr.slice(start, end);
};
});
app.controller('MainController', function($scope) {
$scope.offset = 1;
$scope.items = [1,2,3,4,5,6,7,8,9,10,11,12,13,14];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller='MainController' ng-init="start = 0;">
<ul>
<li ng-repeat="item in items | slice:start:offset">{{item}}</li>
</ul>
<button ng-click="offset = items.length">Expand</button>
</div>
</div>
I use slice for limit set
You can also try with:
limitTo: (limit) : (begin)
you can say ng-repeat="item in list | limitTo:50:0"

Limit the rows by set a scope variable in the controller and filter it in the ng-repeat.
Script:
var app = angular.module('myApp', []);
app.controller('limitCtrl',function($scope) {
$scope.limitNumber = 1;
});
Html:
<table>
<tbody>
<tr ng-repeat="x in names | limitTo: limitNumber">
<td>{{x}}</td>
</tr>
</tbody>
</table>

Related

How can i make dynamic ng-repeat using angularjs?

Below I have added my data
[{
"name":"testapp",
"version":"2.0",
"description":"testapp",
"applicationenvironment":"angularjs"
}]
I want to make ng-repeat but I don't want to hard code any field (name, version, description, applicationenvironment)
How can I achieve this?
MY expectation :
IN TABLE it should come like this
Your array should be an object. So your structure simplifies quite a lot. Just extract key and values from your object and loop over it for each row. Then display key and values in separate columns per row:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.table = [{
"name": "testapp",
"version": "2.0",
"description": "testapp",
"applicationenvironment": "angularjs"
}]
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr ng-repeat="(key, value) in table[0]">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
</table>
</div>
</body>
</html>
Although I don't recommend you to have this strucuture, you can do something like this:
angular.module('app', [])
.controller('appController', function () {
this.data = {
"name":"testapp",
"version":"2.0",
"description":"testapp",
"applicationenvironment":"angularjs"
};
});
And your HTML would be something like this:
<div ng-app="app" ng-controller="appController as vm">
<ul>
<li ng-repeat="(key, value) in vm.data"> {{ key }} : {{ value }}</li>
</ul>
</div>
If you still need to have the data inside an array as you've wrote in the question, you would have to iterate over both the array and the object.
Now since your data source is an array, you need to do two nested ng-repeats
let app = angular.module("table",[]);
app.controller("tableCtrl", ["$scope", function($scope){
$scope.data = [{
"name":"testapp",
"version":"2.0",
"description":"testapp",
"applicationenvironment":"angularjs"
},
{
"name":"testapp 2",
"version":"2.1",
"description":"testapp 2",
"applicationenvironment":"angularjs"
}];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="table" ng-controller="tableCtrl">
<table ng-repeat="row in data">
<tr><td>Key</td><td>Value</td></tr>
<tr ng-repeat="(key,value) in row">
<td>{{key}}</td><td>{{value}}</td>
</tr>
</table>
</div>
Now if you do this, your data structure should yield the wanted result
You need to loop twice: Once through each the entire array of objects to access each object, and then inside each object to access individual key-value pairs.
I have posted the code below:
angular.module('app', [])
.controller('Controller1', function () {
this.data = {
"name":"testapp",
"version":"2.0",
"description":"testapp",
"applicationenvironment":"angularjs"
};
});
<div ng-app="app" ng-controller="Controller1 as c1">
<table>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr ng-repeat="c in c1.data">
<table>
<tr ng-repeat="(key, value) in c">
<td> {{ key }} </td>
<td> {{ value }} </td>
</tr>
</table>
</tr>
</table>
</div>

ng-repeat sortBy not reordering after push

As the title says, I can´t achieve the desired behavior when using orderBy with ng-repeat.
That´s the list I want ordered:
<div class = 'row' ng-repeat = 'tabla_salarial in master.tablas_salariales | orderBy:-fecha'>
<div class = 'col'><p><label>{{tabla_salarial.fecha | date:dd-MM-yyyy }}</label></p></div>
<div class = 'col'><p><span>{{tabla_salarial.salario_bruto | number : 2 }}€</span></p></div>
<div class = 'col'><p><span>{{tabla_salarial.finiquito_vacaciones | number : 2 }}€</span></p></div>
<div class = 'col'><p><span>{{tabla_salarial.finiquito_indemnizacion | number : 2 }}€</span></p></div>
<div class = 'col'><p><span>{{tabla_salarial.precio_sustitucion | number : 2 }}€</span></p></div>
</div>
And this is the piece of code inside the controller that is supposed to handle the list insertions:
$http.post("controlador/TablaSalarial/insert", $scope.tabla_salarial).then(function(response){
if ( response.data.errno ){
Dialog.toast(response.data.err);
}
else{
RowService.add(response.data.row, "tablas_salariales");
$scope._dialog.hide();
$scope.t = {};
$scope.master.tablas_salariales.push(response.data.row);
}
}, function(response){/*...*/});
The table is correctly ordered at start, but every time a push a new record it is appended at the end of the table, although all the other items keep the order.
I know how to make a different approach, or use a new directive, and that´s not what I want.
Is there any way to make it work as expected? (And by expected I mean, keep the list ordered when pushing a new record)
Thanks in advance.
Well, there are some mistakes in your code:
You should use single quotes in your orderBy filter:
<div class="row" ng-repeat="tabla_salarial in master.tablas_salariales | orderBy: '-fecha'">
The date filter should also have single quotes:
<div class="col"><p><label>{{tabla_salarial.fecha | date:'dd-MM-yyyy' }}</label></p></div>
Working demo:
angular.module('app', [])
.controller('mainCtrl', function($scope) {
$scope.products = [];
var start = new Date(2012, 0, 1);
$scope.add = function(times) {
times = times || 1;
for (var i = 1; i <= times; i++) {
$scope.products.push({
"id": i,
"expiresOn": new Date(start.getTime() + Math.random() * (new Date().getTime() - start.getTime())),
"price": parseFloat(Math.min(100 + (Math.random() * (999 - 100)),999))
});
}
}
$scope.add(5);
});
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<table>
<caption>Products table</caption>
<thead>
<tr>
<th>Id</th>
<th>Expires On</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="product in products | orderBy: '-date'">
<td ng-bind="product.id"></td>
<td ng-bind="product.expiresOn | date: 'dd-MM-yyyy'"></td>
<td ng-bind="product.price | currency: '€': 2"></td>
</tr>
</tbody>
</table>
<hr>
<button type="button" value="add" ng-click="add()">Add new product</button>
</body>
</html>
Note: Instead of use the number filter and inserting the symbol by hand, as you're doing here for example:
<div class = 'col'><p><span>{{tabla_salarial.salario_bruto | number : 2 }}€</span></p></div>
You can use currency filter as below:
<div class = 'col'><p><span>{{tabla_salarial.salario_bruto | currency: '€': 2" }}</span></p></div>
I hope it helps!

How to change $index for two ngRepeats with same input but different filters?

I've simulated my problem here.
Looking into this html, you can see that I am doing two ng-repeats with the same array as input, but different filters to each one:
<div ng-app='Lists'>
<div ng-controller='listsController'>
<table>
<tbody>
<tr ng-repeat='item in listValues | filter : xxx track by $index' ng-click="update($index)">
<td>{{item.ref}}</td>
<td>{{item.others}}</td>
</tr>
</tbody>
</table><hr/>
<table>
<tbody>
<tr ng-repeat='item in listValues | filter : yyy track by $index' ng-click="update($index)">
<td>{{item.ref}}</td>
<td>{{item.others}}</td>
</tr>
</tbody>
</table><hr/>
<div>{{updateIndex}}</div>
</div>
</div>
And my js code:
var appModule = angular.module('Lists', []);
appModule.controller('listsController', function($scope) {
$scope.listValues = [
{'ref' : '1', 'others' : 'abc..'},
{'ref' : '2', 'others' : 'def..'},
{'ref' : '1', 'others' : 'ghi..'},
{'ref' : '2', 'others' : 'jkl..'}
];
$scope.xxx = function(a){
return a.ref == 1;
};
$scope.yyy = function(a){
return a.ref == 2;
};
$scope.update = function(i) {
$scope.updateIndex = i;
};
$scope.updateIndex = "none";
});
The problem I'm stuck is that the update(index) function needs to change the object in the correct index of the listValues array. But as you can see clicking in the object of the second table gives me the $index of the first table.
How to work around this situation? Thanks in advance.
Using the $index is doomed to fail, even if you iterate once. $index is the index of the current item in the filtered array. And that index is different from the index of the same element in the original, non-filtered array.
If you want to modify an item on click, don't pass its index as argument. Pass the item itself:
ng-click="update(item)"
Instead of filters use ng-if which allows you to track items by index.Index will give exact click even list has duplicate items
<body>
<div ng-app='Lists'>
<div ng-controller='listsController'>
<table>
<tbody>
<tr ng-repeat="item in listValues track by $index" ng-click="update($index)" ng-if="xxx(item)=='1'">
<td>{{item.ref}}</td>
<td>{{item.others}}</td>
</tr>
</tbody>
</table><hr/>
<table>
<tbody>
<tr ng-repeat='item in listValues track by $index' ng-click="update($index)" ng-if="item.ref=='2'">
<td>{{item.ref}}</td>
<td>{{item.others}}</td>
</tr>
</tbody>
</table><hr/>
<div>{{updateIndex}}</div>
</div>
</div>
</body>

Search in angularjs not working properly with angular bootstrap ui

i am using angular-ui bootstrap for pagination of a table and i have separate search input tag, the search input only searches the first set data from the paginated list, it does not search the subsequent paginated pages of the table, how do i search from the input for all the data.
HTML
<div ng-controller="IndexCtrl" >
<input class="form-control formcustom" id="exampleInputEmail2" ng-model="custquery" placeholder="Search for Tripsheets" autofocus>
<table class="table table-striped table-bordered table-condensed table-hover">
<tr ng-repeat="customer in customers | orderBy:'id':true | filter: paginate | filter: custquery">
<td>{{customer.id}}</td>
<td>
<span>{{customer.name}}</span>
</td>
<td>
<span>{{customer.address}}</span>
</td>
<td>
<span>{{customer.phone1}}</span>
</td>
<td>
<span >{{customer.phone2}}</span>
</td>
<td>
<span >{{customer.phone3}}</span>
</td>
<td>
<span>{{customer.phone4}}</span>
</td>
<td>
<span >{{customer.email}}</span>
</td>
</tr>
</table>
<pagination total-items="totalItems" ng-model="currentPage"
max-size="5" boundary-links="true"
items-per-page="numPerPage" class="pagination-sm">
</pagination>
</div>
JS
app.controller('IndexCtrl', function ($scope, customerFactory, tripsheetFactory, driverFactory, notificationFactory) {
$scope.customers = [];
$scope.addMode = false;
customerFactory.getCustomers().then(function(data){
$scope.customers = data.data;
$scope.totalItems = $scope.customers.length;
$scope.currentPage = 1;
$scope.numPerPage = 20;
$scope.paginate = function(value)
{
var begin, end, index;
begin = ($scope.currentPage - 1) * $scope.numPerPage;
end = begin + $scope.numPerPage;
index = $scope.customers.indexOf(value);
return (begin <= index && index < end);
};
});
});
customerFactory is the factory i created to fetch json data
The position of the customer in $scope.customers doesn't change so the paginate function will always filter out all but the first page of the full customers array. What you need is an intermediate result (another array) that holds the customers that pass the $scope.custquery filter. The paginate function needs to operate on that second, filtered array.
I couldn't see a way to do that declaratively so I injected filterFilter into the controller and added a watch on $scope.custquery to execute it.
I put together a plunk that shows the result.

How to default a table search results to hidden with AngularJS filters?

In the following Angularjs snippet, an entire table is shown by default and gets filtered down as you start typing.
What would be best practice to change it to show no results by default and only start showing results after, say, at least 3 results match the search query?
Bonus question, how would you go about only displaying results if a minimum of 2 characters have been entered?
Html:
<div ng-app="myApp">
<div ng-controller="PeopleCtrl">
<input type="text" ng-model="search.$">
<table>
<tr ng-repeat="person in population.sample | filter:search">
<td>{{person.name}}</td>
<td>{{person.job}}</td>
</tr>
</table>
</div>
</div>
Main.js:
var myApp = angular.module('myApp', []);
myApp.factory('Population', function () {
var Population = {};
Population.sample = [
{
name: "Bob",
job: "Truck driver"
}
// etc.
];
return Population;
});
function PeopleCtrl($scope, Population) {
$scope.people = Population;
}
You can do all of that in your markup, actually... here's a plunk to demonstrate
And here's the change in your markup:
<input type="text" ng-model="search">
<table ng-show="(filteredData = (population.sample | filter:search)) && filteredData.length >= 3 && search && search.length >= 2">
<tr ng-repeat="person in filteredData">
<td>{{person.name}}</td>
<td>{{person.job}}</td>
</tr>
</table>
EDIT: changed my answer to reflect your requests.

Resources