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
Related
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;
}
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
I'm pretty new to Vue and I love it so far. However, I've encountered the following problem and I'll be thankful for any suggestions on how to get around it.
I would like to iterate recursively on an objects to get a nested table.
I have this template:
<script type="text/x-template">
<tr>
<td><a v-on:click="toggle">[+]</a></td>
<td>...</td>
</tr>
<tr is="row-item" v-show="open" ...></tr>
</script>
It's recursive, so each line tr has an other hidden line tr below.
When the user click on the [+] on the parent line, the children lines will appear.
I already try to wrap the content within a tbody tag, but then I get tbody inside tbody, which is still an illegal table layout and breaks it.
<script type="text/x-template">
<tbody>
<tr>
<td>...</td>
<td>...</td>
</tr>
<tr is="row-item" ...></tr>
</tbody>
</script>
Fiddle: https://jsfiddle.net/rafi16d/puwcs9ay/
Vue#1.x doesn't require exactly one root element. How can I do without ?
Has anyone run into anything similar?
Thanks.
(Sadly) Vue2 imperatively needs a real root element for each component.
So from that I think you don't have so many possibilities:
Do two components instead of a single one, and iter both of them with a virtual node:
<table>
<tbody>
<template for="row in someRows">
<tr>mainRow</tr>
<tr>subRow</tr>
</template>
</tbody>
</table>
Forget the idea to do a real table. Emulate the layout by using <div> and the related display css properties instead.
Alright i managed to do it. Red borders are for you to see the structure, you may want to adjust the padding.
https://jsfiddle.net/guanzo/puwcs9ay/9/
Several hacks, and ideas i borrowed from how jQuery Datatables does nested rows:
You can put pretty much anything in a td. So make the root element a tr, nest a td with colspan 100%, then you can nest a table. Since you can put tr inside of table, the recursion begins.
tr -> td -> table -> tr -> td -> table ad infinitum
<td colspan="42">
42, or any number that's definitely higher than your column count, is basically equivalent to colspan="100%".
You also can - and probably should - use the length of your array to give the colspan the correct number of columns, i was just lazy.
Inner trs have their default css changed.
.inner-tr{
display: table;
width:100%;
}
If you flatten the tree (normalize it) in a computed property, then you can render the HTML table without recursion within the component itself, and thus avoid hacking or generating invalid HTML.
Vue.component('tree-table-row', {
data() {
return {
indent: 20,
left_padding: 5
};
},
props: ['node'],
template: '#tree-table-row'
});
var app = new Vue({
el: '#tree-as-table',
data: {
tree: {
id: 0,
value: "fruits",
name: "root",
children: [
{
id: 1,
name: "A",
children: [{
id: 2,
name: "B",
value: "banana"
}],
value: "apple"
},
{
id: 3,
name: "C",
children: [{
id: 4,
name: "D",
value: "durian"
}],
value: "cherry"
}
]
}
},
computed: {
tree_array() {
return this.normalizedTree(this.tree, 0);
}
},
methods: {
normalizedTree(node, level) {
var _this = this;
var normal_element = {id: node.id, name: node.name, value: node.value, level: level};
var array_fragment = [normal_element];
if (node.children && node.children.length > 0) {
var i;
for (i=0; i < node.children.length; i++) {
array_fragment = array_fragment.concat(_this.normalizedTree(node.children[i], level+1));
};
}
return array_fragment;
}
}
});
.vue-table {
border-collapse: collapse;
font-family: sans-serif;
}
td {
border: 1px solid lightgrey;
padding: 2px 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script type="text/x-template" id="tree-table-row">
<tr>
<td :style="{'padding-left': node.level * indent + left_padding + 'px'}">{{node.name}}</td>
<td>{{node.value}}</td>
</tr>
</script>
<div id="tree-as-table">
<table class="vue-table">
<tr is="tree-table-row" v-for="(node, index) in tree_array" :node="node" :key="node.id"/>
</table>
</div>
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
I have a huge css file (Content/Site.css) which includes also more than 200 lines of spirits.
I wanna make a View/PartialView which shows all my sprites images ( many divs ) .
How I do it?
How to read and parse css file in code behind from a controller and then put my result into a ViewBag?
Or there is no need to parse from server side and just show it from client side?
div.feedImgPop,
div.feedImg,
div.feedImgList { background: url("http://xxx/Sprite.jpg") top left no-repeat; }
div.a{ background-position:0 0; }
div.b{ background-position:0 -43px; }
... 200 lines..
asp net mvc 4.5
Update :
Splited CSS file into 2 files , sprite and the rest
Used CSS Parser to read the sprite css file from a controller
Show the sprite images as shown below
I used this css parser
Controller :
public ActionResult Admin()
{
parser.ReadCSSFile(Server.MapPath("~/Content/Sprite.css"));
var cssItems = new List<String>(cssList.Count);
foreach (var item in cssList) cssItems.Add(item.Key.Replace("div.", ""));
ViewBag.items = cssItems;
return View();
}
View : ( CSS Solution - I use this )
<div class="wrapper">
<div class="container">
#foreach (var item in ViewBag.items)
{
string className = "imgContainer imgHover feedImgPop " + #item;
<div class="#className" onClick="adminChooseSpriteImage('#className')"></div>
}
</div>
</div>
View : (Table Solution - 10 items each row ; previous test )
<div id="feedsContainer">
#{
int rowNumber = 1;
<table>
<tr>
#foreach(var item in ViewBag.items)
{
if (rowNumber % 11 == 0)
{
<tr></tr>
}
else
{
string className = "imgContainer imgHover feedImgPop " + #item;
<td><div class="#className"></div></td>
}
rowNumber++;
}
</tr>
</table>
}
</div>