how do I fill table html to column wise? - css

I am trying to fill my table HTML using an API, however, I want to fill the given HTML table into a column instead of a row to look like the following image layout, but however, I am getting filled as row as you can see in my second image. is there a way to convert it into a column-based filling?
row fill
const arr = [
{
"demo": [
{
"_id": "T0810",
"title": "Historian",
"tags": [
"demo"
],
"queries": [],
},
{
"_id": "T0817",
"title": "book",
"tags": [
"demo"
],
"queries": [],
},
],
"demo_2": [
{
"_id": "T0875",
"title": "Program",
"tags": [
"demo_2",
"Control"
],
"queries": [],
},
{
"_id": "T0807",
"title": "Interface",
"tags": [
"demo_2"
],
"queries": [],
}
]
}
]
const keys = Object.keys(arr[0]);
export default function Demo() {
return (
<div className="wrapper">
<table className="table">
<thead>
<tr>
{keys.map((i) => (
<th key={i}>
<div className="column">
<div className="header">{i}</div>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{keys.map((key) => (
<tr key={key}>
{arr[0][key].map((item) => (
<td key={item._id}>
<div className="column">
<div className="option">{item._id}</div>
</div>
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
}

It's only slightly more involved than what you have put together. The first thing you have to consider is that your table will have as many rows as the lengthiest key, so if demo array has 2 element and demo_2 has 6 elements, the table will have 6 rows even though there will be nothing for 3 of those rows to display for demo.
As such your top level loop will have to loop not through keys but through a number representing the length of the lengthiest key, if that makes sense. So apart from getting the keys, you will need something like this:
const max_rows = keys.reduce((acc, cur) => {
if (arr[0][cur].length > acc) return arr[0][cur].length;
else return acc;
}, 0);
Then your nested loop will look like this:
<table className="table">
<thead>
<tr>
{keys.map((i) => (
<th key={i}>
<div className="column">
<div className="header">{i}</div>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{Array(max_rows)
.fill(0)
.map((key, index) => (
<tr key={index}>
{keys.map((item, ind) => (
<td key={ind}>
<div className="column">
{arr[0][item][index] ? (
<div className="option">
{arr[0][item][index]._id}
</div>
) : null}
</div>
</td>
))}
</tr>
))}
</tbody>
</table>
Here is a Sandbox: https://codesandbox.io/s/adoring-wave-5fub7?file=/src/App.js

Related

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

How to create a row with one cell in a expandible 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>

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 to fetch and display data in React js but Line 26: 'cusList' is not defined no-undef error is coming up,pls healp.tnx

How to fetch and display data in ASP.net core using React js Line 26: 'cusList' is not defined no-undef error is coming up.
import React, { Component } from 'react';
import './Map';
export class FetchCustomer extends Component {
static displayName = FetchCustomer.Name;
constructor(props) {
super(props);
this.state = { customers: [], loading: true };
}
render() {
let contents = this.state.loading
? <p><em>Loading...</em></p>
: this.renderCustomerTable(this.state.cusList);
return <table className='table'>
<thead>
<tr>
<th></th>
<th>Id</th>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{cusList.map(cus =>
<tr key={cus.Id}>
<td></td>
<td>{cus.Id}</td>
<td>{cus.Name}</td>
<td>{cus.Address}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(cus.Id)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(cus.Id)}>Delete</a>
</td>
</tr>
)}
</tbody>
</table>;
fetch('api/Customer/Index')
.then(response => response.json())
.then(data => { this.setState({ cusList: data, loading: false }) });
}
}
Following changes are needed in your code...
In your constructor change the last line of code with following:
this.state = { customers: [], loading: true, cusList: [] };
And in the "tbody" section please change the code to:
<tbody>
{this.state.cusList.map(cus =>
<tr key={cus.Id}>
<td></td>
<td>{cus.Id}</td>
<td>{cus.Name}</td>
<td>{cus.Address}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(cus.Id)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(cus.Id)}>Delete</a>
</td>
</tr>
)}
</tbody>
This should work.
Also it's pretty clear from the error itself about what you are missing.
Hope it helps.

Why Bootstrap table do not use styles in Angular 7?

I try to create simple bootstrap table in Angular 7.2 project however it does not use any styles. I just see raw text. Any ideas why it does not work?
component.ts:
elements: any = [
{id: 1, first: 'Mark', last: 'Otto', handle: '#mdo'},
{id: 2, first: 'Jacob', last: 'Thornton', handle: '#fat'},
{id: 3, first: 'Larry', last: 'the Bird', handle: '#twitter'},
];
headElements = ['ID', 'First', 'Last', 'Handle'];
component.html:
<table mdbTable striped="true">
<thead>
<tr>
<th *ngFor="let head of headElements" scope="col">{{head}} </th>
</tr>
</thead>
<tbody>
<tr mdbTableCol *ngFor="let el of elements">
<th scope="row">{{el.id}}</th>
<td>{{el.first}}</td>
<td>{{el.last}}</td>
<td>{{el.handle}}</td>
</tr>
</tbody>
</table>
angular.json:
"styles": [
"src/styles.scss",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/assets/sass/paper-kit.scss",
"src/assets/css/demo.css",
"src/assets/css/nucleo-icons.css"
],
"scripts": [
"node_modules/jquery/dist/jquery.slim.min.js",
"node_modules/popper.js/dist/umd/popper.js",
"node_modules/bootstrap/dist/js/bootstrap.min.js"
],
styles.scss:
#import "~bootstrap/dist/css/bootstrap.css";
app.modules.ts:
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
...
imports: [
...,
NgbModule.forRoot(),
...
],
...
bootstrap: [AppComponent]
To use Bootstrap table, just add the class table, for striped, add table-striped
<table class="table table-striped">
</table
But your HTML shows you have used mdbootstrap. You need to install angular-bootstrap-md
npm i angular-bootstrap-md

Resources