How to create a row with one cell in a expandible react table? - react-table

I want to use useExpanded to create a subrow that stretches along all columns, similar to the screenshot. In the react table example it only provides expanded rows with the same columns like the table header.
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
state: { expanded }
} = useTable(
{
columns: userColumns,
data
},
useExpanded // Use the useExpanded plugin hook
);

You need to set the html colspan attribute on the td element to the number of cells in the row.
<tr>
<td colspan="3">Extra: cdd</td>
</tr>
Here is a good starting point. See the CSB
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{!row.canExpand && <td colSpan={3}>{row.cells[1].value}</td>}
{row.canExpand &&
row.cells.map((cell) => {
return (
<td {...cell.getCellProps()}>{cell.render("Cell")}</td>
);
})}
</tr>
);
})}
</tbody>

Related

How to pre process the key inside loop and show it as label in Vue 3

I want to loop through the following json object:
 
{countryId: 1, countryName: 'Bangladesh4', countryShortName: 'BD4', authStatus: 'U', createdBy: 'nasir', …}
I want to show this json object as follows:
Country Id: 1
Country Name: Bangladesh
and so on. Actually I need to add a space at every capital letter of a camel case word and make the first letter capital. How can I do this in vue 3?
My try:
<table>
<tbody>
<tr v-for="(value, key) in data">
<th>{{ key }} </th>
<td>{{ value }}</td>
</tr>
</tbody>
</table>
I have not tested this code. But I would create a computed property, which creates an object with the correct labels based on the keys in the data:
const labels = computed(() => {
const newLabels = {}
data.forEach(item => {
Object.key(key => {
newLabels[key] = key.replace( /([A-Z])/g, " $1" );
})
})
return newLabels;
})
The object created should look like this: {countryId: 'country Id', countryName: 'country Name', ...}. It is flexible as it will run over all objects in the data array, collecting and converting all possible keys. Downside may be performance when you have a huge array. If all keys are the same for the objects in data, you also just might create a labels object manually.
Now you can use this in your template:
<th style="text-transform: capitalize;">{{ labels[key] }} </th>
I added the style to transform the first letter to a capital.
As said, I did not have an opportunity to test this, but I hope it helps you any further.
you can display name as below
<table>
<tbody>
<tr v-for="(value, key) in data">
<th v-if="key=='countryId'">Country Id</th>
<th v-if="key=='countryName'">Country Name</th>
...
<td>{{ value }}</td>
</tr>
</tbody>
</table>

set min width on <td> in a reactstrap Table

I have searched for a solution with no avail. I need to set a minimum width on my RESPONSIVE table columns in a Table imported from reactstrap.
This table is always going to have a DYNAMIC amount of columns. I have a select as my <th> and I want to set the to a minimum width so users can obviously read the select options.
Here is my component below
import React, { Fragment, useState, useContext, useMemo } from 'react';
import { CustomInput,Input, Table} from 'reactstrap';
const TableComponent = ({ register, errors, watch }) => {
const TableRow = ({ data }) => (
<tr className="align-middle">
{data.map((customer, index) => (
<td className="text-nowrap" key={index}>{customer}</td>
))}
</tr>
);
return (
<Fragment>
<Table responsive bordered striped hover>
<thead>
<tr>
{
fileContacts.map((contact, index) => (
<th className="bg-primary pr-1 pl-1 pt-2 pb-2" scope="col" key={index}>
<Input
type="select"
className="fs--1"
name="selectHeader"
id="selectHeader"
>
<option>First name</option>
<option>Last name</option>
<option>Email</option>
</Input>
</th>
))}
</tr>
</thead>
<tbody>
{
upload.contacts.slice(0, 10).map((customer, index) => (
<TableRow data={customer} key={index}/>
))
}
</tbody>
</Table>
</Fragment>
);
};
export default TableComponent;
Here are two images. These are what it looks like on mobile or smallest laptop size
Here is the solution. In the TableRow component that is being rendered in the body, you need to add a style prop to the <td>
Note: this must be an object within jsx brackets or else you will get an error.
Here is a copy of the TableRow
const TableRow = ({ data }) => (
<tr className="align-middle">
{data.map((customer, index) => (
<td style={{minWidth: 150}} key={index}>{customer}</td>
))}
</tr>
);
Here was my expected output

Vue JS unable to properly show data table (v-for)

