How to highlight table row based on condition in angularJs? - 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/

Related

How do I add an icon within a td at the end of each row using ng-repeat?

I have a 2-dimensional array.
I am using it as a source to populate an html table using angularjs ng-repeat.
I want to add an icon at the end of each row.
It works on the first two rows, but then the next several rows contain only the icon.
<div ng-app="myApp" ng-controller="tblCtrl">
<table id="tableToFilter" class="w3-table-all w3-small w3-row" ng-cloak>
<tr class="w3-blue w3-mobile">
<th data-row="0" data-col="{{$index}}" ng-repeat="columns in header">{{columns}}</th>
<th></th>
</tr>
<tr class="w3-mobile" ng-show="{{$index > 0}}" ng-repeat="rows in table">
<td data-row="{{$parent.$index}}" data-col="{{$index}}" ng-repeat="columns in rows">{{ columns }}</td>
<td><i class="material-icons editIcon">edit</i></td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('tblCtrl', function($scope) {
$scope.table = datags;
$scope.header = datags[0];
});
</script>
'datags' above is a 2-dimensional array in json.stringify format.
It does not have key/value pairs.
It is 94 rows and 9 columns. I am using css to prevent displaying columns 0,4,7,8 so that my table fits on my screen. (I'm sure there's a cleaner way to do this.)
<style>
td[data-col="0"], th[data-col="0"] {
display: none;
}
td[data-col="4"], th[data-col="4"] {
display: none;
}
td[data-col="7"], th[data-col="7"] {
display: none;
}
td[data-col="8"], th[data-col="8"] {
display: none;
}
</style>
screenshot of my table
What am I doing wrong?
I did figure it out. I think ng-repeat was perceiving the blanks as duplicates. I added track by $index and now it works. <tr class="w3-mobile" ng-show="{{$index > 0}}" ng-repeat="rows in table track by $index"> <td data-row="{{$parent.$index}}" data-col="{{$index}}" ng-repeat="columns in rows track by $index">{{ columns }}</td> <td><i class="material-icons editIcon">edit</i></td> </tr>

Angular Js swap columns in table

I would like to swap 2 columns in a table. Finally, I succeeded the change, but only the data. The attributes of the cell (style, id, class) didn't move. I tried to move attributes with jquery (i know, not an elegant method), but it was only symptomatic treatment. After clicking the data reload button, the attributes restored.
How can I change the columns order with all attributes?
my code: https://codepen.io/qwertz_/pen/YxWMBO
<!DOCTYPE html>
<html>
<head>
<title>angT</title>
<script type="text/javascript" src="http://code.angularjs.org/angular-1.0.0rc10.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<style>
th, td{padding: 3px 20px;border: 1px solid red;}
</style>
</head>
<body>
<div ng-controller="MyCtrl" ng-app="myApp">
<button ng-click="swap(0)">first2second</button>
<button ng-click="reload()">reload</button>
<table id="myTable" >
<tr ng-repeat="row in ths">
<th class="oo1">{{col(row, 0)}}</th>
<th class="oo2">{{col(row, 1)}}</th>
<th class="oo3">{{col(row, 2)}}</th>
<th class="oo4">{{col(row, 3)}}</th>
</tr>
<tr ng-repeat="row in rows">
<td class="o1" style="background-color:yellow;">{{col(row, 0)}}</td>
<td class="o2" style="background-color:pink;">{{col(row, 1)}}</td>
<td class="o3" style="background-color:green;">{{col(row, 2)}}</td>
<td class="o4" style="background-color:blue;">{{col(row, 3)}}</td>
</tr>
</table>
</div>
<script type='text/javascript'>
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.mycol = new Array();
$scope.mycol[0] = 'id';
$scope.mycol[1] = 'name';
$scope.mycol[2] = 'db';
$scope.mycol[3] = 'let';
$scope.reload = function()
{
$scope.rows=[{id:parseInt(Math.random()*10000),name:"Liv","db":21,let:"r"},{id:parseInt(Math.random()*10000),name:"Mike",db:30,let:"u"}];
};
$scope.swap = function(i) {
var temp = $scope.mycol[i];
$scope.mycol[i] = $scope.mycol[(i+1)];
$scope.mycol[(i+1)] = temp;
};
$scope.col = function(row, mycol) {
return row[$scope.mycol[mycol]];
};
$scope.reload();
$scope.ths=[{id:"id",name:"name","db":"db",let:"letter"}];
}
</script>
</body>
Thx a lot
Simple way
You can bind colors to header name as:
$scope.styles = {
id: "yellow",
name: "pink"
};
and table will look like:
<tr ng-repeat="row in rows">
<td class="o1" ng-style="{'background-color':styles[mycol[0]]}">{{col(row, 0)}}</td>
<td class="o2" ng-style="{'background-color':styles[mycol[1]]}">{{col(row, 1)}}</td>
<td class="o3" style="background-color:green;">{{col(row, 2)}}</td>
<td class="o4" style="background-color:blue;">{{col(row, 3)}}</td>
</tr>
Once header value changes, colors will change too
Codepen DEMO
More complicated but generic
You can achieve it by replacing all table with directive (headers + data) and by using $compile rebuild all HTML table.

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

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

