Angularjs filter and select all checkbox - angularjs

I have an array of items I am displaying with
<tr ng-repeat="i in items | filter:search_text" ...>
the items have a check box that denotes "selected" or not.
how can I know which items are displayed by the filter when I need to do something like call a delete function that will delete all selected items ?
Items which have been selected (checked in the checkbox) and then hidden by filtering are still selected. I need a way to know which item is on screen at the moment.

You can use $filter to call a filter in your controller.
app.controller('MyCtrl', function($scope, $filter){
var filter = $filter('filter');
$scope.items = [/* your items here */]
$scope.selectAllFilteredItems = function (){
var filtered = filter($scope.items, $scope.search_text);
angular.forEach(filtered, function(item) {
item.selected = true;
});
};
});
You would then call selectAllFilteredItems() in an ng-click or anywhere else you needed to.

Not really super polished, but it works.
In your controller
var filter = $filter('filter');
$scope.item_ids = [];
$scope.selectAllFilteredItems = function (){
var filtered = filter($scope.items, $scope.searchText);
angular.forEach(filtered, function(item, key) {
if($scope.item_ids.indexOf(item.id) == -1){
$scope.item_ids.push(item.id);
$scope.items[key].selected = true;
}else{
$scope.item_ids.splice($scope.item_ids.indexOf(item.id),1);
$scope.items[key].selected = false;
}
});
};
Then in the table you have a checkbox to select all or unselect all.
<table class='table table-striped'>
<tr>
<th><input type="checkbox" ng-click="selectAllFilteredItems()"></th>
</tr>
<tr ng-repeat="item in items | filter:searchText">
<td><input type="checkbox" ng-model="item.selected"></td>
</tr>
</table>

Related

How to bind data from controller to ng-repeat - textbox using index number

I have two select drop down list and one text box.
There is option to clone each row using ng-repeat.
When selecting dropdown value i will get value from database. So i need to bind that value in textbox.
Controller:
$scope.major_change = function(value, index){
$scope.major_id = value;
};
$scope.minor_change = function(value, index){
$scope.minor_id = value;
$scope.active = 'active';
var temp = surveyService.getDistList($scope.major_id, $scope.minor_id);
temp.then(function (msg) {
alert(msg.data[0].gi_code);
$scope.gi_code[index] = msg.data[0].gi_code;
}, function () {
$scope.Error = 'Error in adding record';
});
};
Html Screen
You are binding the wrong value to ng-model. This was the reason two way binding was not working.
$scope.minor_change = function(value, index){
$scope.minor_id = value;
/*$scope.dist.gi_code[index] = value;*/
$scope.dist_list[index].gi_code=value;
}
Working Plunker: https://plnkr.co/edit/dRr90YtjtSRhHUZKisMQ?p=preview
I don't know what actually your html code look like but may be this help you as desired.You can use two-way data binding as :
HTML Code :
<tr>
<td><select class="select1"></option></option></td>
<td><select class="select1"></option></option></td>
<td><input type="text" ng-model="value" ></td>
Javascript Code :
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.value= $('.select1').val();
});
</script>

Angular print service timeout issue for multiple print

var userServicePromise = UserService.printBarCodes(sampleId);
userServicePromise.then(function(response) {
if (response != null && response.data != null && response.data.result != null) {
response.data.result.forEach(function(entry) { //three values in the array, iteraring three times.
$timeout(function() {
vm.barCodeImage = angular.copy(entry);
$timeout(function() {
PrintService.printElement("printThisElement"); // display one value three times
}, 1);
}, 2);
});
} else {
toaster.error(response.data.message);
}
});
using print service to print the div, values of the div are populated using the variable(vm.barCodeImage).
But here one value is displaying all the time in the print. tried adding time out interval after the for each, but no luck.
//print service code
(function() {
'use strict';
angular.module('app.services')
.factory('PrintService', PrintService);
PrintService.$inject = [];
function PrintService() {
var service = {
printElement: printElement
};
return service;
function printElement(elem) {
var printSection = document.getElementById('printSection');
// if there is no printing section, create one
if (!printSection) {
printSection = document.createElement('div');
printSection.id = 'printSection';
document.body.appendChild(printSection);
}
var elemToPrint = document.getElementById(elem);
// clones the element you want to print
var domClone = elemToPrint.cloneNode(true);
printSection.innerHTML = '';
printSection.appendChild(domClone);
window.print();
window.onafterprint = function() {
printSection.innerHTML = '';
}
};
}
})();
The expected result for this should be three different print(suppose loop size is 3, it should be 7858,7859,7860), but here it displays all same.
printThisElement id is an HTML.
<div id="printThisElement" class="onlyprint" >
<table>
<tr>
<td>{{ ctrl.instCode }}</td>
<td align="center">{{ ctrl.date | dateDisplayFilter}} </td>
</tr>
<tr>
<td colspan="2" align="center"> <img ng-src="data:image/JPEG;base64,{{ctrl.barCodeImage}}"> </td>
</tr>
<tr>
<td colspan="2" align="center">{{ ctrl.user.name }} </td>
</tr>
<tr>
<td >Reg Id: {{ ctrl.regIdLookup }}</td>
<td align="center">{{ ctrl.testName }}</td>
</tr>
</table>
</div>
Ok, I supposed your binding is wrong. printThisElement refer to single data in controller. So if you have multiple entries, it must be an array.
I suggest to you to use a directive instead of a service to print element in DOM.
I create a little plunker to illustrate it : https://plnkr.co/edit/QvmqV88wZCYbsehMWh3W?p=preview
This plunker show how from an array resulting of calling an async service you can display all entries.
The directive is very simple :
.directive('print', function() {
return {
restrict: 'E',
scope: {
data: '='
},
template: '<div id="printThisElement" class="onlyprint" ><table><tr> <td>{{ data.instCode }}</td></tr><tr><td>... Other values in data ...</td></tr></table></div>',
}
})
The template of the directive is your printThisElement id. With this way you can display multiple result isolate by directive.
Hope this will help you
Edit : Solution for the problem was report on this stack Inconsistent Data on multiple page printing on a printer