i'm trying to show a table of data that is coming from Firebase Firestore, i've already managed to put all data into a array, but when i try to show that content, the entire array shows up instead of the single items, see the image:
And heres my code:
<template>
<v-simple-table>
<template v-slot:default>
<thead>
<tr>
<th class="text-left">
Name
</th>
<th class="text-left">
Calories
</th>
</tr>
</thead>
<tbody>
<tr
v-for="(item, index) in result"
v-bind:key="index"
>
<td>{{ result }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</template>
<script>
import firebase from 'firebase'
import {db} from '../service/firebase'
export default {
data () {
return {
userName: null,
result: [],
name: null,
email: null,
userMail: null,
telefone: null,
userPhone: null,
userAccept: null,
}
},
async created() {
var userData = []
await db.collection("users").get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data()}`);
userData.push(doc.data())
});
});
this.result = userData.map(a => a.name)
console.log(result)
}
}
</script>
How do i show a table of single items of the array instead of a table of arrays?
Thank you in advance!
You're printing the whole content using {{result}}, the right syntax is the following :
<tr v-for="(item, index) in result" v-bind:key="index" >
<td v-for="(record,i) in item" :key="i">{{ record }}</td>
</tr>

How can I assign different colors to disabled columns in Mat-Table?

i have disabled several columns in my table and want to display them in different colors. Therefore I wrote a function in Typescript where CSS is changed via the class .disabledRange. I have read that you can solve it with [ngClass]... I have an array with three columns: first, second, third. How can I leave the columns disabled and still style them in different colors? In my case I don't know how to use it in the most useful way. I would be grateful for help :)
My code:
// Template
<td mat-cell *matCellDef [class.disabledRange]="column.disabledRange">
...
</td>
// Array
private displayedColumns: EditColumns[] = [
{ attribute: 'first', name: 'MyFirstCol', object: null, disabledRange: false },
{ attribute: 'second', name: 'MySecondCol', object: null, disabledRange: false },
{ attribute: 'third', name: 'MyThirdCol', object: null, disabledRange: false }
];
// Set columns disabled
private disabledColumns(attributeName: string) {
if (attributeName) {
const displayedColumn = this.displayedColumns.find((c) => c.attribute === first);
if (displayedColumn) {
displayedColumn.disabledRange = !displayedColumn.disabledRange;
const columnIndex = this.columns.findIndex((c) => c === attributeName);
}
}
ngAfterViewInit() {
// To disabled columns
this.disabledColumns('first');
this.disabledColumns('second');
this.disabledColumns('third');
}
// Style
// When ranges are disabled in the data table
.disabledRange {
background-color: #eae9e9;
color: #000000;
}
you can use together [class.disabledRange]="condition" and [ngClass], e.g. if you has some like
.col0,.col1,.col2,.col3
{
padding-left: .5rem
}
.col0
{
background-color: silver
}
.col1
{
background-color: yellow
}
.col2
{
background-color: red;
color:white;
}
You can use
<ng-container *ngFor="let col of defColumns;let i=index" [matColumnDef]="col.name">
<th mat-header-cell *matHeaderCellDef [class.disabledRange]="col.disabledRange" [ngClass]="'col'+i">{{col.attribute}} </th>
<td mat-cell *matCellDef="let element" [class.disabledRange]="col.disabledRange" [ngClass]="'col'+i" > {{element[col.name]}} </td>
</ng-container>
See, stackblitz, for more about ngClass see the docs
Updated if we can change the "class" of the rows we can use the tag "tr mat-row.
Imagine some data like:
[
{position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H',class:"col0"},
{position: 2, name: 'Helium', weight: 4.0026, symbol: 'He',class:"col1"},
]
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [ngClass]="row.class"></tr>
Of course we can also changing the td., we need use "some variable of the row". We can has a property of our "data",
You can write
<td mat-cell *matCellDef="let element"
[class.disabledRange]="col.disabledRange"
[ngClass]="element.class"> {{element[col.name]}} </td>
We can also use the "index of the row", e.g.
<!--see the "let row=index"-->
<td mat-cell *matCellDef="let element;let row=index"
[class.disabledRange]="col.disabledRange"
[ngClass]="'col'+(row%4)" > {{element[col.name]}} </td>
NOTE: If only want to change the background, we can use
[style.background-color]="....."

Display row number using {{#each}}

I'm trying to count each row in a table. Each table row is a new collection. The code below counts the total number of collections and displays that. How do I change it to display the row number.
Path: calc.js
SalaryCalculator: function () {
return SalaryCalculator.find({});
},
SalaryCalculatorCount: function () {
return SalaryCalculator.find({}).count();
}
Path: calc.html
{{#each SalaryCalculator}}
<tr>
<th scope="row">{{SalaryCalculatorCount}}</th>
<td>{{specialisation}}</td>
<td>{{subSpecialisation}}</td>
<td>{{positionTitle}}</td>
<td>{{yearsOfExperience}}</td>
<td>{{salary}}</td>
</tr>
{{/each}}
Here's the helpers
SalaryCalculator: function () {
var count = 1;
var salCalDetails = SalaryCalculator.find({});
salCalDetails.forEach(function(doc){
doc.rowCount = count;
count++;
});
return salCalDetails;
},
{{#each SalaryCalculator}}
<tr>
<th scope="row">{{rowCount}} </th>
<td>{{specialisation}}</td>
<td>{{subSpecialisation}}</td>
<td>{{positionTitle}}</td>
<td>{{yearsOfExperience}}</td>
<td>{{salary}}</td>
</tr>
{{/each}}
Or if you follow through the answer given by #Michel Floyd then you need this answer too https://stackoverflow.com/a/22103990/3422755 as {{#index}} will give you starting number as 0

Resources