Highlight multiple selected Table Data (<td></td>) in ngRepeat - angularjs

There is a lot of examples about select multiples row in ngRepeat, but what I need is highligth multiple Table Data on click. This is what I have in my Controller:
app.controller('CalendarCtrl', function($scope, Calendar){
$scope.week = ['Dom','Lun','Mar','Mie','Jue','Vie','Sab']
$scope.hours = ['6:00','7:00','8:00','9:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00','20:00','21:00','22:00','23:00'];
$scope.idSelectedDayActive = null;
$scope.idSelectedHourActive = null;
$scope.setSelected = function (day, hour) {
$scope.idSelectedDayActive = day;
$scope.idSelectedHourActive = hour;
};
This is my View
<table class="table table-bordered">
<thead>
<th scope="col" title="Monday"><i class="fa fa-clock-o" aria-hidden="true"></i></th>
<th ng-repeat="d in week" scope="col">{{d}}</th>
</thead>
<tbody>
<tr ng-repeat="h in hours">
<td class="col">{{h}}</td>
<td ng-repeat="d in week"
ng-click="setSelected(d, h)"
ng-class="{'calendar-element-active' : d === idSelectedDayActive && h === idSelectedHourActive, 'calendar-element-disable' : d === idSelectedDayDisable && h === idSelectedHourDisable}">
</td>
</tr>
</tbody>
</table>
This are my CSS classes:
.table tbody>tr>td.calendar-element-active, .table tbody>tr>td.calendar-element-active {
background-color: #00d0d1;
border: 1px solid #fff;
}
.table tbody>tr>td.calendar-element-disable {
background-color: #fff;
}
And a Plunker DEMO

Here You can do it like this, The Js
'use strict';
var app = angular.module("app", []);
app.controller('CalendarCtrl', function($scope){
$scope.week = ['Dom','Lun','Mar','Mie','Jue','Vie','Sab']
$scope.hours = ['6:00','7:00','8:00','9:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00','20:00','21:00','22:00','23:00'];
$scope.idSelectedDayActive = null;
$scope.idSelectedHourActive = null;
$scope.selectedCells = [];
$scope.setSelected = function (day, hour) {
for(let selectedCell in $scope.selectedCells){
if($scope.selectedCells[selectedCell].day == day &&
$scope.selectedCells[selectedCell].hour == hour){
$scope.selectedCells.splice(selectedCell,1);
return ;
}
}
$scope.selectedCells.push({'day':day,'hour':hour});
};
$scope.check = function(day,hour){
for(let selectedCell of $scope.selectedCells){
if(selectedCell.day == day && selectedCell.hour == hour)
return true
}
return false
}
});
And in Html
<tr ng-repeat="h in hours">
<td class="col">{{h}}</td>
<td ng-repeat="d in week" ng-click="setSelected(d, h)"ng-class="{'calendar-element-active' : check(d,h), 'calendar-element-disable' : d === idSelectedDayDisable && h === idSelectedHourDisable}">
</td>
</tr>
Basically it is your logic only, just instead of a single selected, you have to use array and make it array of selected cells
Edit :- For removing the selected item, the setselected function is just checking if the cell is currently selected.. if it selected then it deselects and returns if the loop goes through without returning a new cell is selected

Related

How to highlight table row based on condition in angularJs?

so I got the table where I display certain data which includes dates and other stuff. What I want is to highlight row where the displayed date is the same as the current day. Table is ordered by the dates. Any idea about this use-case?
This is my code:
<table class="table table-striped" style="font-size:14px; margin-left: 5px;">
<head>
<tr>
<th style="text-align: left;"><data-i18n i18n="_m_f_pen_feeding_start_date_">Feeding date</data-i18n></th>
<th style="text-align: left;"><data-i18n i18n="_m_f_pen_frequency_of_feeding_">Frequency of feeding</data-i18n></th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="freq in vm.details.pen_feeding_scheduler_list | orderBy:'-start_feeding_date'">
<td style="min-width: 120px; text-align: left;">{{freq.start_feeding_date | date:'shortDate'}}</td>
<td style="min-width: 120px; text-align: left; display: inline-block;white-space: nowrap">{{freq.feeding_frequency || ('_label_empty_' | i18n)}}</td>
</tr>
</tbody>
</table>
In my controller i set current date as :
vm.current_date = new Date().toISOString().slice(0, 10)
If you need more code, I can provide it. Thanks in advance
Here is fiddle link for a simple example. You can modify it as per your need.
<div ng-class="getClass()">text</div>
Controller:
var myModule = angular.module('app', []);
var current_date = new Date().toISOString().slice(0, 10);
myModule.controller('myCtrl', function ($scope) {
$scope.getClass = function(){
if(current_date == '2020-07-23'){
return 'blue';
}else{
return 'red';
}
}
});
http://jsfiddle.net/5oc3fqzj/

ng-table: check box selection in each row

I have a ng-table where i am trying to implement selection using check box in each row.
<table id="List" class=" table table-bordered table-striped"
ng-table="tableParams" show-filter="true" template-pagination="custom/pager">
<tbody>
<tr ng-repeat="item in $data" >
<td style="width: 35px">
<input type="checkbox" name="selectedIds[]" value="{{item.id}}" ng-checked="isRowSelected(item.id)" ng-click="toggleSelection(item.id)" />
</td>
<td data-title="'Name'" sortable="'Name'" filter="{ 'Name': 'text' }" >
{{ item.Name}} </a>
</td>
<td data-title="'Email'" sortable="'Email'" >
{{ item.Email}}
</td>
<td data-title="'Phone Number'" sortable="'PhoneNumber'">
{{ item.PhoneNumber}}
</td>
</tr>
this is the controller:
angular.module("umbraco").controller("ListController",
function ($scope, $http, $routeParams) {
$scope.selectedIds = [];
$scope.toggleSelection = function (val) {
var idx = $scope.selectedIds.indexOf(val);
if (idx > -1) {
$scope.selectedIds.splice(idx, 1);
} else {
$scope.selectedIds.push(val);
}
};
$scope.isRowSelected = function (id) {
return $scope.selectedIds.indexOf(id) >= 0;
};
$scope.isAnythingSelected = function () {
return $scope.selectedIds.length > 0;
};
});
i am trying to select individual rows however the above code selecting all the rows on any row click.
any suggestion on this please?
You are not using the power of angular correctly :)
You should try something like that in your view:
<input type="checkbox" ng-checked="item.isRowSelected" ng-click="toggleSelection(item)" />
and in the controller:
$scope.toggleSelection = function(item){
item.isRowSelected = !item.isRowSelected;
}
$scope.isAnythingSelected = function () {
for(var i = 0; i < $scope.data.length; i++){
if($scope.data[i].isRowSelected === true){
return true;
}
}
return false;
};

Lazy loading without scrolling

<div class="table-responsive">
<table class="table table-striped table-hover table-bordered table-condensed">
<thead>
<tr style="text-align: left!important;">
<th width="4%">Part#</th>
<th width="5%">Description</th>
<th width="3.8%">{{title}}</th>
</tr>
</thead>
<tbody>
<tr ng-if="show" ng-repeat="item in dataElemet |orderBy:orderByField:reverseSort" class="PartData">
<td>
<div ng-if="item.isWarningIconShow == true"><img ng-src="../cim/images/projIcons/warning.png"/></div><span ng-bind="item.number"></span>
</td>
<td ng-bind="item.description"></td>
<td ng-bind="item.Number"></td>
<td ng-bind="item.prodCategory"></td>
</tr>
<tr ng-if="show" ng-repeat="item in dataElemet |orderBy:orderByField:reverseSort" class="PartData">
<td>
<div ng-if="item.isWarningIconShow == true"><img ng-src="../cim/images/projIcons/warning.png"/></div><span ng-bind="item.number"></span>
</td>
<td ng-bind="item.description"></td>
<td ng-bind="item.prodCategory"></td>
</tr>
</tbody>
</table>
$scope.intializePartsData = function(objId, dataType){
$scope.loading = true;
$scope.dataElemet = null;
$scope.dataElemet2 = null;
if($scope.show == true && $scope.title == "Show Non Prod"){
objectService.getParts(objId).then(function(parts){
if(dataType == "Elemet") {
$scope.dataElemet = parts.data;
$scope.partsOriginalElemet = angular.copy($scope.dataElemet);
} else {
$scope.dataElemet2 = parts.data;
$scope.partsOriginalElemet2 = angular.copy($scope.dataElemet2);
}
});
} else {
objectService.getPartsProduction(objId).then(function(parts){
if(dataType == "Elemet") {
$scope.dataElemet = parts.data;
$scope.partsOriginalElemet = angular.copy($scope.dataElemet);
} else {
$scope.dataElemet2 = parts.data;
$scope.partsOriginalElemet2 = angular.copy($scope.dataElemet2);
}
});
}
$scope.loading = false;
}
$scope.showHideParts = function(dataType){
$scope.intializePartsData($scope.objId, dataType);
if($scope.show == true && $scope.title == "Show Non Prod"){
$scope.title = "Hide Non Prod";
$scope.show = false;
}else{
$scope.title = "Show Non Prod";
$scope.show = true;
}
}
This is my code its work fine normally . But When there is more data it takes time. So I want to implement lazy loading but as client not interested in scrolling, i need to to do lazy loading without scroll. Is it any way to do lazy loading in angularjs without any event from user.

How to set checkAll for in angularjs ng-repeat table

I have a complex ng-repeat table,which I need to set the select all function for the checkbox of each row.He is my code:
JS:
$scope.getCCGenie = function(){
CCGenieService.transactionList().then(function(list){
$scope.CreditCardsList = list;
$scope.CorporateCardsNum = $scope.CreditCardsList.transactionInfo.corpCardCount;
$scope.PersonalCardsNum = $scope.CreditCardsList.transactionInfo.personalCardCount;
});
}
$scope.hasExpenseTypeLabel = false;
$scope.getCCGenie();
$scope.checkAllcorp = function(copcards) {
console.log(copcards);
if (copcards.selectedAllcorp) {
copcards.selectedAllcorp = true;
$scope.hasSelectedExpense = true;
} else {
copcards.selectedAllcorp = false;
$scope.hasSelectedExpense = false;
}
angular.forEach('copcards.transactions',function(v,k){
v.corpisSelected = copcards.selectedAllcorp;
})
};
// I need to loop the selected table to reset each corpisSelected,assign them the new value selectedAllcorp. but how?
};
Html:
<ul>
<li ng-repeat='copcards in CreditCardsList.transactionInfo.corporateCards'>
<span class='creditcardsubtitle'>{{copcards.cardName}} (****{{copcards.cardNumber}})</span>
<table class='table col-xs-12 col-md-12 col-lg-12' border="0" cellpadding="10" cellspacing="0" width="100%">
<thead>
<th class='text-center'><input type="checkbox" ng-model="copcards.selectedAllcorp" ng-change="checkAllcorp(copcards)"/></th>
<th class='text-left'>Date</th>
<th class='text-left'>Merchant</th>
<th class='text-right'>Amount</th>
<th class='text-center'>Expense Type</th>
<th class='text-left'><input type="checkbox" ng-model="selectedAllBill" ng-change="checkAllBillable()" style='margin-right:3px;'/> Billable</th>
<th class='text-center'>Attachment</th>
<th class='text-center'>Description</th>
</thead>
<tbody><tr ng-show='noExpense'><td colspan="8" align="center" style="text-align: center;" >No any Personal Cards!</td>
</tr>
<tr ng-repeat='componentObject in copcards.transactions' ng-class="{'selectedrow':componentObject.corpisSelected}">
<td type='checkbox' class='text-center'><input type='checkbox' ng-model='componentObject.corpisSelected' class='deletebox'/>{{componentObject.corpisSelected}}</td>
<td class='text-left tdwidth'>{{componentObject.transactionDateString | parseDateFormat | date}}</td>
<td class='text-left tdwidth'>{{componentObject.merchant}}</td>
<td class='text-right tdwidth'>${{componentObject.amount}}</td>
<td class='text-center tdwidth'><smart-expense-type></smart-expense-type></td>
<td class='text-left tdwidth'><input type='checkbox' ng-model='componentObject.isBillable'/></td>
<td class='text-center tdwidth'>{{componentObject.hasImage}}</td>
<td class='text-center tdwidth'><input type='text'ng-model='componentObject.description'/></td>
</tr>
</tbody>
</table>
</li>
</ul>
As you can see, I use nasted ng-repeat the loop data, there may be many tables over there, I want each table has his own selectAll function which works independently. Now the code is partly working fine, the problem is if you check the single checkbox in row, the checkall function will not work.I know I need to do something like this:
$scope.checkAllcorp = function() {
if (this.selectedAllcorp) {
$scope.hasSelectedExpense = true
this.selectedRow = true;
this.corpisSelected = true;
} else {
$scope.hasSelectedExpense = false;
this.selectedRow = false;
this.corpisSelected = false;
}
angular.forEach('selectedTable',function(v,k){
v.corpisSelected = this.selectedAllcorp;
})
};
But how can I access this 'selectedTable'?
Pass copcards to your function and then operate on that object instead of this:
ng-change="checkAllcorp(copcards)"
And then in your controller:
$scope.checkAllcorp = function(copcards) {
if (copcards.selectedAllcorp) {
$scope.hasSelectedExpense = true
copcards.selectedRow = true;
copcards.corpisSelected = true;
} else {
$scope.hasSelectedExpense = false;
copcards.selectedRow = false;
copcards.corpisSelected = false;
}
angular.forEach('selectedTable',function(v,k){
v.corpisSelected = copcards.selectedAllcorp;
})
};
you can pass the object you are on by calling it thru the function itself like this
ng-change="checkAllcorp(copcards)
and then use it as a parameter for you checkAllcorp function instead of this in you function
example :
<div ng-repeat="name in names"><button ng-click="msg(name)"></button></div>
controller scope :
$scope.msg = function(name) { alert(name.first)};