watching ng-repeat objects used outside of of ng-repeat

Ok I have created a ng-repeat to get all users created by an $http.get. This get request updates every 5 secs by using $interval and displays individual user data when clicked by calling $scope.goInfo(data). This $scope.goInfo(data) is used throughout the page to show user data, but is created by the ng-repeat (but not always used in ng-repeat). How can I have this data obj created by ng-repeat update every 5 secs outside of ng-repeat? I can't wrap $scope.goInfo() in a $interval.
EXAMPLE
//CONTROLLER//
function liveFeed(){
$http.get('some URL').then(function (user) {
$scope.user = user.data;
console.log('user data is', $scope.user);
});
}
//Updates get req every five secs//
$interval(liveFeed, 5000);
//gets data obj from ng-repeat, needs to be updated every 5 secs.//
$scope.goInfo = function (data) {
$scope.name = data.name;
$scope.beats = data.beats;
}
HTML
<table>
<th>First Name: John</th>
<th>Last Name:</th>
<tr ng-repeat="data in user" ng-click = "goInfo(data)">
<td>{{data.name}}<td>
</tr>
</table>
<span>{{beats}}</span><!--needs to update every 5 secs, outside of ng-repeat and be binded to the user that was clicked on-->
You need to reset selected object after you retrieve new data. Basically, you just need to find corresponding records in new array of objects and set it as selected again.
Something like this should do the trick:
function liveFeed() {
$http.get('some URL').then(function(user) {
$scope.user = user.data;
// Find the record that was selected before this update
if ($scope.selectedUser) {
$scope.selectedUser = $scope.user.filter(function(obj) {
return obj.name === $scope.selectedUser.name; // or compare by unique id
})[0];
}
});
}
// Updates get req every five secs
$interval(liveFeed, 5000);
// Gets data obj from ng-repeat, needs to be updated every 5 secs
$scope.goInfo = function(data) {
$scope.selectedUser = data;
}
and HTML will use selectedUser:
<table>
<tr>
<th>First Name: John</th>
<th>Beats:</th>
</tr>
<tr ng-repeat="data in user" ng-click="goInfo(data)">
<td>{{data.name}}<td>
<td>{{data.beats}}</td>
</tr>
</table>
<span>{{selectedUser.beats}}</span>

Select value where id in angularjs template

I've got two scope objects
$scope.selectedItems = [1,3]
$scope.items = [{'id':'1','name':'apple'},{'id':'2','name':'banana'},{'id':'3','name':'grapes'}]
In my template I want to use ng-repeat for $scope.selectedItems, but show item names. Is it possible?
Smth. like
<span ng-repeat="selItem in selectedItems track by $index">{{ items.name | items.id == selItem }}</span>
You have few of issues, First is that your ids are string but your stored array of selected items are numbers. My solution tries to accommodate that.
You need to create a third scope property that dynamically calculates the items that have the same id as your selected items ids and returns them.
$scope.selectedItemIds = [1,3]
$scope.items = [{'id':'1','name':'apple'},{'id':'2','name':'banana'},{'id':'3','name':'grapes'}];
$scope.selectedItems = function(){
var _selectedItems = [];
angular.forEach($scope.items, function(item){
if ($scope.selectedItemIds.indexOf(Number(item.id)) != -1){
_selectedItems.push(item);
}
});
return _selectedItems;
};
Now you can use that function in your ng-repeat iterator to access the selected items on the view:
<ul>
<li ng-repeat="item in selectedItems()">{{ item.name }}</li>
</ul>
Here is a working fiddle
You can try it by custom filter:
In controller:
$scope.selectedItems = ['1','3'];
$scope.items = [{'id':'1','name':'apple'},{'id':'2','name':'banana'}, {'id':'3','name':'grapes'}];
$scope.getselectedItem= function(item) {
if($scope.selectedItems.indexOf(item.id)!==-1) {
return item;
}
else {
return null;
}
};
In Html:
<p ng-repeat="item in items | filter: getselectedItem">{{item.name}}</p>

$$hashkey showing up in ng-repeat output

One of the columns in my ng-repeat directive outputs the values of $$hashkey.
I have no idea how this started happening. I get data from a simple GET and inspecting that data as it gets in from the success callback shows the $$hashkey being inserted to each object. I understand the $$hashkey is used by angular but this never happened before as far as HTML view output goes.
This is on 1.2.16
HTTP GET:
$http.get('index.php/getWorkbook/'+$routeParams.workbook).success(function(data) {
console.log(data); // Has $$hashkey inserted
$scope.workbook = data;
});
HTML:
<tr ng-repeat='row in workbook'>
<td ng-repeat="key in notSorted(row)" ng-init="value = row[key]">
<input type="text" ng-model="value" ng-blur="edit(value, key, row)" />
</td>
</tr>
Here is the controller function.
$scope.notSorted = function(obj){
if (!obj) {
return [];
}
return Object.keys(obj);
}
Seems the rows don't like being ran through notSorted(). Adding angular.copy() ended up working for me.
$scope.notSorted = function(obj){
obj = angular.copy(obj);
if (!obj) {
return [];
}
return Object.keys(obj);
}
Try this change in your controller
$scope.workbook = data;
$scope.workbook = angular.fromJson(angular.toJson($scope.workbook));

Resources