table with a tr in it. Now I would like if you click on that table row the backgroundcolor changes. Why I want this is because I am using a tree table to open up this table row. And I would like it if you click on this table row that the background color of the whole row changes. Now if I close this table row (by clicking on it again) I would like that the backgroundcolor goes back to normal
<ng-template pTemplate="header">
<tr>
<th>Bedrijsnaam</th>
<th>Bedrijfstype</th>
<th>Status</th>
<th>Bank</th>
</tr>
</ng-template>
This is the tr I am talking about. I tried using ng-class but without any luck. Does someone know how to do this?
You can use (click) and [ngClass] on the tr.
Ex :
<tr (click)="toggleClass()" [ngClass]="{active: className}">
....
</tr>
in ts
let className = "";
toggleClass(){
if(this.className === "active"){
this.className = ""
}else{
this.className = "active";
}
}
in csss
.active{
background-color: yellow;
}
Note this implemenation is for one tr you may need to attach this className for each row.
This another solution and you don't need to create a property in the component
<tr #tr (click)="tr.classList.toggle('active')" >
....
</tr>
demo
Table.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.css']
})
export class TableComponent {
tableRowClicked = false;
toggleTableRowClicked() {
this.tableRowClicked = !this.tableRowClicked;
}
}
Create an instance variable tableRowClicked to manage whether the table row has been clicked or not.
Create a toggle function to toggle the variable true or false.
Table.component.html
<div>
<table>
<tr (click)="toggleTableRowClicked()" [class.table__row--clicked]="tableRowClicked">
<th>Bedrijsnaam</th>
<th>Bedrijfstype</th>
<th>Status</th>
<th>Bank</th>
</tr>
</table>
</div>
Invoke the toggle function using the click handler on the <tr>
Apply the table__row--clicked class when tableRowClicked=true
Table.component.css
.table {
&__row {
&--clicked {
background-color: red;
}
}
}
CSS to make the background-color: red; when the tableRowClicked = true
Related
I am trying to select all table cells that have colSpan or rowSpan bigger than 1. I know that you can do querySelectorAll('td[colspan="3"]') to select cells that meet a narrower condition.
But I need something like querySelectorAll('td[colspan>"1"]').
It is not possible to put conditional operator inside the querySelector. In your case, if you want to achieve it using only CSS selector then you can ignore the particular colspan condition and select the remaining using :not operator.
td[colspan]:not(td[colspan = "1"]) {
background : red;
}
table, th, td {
border: 1px solid black;
}
td[colspan]:not(td[colspan = "1"]) {
background : red;
}
<table>
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
<tr>
<td colspan="1">January</td>
<td>$100</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
<tr>
<td colspan="2">Sum: $180</td>
</tr>
</table>
According to this link : https://bobbyhadz.com/blog/javascript-get-all-elements-by-data-attribute#get-all-dom-elements-by-partial-match-of-a-data-attribute
you can get elements with data-attribute starts with, ends with or contains with something like below:
// ✅ Get all where value of data-id starts with `bo`
const elements1 = document.querySelectorAll('[data-id^="bo"]');
console.log(elements1); // 👉️ [div, div]
// ✅ Get all where value of data-id ends with `ox1`
const elements2 = document.querySelectorAll('[data-id$="ox1"]');
console.log(elements2); // 👉️ [div]
// ✅ Get all where value of data-id contains with `box`
const elements3 = document.querySelectorAll('[data-id*="box"]');
console.log(elements3); // 👉️ [div, div]
in your case you can do something like that:
const getAllTdColspanBiggerThanOne= (a) => {
for (let i in a) if (a.hasOwnProperty(i)) {
if (a[i].getAttribute('colspan') > 1) {
alert(a[i].getAttribute('colspan'));
}
}
}
const td = document.querySelectorAll("td[colspan]") // or document.querySelectorAll("[colspan]")
const tdColspanBiggerThanOne = getAllTdColspanBiggerThanOne(td)
I am running into issues in getting the alternate rows with 2 different colors. I have a JSON data coming from backend, which is a dynamic array of objects. I need to show the data in the table as in the example here:
https://stackblitz.com/edit/create-xpkbjm?file=app/app.component.html
The odd, even rule that I find in most Stackoverflow questions doesn't seem to work here.
I would like to show the rows with alternate colors(the rows come as groups). The data should be presented similar to the link in the above stackblitz, but each rows should have alternate color. The odd, even rule only work for each group, but doesn't alternate the color in the table as a whole.
You can do this with plain old css,
tr:nth-child(2n) {
background: lightgray;
}
You can update the object that you're using to loop over and create the table.
Currently, you're using two loops,
one over tbody with groups
and one over tr with group.events
Instead, you can create another variable that is a list of events,
// app.component.ts
events = this.groups.map(g => g.events).flat();
Which simplifies your HTML to,
<!-- app.component.html -->
<tr *ngFor="let event of events; index as i">
<td>
{{event.event}}
</td>
</tr>
Check on stackblitz
UPDATE:
You can track total elements using a group/count property on each event across the whole object like so,
//app.component.ts
constructor() {
this.createGroups();
}
createGroups() {
let count = 0;
this.groups.forEach(g => {
g.events.forEach(e => {
e.group = count++;
});
});
console.log(this.groups);
}
And then use [ngClass] to bind a css class based on this property,
<tbody>
<tr *ngFor="let group of groups; index as i">
<table>
<tbody>
<tr *ngIf="i!==0">
<td></td>
</tr>
<tr *ngFor="let event of group.events;" [ngClass]="{'even': event.group % 2 !== 0}">
<td>{{event.event}} {{event.group}}</td>
</tr>
</tbody>
</table>
</tr>
</tbody>
Updated stackblitz
You can do this using pure CSS without the need to modify the angular.
tbody tr
{
background-color: #FFFFFF;
color: #fff;
}
tbody tr:nth-child(odd)
{
background-color: #000000;
color: #fff;
}
I have an Angular 2 App using the Kendo UI Grid. There I have a Grid showing some data (integer values). Is it possible, to colorize each cell according to it's type? Maybe adding css class to each cell based on the type?
right now, the data looks like this [{"a":4,"b"=35,...},{...},....] I also have types for each element but not yet saved in the data grid.
I have a suggestion it's still in form of pure js kendo (but you should be able to do it in angular 2 kendo), by using schema.parse or in angular 2 : after getting data from backend you could add additionals field in the after retrieving your data from rest endpoint. add your logic inside the looping in my case i just assign color at random
schema: {
parse : function(response){
var colors = [
'red',
'green',
'blue',
'yellow'
];
//loop through all you data, add adding aditional field.
//also here i randomize the color for each cell
for(var i = 0; i< response.d.results.length; i++){
response.d.results[i].cell1 = colors[ Math.floor(Math.random()*colors.length)];
response.d.results[i].cell2 = colors[ Math.floor(Math.random()*colors.length)];
response.d.results[i].cell3 = colors[ Math.floor(Math.random()*colors.length)];
response.d.results[i].cell4 = colors[ Math.floor(Math.random()*colors.length)];
}
return response
}
}
Then on the row template you could use it as class like this (look at the cell1,cell2,cell3,cell4 attribute) in kendo-angular2 reference detail row template :
<script id="rowTemplate" type="text/x-kendo-tmpl">
<tr data-uid="#: uid #">
<td class="photo #=data.cell1#">
<img src="../content/web/Employees/#:data.EmployeeID#.jpg" alt="#: data.EmployeeID #" />
</td>
<td class="details #=data.cell2#">
<span class="name">#: FirstName# #: LastName# </span>
<span class="title">Title: #: Title #</span>
</td>
<td class="country #=data.cell3#">
#: Country #
</td>
<td class="employeeID #=data.cell4#">
#: EmployeeID #
</td>
</tr>
</script>
then add the css
<style>
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
</style>
Working example in dojo
I need to change the text color of some elements inside TD based on conditions.
My Angular table is :
<table ng-table="employeesList" show-filter="true" class="table table-striped table-bordered">
<tr ng-repeat="employee in $data">
<td data-title="'#'">{{$index + 1}}</td>
<td data-title="'First Name'" sortable="'firstName'" filter="{ 'firstName': 'text' }">
{{employee.employee.firstName}}
</td>
<td data-title="'Current State'" sortable="'currentState'" ng-class="{ red: employee.state.state == 'Available'}">
{{employee.state.state}}
</td>
</tr>
</table>
In the above table, the color of text inside TD with title 'Current state' will change to Red if the condition (employee.state.state == 'Available') is true.
My CSS file :
.red {
color: red;
}
.blue {
color:blue;
}
Similarly I want to have a different color for the same TD if another condition is true.
ie, if (employee.state.state == 'Blocked'), I want the text to be in blue color. I have more than 3 states and want a different color for each of the state, so a simple If else won't work.
How can I achieve this?
Thanks in advance...
Try to move this logic into controller:
<td ng-class="calculateClass(employee)">
and in the controller:
$scope.calculateClass = function(employee) {
var classNames = [];
switch (employee.state.state) {
case 'Available':
classNames.push('red');
break;
case 'Blocked':
classNames.push('blue');
break;
default:
break;
}
return classNames;
}
What you want is something like this:
<td ng-class="employee.state.state == 'Available' ? 'red' : 'blue'">{{employee.state.state}}</td>
If you want more options, you can always extend the operator like so:
<td ng-class="(employee.state.state == 'Available') ? 'red' : (employee.state.state == 'Blocked') ? 'blue'">{{employee.state.state}}</td>
A third and better option would be to write a function here and move the logic to the controller:
<td ng-class="chooseClass">{{employee.state.state}}</td>
// Controller
$scope.chooseClass = function(employee) {
switch(employee.state.state) {
case 'Available':
return 'red';
break;
:
:
default:
return 'white';
}
}
If you prefer one line solution, then:
ng-class="{'Available': 'red', 'Blocked': 'blue'}[employee.state.state]"
should do the trick
How can I add a background-color to every second table row even some table rows are not displayed?
In my HTML is a simple table with some table rows. Just like that:
<label for="cb">hide blue</label>
<input id="cb" type="checkbox" onchange="hideBlue(this.checked)" />
<table>
<tr data-cat="red">
<td>red car</td>
</tr>
<tr data-cat="blue">
<td>blue jacket</td>
</tr>
<tr data-cat="red">
<td>red bull</td>
</tr>
<tr data-cat="red">
<td>red pen</td>
</tr>
</table>
As you can see there is also a checkbox which can toggle the "blue" category-rows.
My CSS is looking like that:
tr:nth-child(odd) {
background-color:#aaa;
}
But now if someone hides the "blue" category (by adding a display:none-class), the background colors are not alternate right anymore.
How can I prevent this failure?
I already tried to add :not(.displaynone) to the css rule but this didn't work.
Here is a jsFiddle
There is a way to get the updating alternating row colors using only CSS selectors.
tr:nth-child(odd) {
background-color:#aaa;
}
tr.displaynone ~ tr {
background-color: transparent;
}
tr.displaynone ~ tr:nth-child(even) {
background-color:#aaa;
}
What this does is it sets all siblings after the displaynone row background-color to transparent, and then sets the even rows after that background-color to #aaa.
This works for your example fiddle (forked here), but it will not work if you have to hide more than one element at once. (example, comment out the marked line and click on rows).
If you need to hide multiple rows at once, this solution will not work for you, and you'd have to use javascript to compute the row color whenever you hide/show rows.
As per your requirement only jquery can solve your problem. Even one <tr> is hidden the background color will be in sequence. Check DEMO.
Here is the jQuery Code.
$(document).ready(function(){
$("tr[data-cat='red']:even").css({'background':'red'});
$("tr[data-cat='red']:odd").css({'background':'orange'});
$("tr:not([data-cat='red'])").css({'background':'blue'});
});
You haven't tagged jQuery, but I'm giving you it as an alternative anyways (also for other users who might stumble upon the same problem).
function loopTable() {
var x=0;
$("table>tbody>tr").each(function() {
if( $(this).is(":visible") ) {
if( x%2==0 )
$(this).addClass('red');
else
$(this).removeClass('red');
x++;
}
});
}
This function should be called on body load, and everytime the table is altered. Or on interval.
DEMO.