How can I render blank data in specific column if value in object does not match
Data from API
[
{
"parent": "parent1",
"ouid": 1,
"child1": "tom",
"child2": "bob"
},
{
"parent": "parent2",
"ouid": 2,
"child1": "smith",
"child2": "steven"
},
{
"parent": "parent3",
"ouid": 1,
"child1": "mack",
"child2": "jack"
}
]
Column mapping
const defaultColumns = [
table.createDataColumn("parent", {
id: "parent",
}),
table.createGroup({
header: "ouid",
columns: [
table.createDataColumn("child1", {
id: "child1",
}),
table.createDataColumn("child2", {
id: "child2",
}),
],
}),
table.createGroup({
header: "ouid1",
columns: [
table.createDataColumn("child1", {
id: "child1",
}),
table.createDataColumn("child2", {
id: "child2",
}),
],
}),
];
Table Mapping
<table border={1}>
<thead>
{instance.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id} colSpan={header.colSpan}>
{header.isPlaceholder ? null : header.renderHeader()}
</th>
))}
</tr>
))}
</thead>
<tbody>
{instance.getRowModel().rows.map((row) => (
<tr key={row.id}>
{row.getVisibleCells().map((cell) => (
<td key={cell.id}>{cell.renderCell()}</td>
))}
</tr>
))}
</tbody>
</table>
Output
Expected Output
I want different column group to be rendered based on value of 'ouid' and it's child column will always be 'child1','child2'
rest all common column will be filled 'parent' in this case, new column group will be created for another 'ouid' value and so on..., do let me know if I need to alter data from api in a specific way to achieve this.
#tanstack react-table version - 8.0.0-beta.4 (I can't update to latest stable, but can downgrade to v7 if this is achievable by it)
row.getVisibleCells return
What's the return of row.getVisibleCells() look like?
I have data related to the inventory of the different types of items. I need to get the values in a table with the value of parent level repeating till all the child values have been rendered.
the data is
const data = [
{
Category: "IT",
Subcategory: [{
Asset: "Computer",
Specifications: [{ Display: ["LCD"]},
{ RAM: ["8GB", "12GB", "16GB"] },
{ Grapics_Type: ["Dedicated", "Integrated"] },
{ HardDisk: ["500GB", "1TB", "2TB"] },
]
},
{
Asset: "Printer",
Specifications: [{ Type: ["Color", "black&white"] },
{ Memory: ["128MB", "512MB", "1GB"] },
{ Printing_type : ["Dedicated", "Integrated"] },
{ HardDisk: ["500GB", "1TB", "2TB"] },
]
},
{
Asset: "Tablet",
Specifications: [{ Display: ["LCD"] },
{ RAM: ["8GB", "12GB", "16GB"] },
{ Grapics_Type: ["Dedicated", "Integrated"] },
{ HardDisk: ["500GB", "1TB", "2TB"] },
]
},
],
},
{
Category: "NonIT",
Subcategory: [{
Asset: "Table",
Specifications: [{ Color: ["Red", "Green", "Blue"] },
{ Weight: ["5", "7", "10"] },
]
},
{
Asset: "Chair",
Specifications: [{ Spec1: ["val1","val2"] },
{ Spec2: ["val3", "val4", "val5"] },
{ Spec3: ["val6", "val7"] },
]
},
{
Asset: "Fan",
Specifications: [{ Spec4: ["val8"] },
{ Spec5: ["val8", "val9", "val10"] },
{ Spec6: ["val11", "val12"] },
{ Spec7: ["val13", "val14", "val15"] },
]
},
],
},
]
I need to get this data rendered in a table in the format as:
Sl.No.
Category
Asset
Specification
Values
1.
IT
Computer
Display
LCD
2.
IT
Computer
RAM
8GB,12GB, 16GB
3.
IT
Computer
Graphics_Type
Dedicated,Integrated
. .
......
........
...............
.............
.
IT
Printer
Type
Color, black&white
IT
Printer
Memory
128MB,512MB,1GB
. .
. .
. . . .
. . . . . . . .
. . . . . . . . .
. .
. .
. . . . .
. . . . . . .
. . . . . . . . .
.
NonIT
Table
Color
Red, Green, Blue
..
Non IT
Table
Weight
5,7,10
.....
.......
.........
..............
..................
What should be the best way to do it. Do i need to modify the original array (and how to do it?) to contain all the values or directly render it to the table from the original array?
Thanks in advance.
You need to have multiple iterations using array.map() step by step and get appropriate values and bind to table td's .
The level of iteration be like,
-> data
-> Subcategory
-> Specifications
To increase the Sl.No, you can have a global variable as let count = 0 and then assign the increased value like count += 1
Working Example:
const App = () => {
const data = [
{
Category: "IT",
Subcategory: [
{
Asset: "Computer",
Specifications: [
{ Display: ["LCD"] },
{ RAM: ["8GB", "12GB", "16GB"] },
{ Grapics_Type: ["Dedicated", "Integrated"] },
{ HardDisk: ["500GB", "1TB", "2TB"] }
]
},
{
Asset: "Printer",
Specifications: [
{ Type: ["Color", "black&white"] },
{ Memory: ["128MB", "512MB", "1GB"] },
{ Printing_type: ["Dedicated", "Integrated"] },
{ HardDisk: ["500GB", "1TB", "2TB"] }
]
},
{
Asset: "Tablet",
Specifications: [
{ Display: ["LCD"] },
{ RAM: ["8GB", "12GB", "16GB"] },
{ Grapics_Type: ["Dedicated", "Integrated"] },
{ HardDisk: ["500GB", "1TB", "2TB"] }
]
}
]
},
{
Category: "NonIT",
Subcategory: [
{
Asset: "Table",
Specifications: [
{ Color: ["Red", "Green", "Blue"] },
{ Weight: ["5", "7", "10"] }
]
},
{
Asset: "Chair",
Specifications: [
{ Spec1: ["val1", "val2"] },
{ Spec2: ["val3", "val4", "val5"] },
{ Spec3: ["val6", "val7"] }
]
},
{
Asset: "Fan",
Specifications: [
{ Spec4: ["val8"] },
{ Spec5: ["val8", "val9", "val10"] },
{ Spec6: ["val11", "val12"] },
{ Spec7: ["val13", "val14", "val15"] }
]
}
]
}
];
let count = 0;
return (
<div className="App">
<table>
<thead>
<tr>
<th> Sl.No </th>
<th> Category </th>
<th> Asset </th>
<th> Specification </th>
<th> Values </th>
</tr>
</thead>
<tbody>
{data.map(({ Category, Subcategory }, index) => {
return Subcategory.map(({ Asset, Specifications }, j) => {
return Specifications.map((spec, k) => {
return (
<tr key={k}>
<td> {(count += 1)} </td>
<td> {Category} </td>
<td> {Asset} </td>
<td> {Object.keys(spec)} </td>
<td> {spec[Object.keys(spec)].join(",")} </td>
</tr>
);
});
});
})}
</tbody>
</table>
</div>
);
}
ReactDOM.createRoot(
document.getElementById("root")
).render(
<App />
);
table,
th,
td {
border: 2px solid #000;
}
table {
border-collapse: collapse;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
I have been searching for hours how I can translate the values of an object array with the module ngx-translate,
Here is an extract of my code but I don’t know how to implement the json file
Template HTML :
<div class="sort-header-container">
<table matSort class="mat-sort">
<tr *ngFor="let item of items" class="row">
<td class="row">{{item.critere}}</td>
<td>{{item.res}}</td>
</tr>
</table>
</div>
The object array in the service :
items: any[] = [
{ critere: "Code-modèle", res: "Mizuno Shadow 4" },
{ critere: "Code Libellé", res: "KR32" },
{ critere: "Stock", res: 10 },
{ critere: "Prix TTC", res: "Bleu" },
{ critere: "Couleur", res: 42 },
{ critere: "Matière", res: 125 },
{ critere: "Zone", res: 100 },
];
I need to translate only the critere column
Thank you
You need to use the TranslatePipe from ngx-translate.
<div class="sort-header-container">
<table matSort class="mat-sort">
<tr *ngFor="let item of items" class="row">
<td class="row">{{item.critere | translate}}</td>
<td>{{item.res}}</td>
</tr>
</table>
</div>
Make sure your critere field have the corresponding translations in the json translation files
example for en english translation:
{
"Prix TTC": "Price",
"Couleur": "Color",
}
As taken from the example in ngx-translate github
You can use the translate pipe in your code, like this:
<td class="row">{{ item.critere | translate }}</td>
For this to work, your critere would need to be keys in your language file, for example:
{
'Stock': 'Stock english translation',
'Couleur': 'Is this color?'
}
Thank you very much for your answers
Finally here's what I did :
<tr *ngFor="let item_translate of ('PRODUCT.PRODUCT' | translate); let i = index " class="row"
[ngStyle]="item_translate.critere == 'Stock' && stock<0 ?{color:'red'}:{color:'#474646'}">
<td class="row">{{item_translate.critere}}</td>
<td>{{items[i].res}}</td>
</tr>
In my json example fr :
"PRODUCT": {
"PRODUCT": [
{
"critere": "Code-modèle"
},
{
"critere": "Code Libellé"
},
{
"critere": "Stock"
},
{
"critere": "Prix TTC"
},
{
"critere": "Couleur"
},
{
"critere": "Matière"
},
{
"critere": "Zone"
}
]
}
Below is my JSON object and I am trying to show the same in html table.
$scope.results = {
"data": [
{
"name": "Sam",
"details": [
{
"official": [
{
"address1": "Link road",
"pincode": 76755554
},
{
"address1": "K main road",
"pincode": 9766565
}
]
},
{
"name": "John",
"details": [
{
"official": [
{
"address1": "Old college road",
"pincode": 11111
},
{
"address1": "near east side",
"pincode": 6555446
}
]
}
]
}
]
}
]
}
I have used ng-repeat to achieve the below output. But I am not getting the expected result
This is the code which I have tried and got stuck JSFIDDLE
Any idea on how to achieve my expected result will be really helpful.
You may have to tweak this slightly if your data structure can get more complicated when there are more levels, but this should reformat your data and flatten everything into an array of people without all the different levels.
$scope.peopleFlat = [];
function flattenPeople(people) {
people.forEach((person) => {
$scope.peopleFlat.push({
name: person.name,
addresses: person.details[0].official
});
if (person.details.length > 1) {
flattenPeople([person.details[1]]);
}
});
}
flattenPeople($scope.people);
Then you can use a combination of ng-repeat-start and ng-repeat-end to make it work using rowspan instead of a nested <table> element.
<table class="table table-bordered table-condensed">
<tr>
<th>Name</th>
<th>Address</th>
<th>Pincode</th>
</tr>
<tr ng-repeat-start="person in peopleFlat">
<td rowspan="{{person.addresses.length || 1}}">{{person.name}}</td>
<td>{{person.addresses.length ? person.addresses[0].address1 : ''}}</td>
<td>{{person.addresses.length ? person.addresses[0].pincode : ''}}</td>
</tr>
<tr ng-repeat-end ng-repeat="address in person.addresses.slice(1)">
<td>{{address.address1}}</td>
<td>{{address.pincode}}</td>
</tr>
</table>
I have various tables and I'm trying to sort table using https://www.npmjs.com/package/ngx-order-pipe. I followed their documentation and everything works fine except it is not sorting correctly the columns (here in the example, 'Rank' column)
For example I have a response like this:
"collection": [
{
"name": "John",
"age" : "25",
"details": [
{
"final_rank": "150"
}
]
}
{
"name": "Mark",
"age" : "19",
"details": [
{
"final_rank": "254"
}
]
}
Here's my HTML:
<table>
<thead>
<tr>
<th (click)="setOrder('name')">Name</th>
<th (click)="setOrder('age')">Age</th>
<th (click)="setOrder('final_rank')">Rank</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let Data of collection | orderBy: order:reverse:'case-insensitive'">
<td class="text-truncate">{{Data.name}}</td>
<td class="text-truncate">{{Data.age}}</td>
<td class="text-truncate" *ngIf="!isArray(Data.details)">
<tr> {{Data.details.final_rank}} </tr>
</td>
<td class="text-truncate" *ngIf="isArray(Data.details)"><tr *ngFor="let rankData of Data.details"> {{rankData.final_rank}} </tr></td>
</tr>
</tbody>
</table>
component.ts
order;
reverse = false;
isArray(obj: any) {
return Array.isArray(obj)
}
getData() {
this.http.get('**')
.subscribe(data => {
console.log(data);
});
}
setOrder(value) {
if (this.order === value) {
this.reverse = !this.reverse;
}
this.order = value;
console.log(this.order);
}
Your problem seems to be that you try to sort by a field that is inside of an array of the actual object. I suspect that your library doesn't know how to do the sorting (and that probably rightly so). So what you should do is to transform your data in a format, where it can be sorted.
At some point in your application you have the data:
const originalData = [{
'name': 'John',
'age': '25',
'details': [
{
'final_rank': '150'
}
]
},
{
'name': 'Mark',
'age': '19',
'details': [
{
'final_rank': '254'
}
]
}];
Whata you want to do now is to take that data and to convert it to something else. In this example I want to get the max final_rank value of any of the details items. That max value will be used for sorting. You might want to use another way of defining what value to use, but for this example the max value should do fine.
We can use a map function to transform each value of your original data:
const mappedData = originalData.map(item => ({
// This will do a shallow copy of all the fields of the original object
...item,
// With reduce we can easily find the max ```final_rank``` value
maxRank: item.details.reduce(
// +current.final_rank converts the string to a number
(max, current) => +current.final_rank > max ? current.final_rank : max,
0
)
}));
This should yield a new array which should look the same as your original data, except for an additional maxRank field on the root object.
The resulting object would look something like this:
const mappedData = [{
'name': 'John',
'age': '25',
'maxRank': 150,
'details': [
{
'final_rank': '150'
}
]
},
{
'name': 'Mark',
'age': '19',
'maxRank': 254,
'details': [
{
'final_rank': '254'
}
]
}];
Now you should be able to do sorting based on the maxRank field.