highlight table row using angularjs

how to highlight a table row using angularjs. i tried in the following way but it is highlighting all rows.
I have a table in the following way,
<table>
<tr>
<th>header1</th>
<th>header2</th>
</tr>
<tbody data-ng-repeat="transaction in transactionsgroup">
<tr data-ng-click="rowHighilited($index)" data-ng-repeat="txns in transaction.transactions" data-ng-class='{selected: $index==selectedRow}'>
<td>xxxxxx</td>
<td>xxxxxx</td>
</tr>
</tbody>
</table>
controller,
$scope.rowHighilited = function(row){
$scope.selectedRow = row;
};
Is this what you are looking for ? I had to guess some mock data and also the selection behavior.
Feel free to ask for more details if this solution suites you well.
function TestCtrl($scope){
$scope.rowHighilited = function(group, row){
$scope.selectedGroup= group;
$scope.selectedRow = row;
};
$scope.transactionsGroups=[
{transactions:['test1','test2','test3']},
{transactions:['test1','test2']},
{transactions:['test1','test2']},
]
}
.selected{
background:black;
color:white;
}
/* The following just makes the tbody tags spaced up,
see http://stackoverflow.com/questions/294885/how-to-put-spacing-between-tbody-elements for details */
table {
border-collapse: collapse;
width:100%;
max-width:300px;
}
table tbody {
border-top: 30px solid white;
}
td,th{width:50%; text-align:center;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="TestCtrl">
<pre ng-bind="{{transactionsgroups}}"></pre>
<table>
<tr>
<th>header1</th>
<th>header2</th>
</tr>
<tbody
ng-repeat="transactionGroup in transactionsGroups"
ng-init="groupIndex=$index"
>
<tr
ng-repeat="transaction in transactionGroup.transactions"
ng-init="transactionIndex=$index"
ng-click="rowHighilited(groupIndex, transactionIndex)"
ng-class="groupIndex==selectedGroup && transactionIndex==selectedRow?'selected':''">
<td>transaction:</td>
<td>{{transaction}}</td>
</tr>
</tbody>
</table>
</div>
<div ng-app="myApp">
<div ng-controller="startCtrl">
<table>
<tr>
<th>header1</th>
<th>header2</th>
</tr>
<tbody data-ng-repeat="transaction in transactionsgroup">
<tr ng-class="{active:$index==selectedRow}" data-ng-click="rowHighilited($index)" data-ng-repeat="txns in transaction.transactions">
<td>{{txns.id}}</td>
<td>{{txns.trasactionName}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Your Controller.
var app=angular.module("myApp",[]);
app.controller("startCtrl",function($scope){
$scope.transactionsgroup=[
{id:1,
transactions:
[{id:1,trasactionName:"a"},
{id:2,trasactionName:"b"},
{id:3,trasactionName:"c"}
]}
];
$scope.rowHighilited=function(row)
{
$scope.selectedRow = row;
}
});
Your .css
.active{
background:yellow;
border:1px solid;
}
Working Fiddle Link
http://jsfiddle.net/Lk4me2xp/1/
This is my custom easy solution.
i tried in the following way but it is highlighting all rows
It's because you are setting common scope property which is shared by all rows. You should set selectedRow in the scope of the individual clicked row. You can refer row child scope with this inside ngClick:
$scope.rowHighilited = function(row) {
this.selectedRow = true;
// or if you also want to unselect on the second click
// this.selectedRow = !this.selectedRow;
};
and then:
data-ng-class='{selected: txns.selectedRow}'

Dragging a table column using HTML5 and AngularJS

http://jsfiddle.net/asutosh/82qum/
<div ng-app='myApp'>
<div ng-controller="myCtrl">
<table border="4">
<thead>
<th ng-repeat="hd in heads">
<div draganddrop drag="handleDrag()">{{hd}}</div>
</th>
</thead>
<tr ng-repeat="row in myData">
<td ng-repeat="hd in heads">
{{row[hd]}}
</td>
</tr>
</table>
</div>
Here is the JS:
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',function($scope){
$scope.handleDrag=function()
{
}
$scope.heads=['name','age','company','tech'];
$scope.myData=[{name:'Jay',age:27,company:'XYZ',tech:'Js'},
{ name:'Rayn',age:30,company:'XYZ',tech:'.net'}]
});
myApp.directive('draganddrop',function(){
return{
scope:{
drag:'&'
},
link: function(scope, element) {
// this gives us the native JS object
var el = element[0];
el.draggable=true;
el.addEventListener(
'dragstart',
function(e) {
e.dataTransfer.effectAllowed = 'move';
// this.classList.add('drag');
return false;
},
false
);
el.addEventListener(
'dragend',
function(e) {
this.classList.remove('drag');
return false;
},
false
);
}
};
});
In the above fiddle I want to create a table having column reordering, I am able to set the column header to draggable however while dragging only the header's image is getting dragged, I want the the image of the whole column should come as the dragging image, any suggestion on that will be helpful.
The following solution works with Chrome's latest version, and this solution is implemented using AngularJS 1.4 version:
The change in the code is:
var headerElem=e.target.closest('th');
var textOfHeader=angular.element(headerElem).find("a");
scope.$apply(function() {
scope[dropfn](data, textOfHeader[0]);
});
http://plnkr.co/VDygHR
If you want to use a plugin instead of implementing it yourself you can choose from:
http://ng-table.com/
http://ui-grid.info/
http://lorenzofox3.github.io/smart-table-website/
http://ekokotov.github.io/object-table/
They all support column reorder and a lot of other features, I believe there are a lot of other solutions around.
http://jsfiddle.net/asutosh/82qum/142/
Following is HTML Code:
<div ng-app='myApp'>
<div ng-controller="myCtrl">
<table ng-hide={{dragStart}} id="hidtable" border="4" >
<thead>
<th>{{dragHead}}</th>
</thead>
<tr ng-repeat="row in myData">
<td>{{row[dragHead]}}</td>
</tr>
</table>
<div class='dragstyle' id="coverup"></div>
<table border="4">
<thead>
<th ng-repeat="hd in heads">
<div draganddrop drag="handleDrag">{{hd}}</div>
</th>
</thead>
<tr ng-repeat="row in myData">
<td ng-repeat="hd in heads">
{{row[hd]}}
</td>
</tr>
</table>
</div>
</div>
Following is the CSS:
.dragstyle{
background: white;
width:200px;
color:white;
height: 100px;
position: absolute;
top: 0;
right: 0;
z-index: 2;
}
#hidtable{
height: 100px;
position: absolute;
top: 0;
right: 0;
z-index: 2;
}
Following is the JS:
var myApp=angular.module('myApp',[]);
myApp.controller('myCtrl',function($scope){
$scope.handleDrag=function(columnName)
{
$scope.dragHead=columnName;
};
$scope.dragHead='name';
$scope.heads=['name','age','company','tech'];
$scope.myData=[{name:'Jay',age:27,company:'XYZ',tech:'Js'},
{name:'Rayn',age:30,company:'XYZ',tech:'.net'}]
});
myApp.directive('draganddrop',function(){
return{
scope:{
drag:'='
},
link: function(scope, element,attrs) {
var el = element[0];
el.draggable=true;
el.addEventListener(
'dragstart',
function(e) {
e.dataTransfer.effectAllowed = 'move';
var columnName=e.target.innerHTML;
scope.$apply(function(self){
console.log(self);
scope.drag(columnName);
});
e.dataTransfer.setDragImage(document.getElementById('hidtable'), 0, 0);
;
return false;
},
false
);
el.addEventListener(
'dragend',
function(e) {
this.classList.remove('drag');
return false;
},
false
);
}
};
});
So this way I have created a box with width of 200px and having background color as white, under that the 'hidetable' element is present, so it's visible to the browser but not to the user.
When the drag event occurs at any column head element, the 'hidetable' element is set as the drag image.
This drag'n'drop library will do it for you:
https://github.com/lorenzofox3/lrDragNDrop
Just include it in your app, and make your <th> say this:
<th lr-drag-src="headers" lr-drop-target="headers" ng-repeat="hd in heads" >

Resources