Getting AngularJS orderBy to sort both directions

I'm attempting to setup a clickable table column header that sort Ascending when first clicked, and Descending when clicked again. My ascending sort is working fine, but I'm not sure how to setup an expression within my OrderBy to sort Descending
My setup thus far:
Table html has something like
<th ng-click="sort('LastName')">Last Name</th>
My sort method looks like
scope.sort = function (columnName) {
if (angular.isDefined(scope.filter)) {
if (scope.filter.SortColumn == columnName) {
scope.filter.SortColumn = columnName;
scope.filter.SortDirection = scope.filters.SortDirection == "Asc" ? "Desc" : "Asc";
} else {
scope.filter.SortColumn = columnName;
scope.filter.SortDirection = "Asc";
}
}
};
And my ng-repeat looks as follows
<tbody ng-repeat="name in resp.Names | orderBy : filter.SortColumn">
How can I get the SortDirection to factor into the orderBy?
To simply reverse you'd change it to this:
<tbody ng-repeat="name in resp.Names | orderBy : filter.SortColumn : true">
It'd be best if you used a boolean in your controller, but this should work too:
<tbody ng-repeat="name in resp.Names | orderBy : filter.SortColumn : filter.SortDirection === 'Desc'">
And just for fun, here's how I do sorting with filtering in my tables.
Controller:
$scope.search = { query: ''};
$scope.sort = { field: 'defaultField', descending: true};
$scope.order = function(newValue) {
if(newValue === $scope.sort.field) {
$scope.sort.descending = !$scope.sort.descending;
} else {
$scope.sort = {field: newValue, descending: false};
}
};
$scope.filteredDocuments = function() {
var a = $filter('filter')($scope.documents, {$:$scope.search.query});
var b = $filter('orderBy')(a, $scope.sort.field, $scope.sort.descending);
return b;
};
A search box for filtering:
<input type="text" ng-model="search.query">
A column header:
<th nowrap>
<a href ng-click="order('size')">Size </a>
<i ng-show="sort.field === 'size' && !sort.descending" class="fa fa-sort-amount-asc"></i>
<i ng-show="sort.field === 'size' && sort.descending" class="fa fa-sort-amount-desc"></i>
</th>
The row binding:
<tr ng-repeat="d in filteredDocuments()" >
A simplified version of the above answer:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<p>Click the table headers to change the sorting order:</p>
<div ng-app="myApp" ng-controller="namesCtrl">
<table border="1" width="100%">
<tr>
<th ng-click="orderByMe('name')" >Name</th>
<th ng-click="orderByMe('country')">Country</th>
</tr>
<tr ng-repeat="x in names | orderBy:myOrderBy:mySortOrder">
<td>{{x.name}}</td>
<td>{{x.country}}</td>
</tr>
</table>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.names = [
{name:'Jani',country:'Norway'},
{name:'Carl',country:'Sweden'},
{name:'Margareth',country:'England'},
{name:'Hege',country:'Norway'},
{name:'Joe',country:'Denmark'},
{name:'Gustav',country:'Sweden'},
{name:'Birgit',country:'Denmark'},
{name:'Mary',country:'England'},
{name:'Kai',country:'Norway'}
];
$scope.sorts={};
$scope.orderByMe = function(x) {
$scope.myOrderBy = x;
if(x in $scope.sorts) {
$scope.sorts[x]=!$scope.sorts[x];
} else {
$scope.sorts[x]=false;
}
$scope.mySortOrder=$scope.sorts[x];
}
});
</script>
</body>
</html>

Resources