Styling cells in table with react-bootstrap components - css

I'm rendering a table in which each cell corresponds to a Button component of react-bootstrap.
<>
<Table borderless className='below-nav table-style' responsive="sm">
<tbody>
{Array.from({ length: rows }).map((_, row_index) => (
<tr key={row_index}>
{Array.from({ length: columns }).map((_, column_index) => (
<Button className="td-style button-style" variant="warning">
<td key={column_index}>
ciao
</td>
</Button>
))}
</tr>
))}
</tbody>
</Table>
</>
The problem is that it renders buttons that are not fulfilled with the color selected: variant="warning", but just the border is of that color. There is another issue: bottom-border of each cell is not rendered at all so it seems clearly that something is overlayed on something else but i don't know why.
CSS like this seems not to work:
.table-style {
border-collapse: separate;
border-spacing: 1px ;
border-width: 1px;
}
.td-style {
margin: 5px ;
}

You are wrapping the <td> with the <Button>, this is not the correct way to use a table. This is how it should work:
<>
<Table responsive="sm">
<tbody>
{Array.from({ length: rows }).map((_, row_index) => (
<tr key={row_index}>
{Array.from({ length: columns }).map((_, column_index) => (
<td key={column_index}>
<Button variant="warning">
ciao
</Button>
</td>
))}
</tr>
))}
</tbody>
</Table>
</>
Basic DEMO of a table https://codesandbox.io/s/serene-knuth-qhpuu?file=/src/App.js

Related

Is there any CSS hack to stop a dropdown menu from causing an overflow?

My problem: https://i.gyazo.com/152caf74df3c484e770f9e8c34f5471e.mp4
If I click on the button, then it causes an overflow. I want to menu to appear without the overflow.
Sandbox: https://stackblitz.com/edit/react-ts-8aq1rq?file=App.tsx,index.html
Code:
import * as React from 'react';
import './style.css';
import 'bootstrap/dist/css/bootstrap.min.css';
import { NavDropdown, Button } from 'react-bootstrap';
// #ts-nocheck
export default function App() {
return (
<div className="table-responsive">
<div className="table">
<table
id="user-list-table"
className="table table-striped"
role="grid"
data-toggle="data-table"
>
<thead>
<tr className="light">
<th>Col one</th>
<th>Col two</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>
<NavDropdown
id="basic-nav-dropdown"
title={
<Button className="btn btn-sm btn-icon" variant="primary">
click
</Button>
}
>
<NavDropdown.Item>Option 1</NavDropdown.Item>
<NavDropdown.Item>Option 2</NavDropdown.Item>
<NavDropdown.Item>Option 3</NavDropdown.Item>
</NavDropdown>
</td>
</tr>
</tbody>
</table>
</div>
</div>
);
}
Is there another bootstrap component that does this so that I can swap NavDropdown to it? If not, is there something else like a CSS hack that lets me do this?
The issue is that there isn't enough room to dropdown the nav list inside the div with the class of table-responsive. You can give it some min height or padding, but that might be weird if you have content below it. So you can add a negative margin to counter the additional padding:
.table-responsive {
padding-bottom: 100px;
margin-bottom: -100px;
}
Demo

How Can I truncate overflowed text using ellipsis in description rows from Product List?

Is there a way
e.g
instead I have "product 1 is the best from the industry" I try this "product 1..."
This is my code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { searchProducts, deleteProduct } from '../../actions';
import { Link } from 'react-router-dom';
const moment = require('moment');
class ProductList extends Component {
componentDidMount() {
this.props.searchProducts();
}
runFiles() {
return this.props.productList.map(product => {
return (
<tr key={product._id}>
<td style={{fontStyle: 'italic',fontWeight:'500'}}>{product.name}</td>
{/*IN THE FOLLOWING ONE LINE I WANT TO TRUNCATE DESCRIPTION*/}
<td style={{fontStyle: 'italic',fontWeight:'500'}}>{product.description}</td>
<td style={{fontStyle: 'italic',fontWeight:'500'}}>{product.brand}</td>
<td style={{fontStyle: 'italic',fontWeight:'500'}}>{product.price}</td>
<td style={{fontStyle: 'italic',fontWeight:'500'}}>{product.stock}</td>
<td style={{fontStyle: 'italic',fontWeight:'500'}}>{product.code}</td>
<td style={{fontStyle: 'italic',fontWeight:'500'}}>{producto.isPassedAway}</td>
<td style={{fontStyle: 'italic',fontWeight:'500'}}>
{moment(product.createdAt).format('DD-MM-YYYY HH:mm:ss')}</td>
<td style={{fontStyle: 'italic',fontWeight:'500'}}>
{moment(product.passedAwayAt).format('DD-MM-YYYY HH:mm:ss')}</td>
<td>
<Link to={`/products/${product._id}/show`} className='mr-2' style=
{{fontWeight:'bold',color:'blue'}}>
show
</Link>
<Link to={`/products/${product._id}/edit`} className='mr-2' style=
{{fontWeight:'bold',color:'blue'}}>
Edit
</Link>
<a
className='mr-2'
style={{fontWeight:'bold',color:'blue'}}
href='#more'
onClick={() => {
if (
window.confirm(
'¿Are you sure to want to delete the product?' + ' ' + product.name
)
)
this.props.deleteProduct(product._id);
}}
>
Delete
</a>
</td>
</tr>
);
});
}
render() {
return (
<div>
<h2><b>Listing products</b></h2>
<p>
<Link to='/products/new' className= 'btn btn-primary' style=
{{fontWeight:'bold',color:'black'}}>
New
</Link>
</p>
<div className='table-responsive'>
<table className='table table-sm'>
<thead className='thead-light'>
<tr>
<th style={{fontStyle: 'arial'}}>Name</th>
<th style={{fontStyle: 'arial'}}>Description</th>
<th style={{fontStyle: 'arial'}}>Brand</th>
<th style={{fontStyle: 'arial'}}>Price</th>
<th style={{fontStyle: 'arial'}}>Stock</th>
<th style={{fontStyle: 'arial'}}>Code</th>
<th style={{fontStyle: 'arial'}}>Is passed Away</th>
<th style={{fontStyle: 'arial'}}>Created At</th>
<th style={{fontStyle: 'arial'}}>Passed Away At</th>
<th style={{fontStyle: 'arial'}}>Actions</th>
</tr>
</thead>
<tbody>{this.runFiles()}</tbody>
</table>
</div>
</div>
);
}
}
function mapState(state) {
return {
productList: state.productsDs.productList
};
}
const actions = {
searchProducts,
deleteProduct
};
export default connect(
mapState,
actions
)(ProductList);
My productList fetched to componentDidMount is following:
[product1:{name: "product 1",description:"the product 1 is biggest of the
factory"},...//OTHER FIELDS]
I want something like this:
product 1: {name: "product1", description: "the product 1..."//OTHER FIELDS,... }
in every description rows form each product I want to truncate text with ellipsis.
I know it's possible truncate the text on determinate part from the parragraph. Say prod1... instead prod1 is the best of the industry.
anyone who can solve this?
You should be able to achieve that by adding some css to the description cell.
.truncate {
width: [width];
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<td className="truncate" style={{fontStyle: 'italic',fontWeight:'500'}}>{product.description}</td>

Remove all tr elements unless tr>td>input has a class 'DontRemoveMe'

Sorry for the very specific title, couldn't think of how to say it in more general terms.
Assume you have a table and each row contains a cell that has an input, but some input fields have a class of 'DontRemoveMe'. How do you target every row except the 'DontRemoveMe' rows?
Manipulation of DOM Elements requires JavaScript. One way to achieve this is with jQuery:
function remove() {
$('tr:not(.dontRemoveMe)').remove();
}
.dontRemoveMe td {
background-color: green;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr class="dontRemoveMe">
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Jon</td>
<td>Jones</td>
<td>33</td>
</tr>
</table>
<button onclick="remove()">Remove rows</button>
CSS (Not Yet Implemented):
Using CSS level 4 selectors, I believe it would be
tr:has(td>input:not(>>.DontRemoveMe))
However, those aren't implemented in any browser. So you would want to use javascript.
Javascript:
// Select all rows that don't contain a input.DontRemoveMe
let rows = Array.from(document.querySelectorAll("tr")).filter(x => !(x.querySelector("input.DontRemoveMe")));
// Add a special class to these rows so we can target them with CSS
rows.forEach(x => x.classList.add("selected"));
td {
padding: 8px; /* Padding for all rows to make background visible */
}
.selected {
background: red;
}
<table>
<tr>
<td><input type="text" value="selected" />
</td>
</tr>
<tr>
<td><input class="DontRemoveMe" type="text" value="not selected" />
</td>
</tr>
<tr>
<td>
<input type="text" value="selected" />
</td>
</tr>
</table>
Here is an old school javascript way.
Find all the tr tags then find any children with class DontRemoveMe, if it doesn't find any add a .hide class to the current row.
But, honestly I'd question the reason you want to do it like this, chances are there is a more sensible way.
var tr = document.getElementsByTagName('tr');
var i = 0;
var length = tr.length
for (; i < length; i++) {
var dontRemove = tr[i].getElementsByClassName('DontRemoveMe')
if (!dontRemove.length) {
tr[i].classList.add('hide')
}
}
td {
color: #ededed;
}
.red {
background-color: #ff3030;
}
.blue {
background-color: #6495ED;
}
.hide {
display: none;
}
<table>
<tr class="red">
<td>Normal</td>
<td>Normal</td>
<td class="DontRemoveMe">Don't Remove Me</td>
</tr>
<tr class="blue">
<td>Can't see me</td>
<td>Can't see me</td>
<td>Can't see me</td>
</tr>
<tr class="red">
<td class="DontRemoveMe">Don't Remove Me</td>
<td>Normal</td>
<td class="DontRemoveMe">Don't Remove Me</td>
</tr>
</table>

How to show a table on hovering a button in react?

I tried
class MyColorPicker extends React.Component {
render() {
const darkColors = ['#B80000', '#DB3E00', '#FCCB00', '#008B02', '#006B76', '#1273DE', '#004DCF', '#5300EB'];
const lightColors = ['#EB9694', '#FAD0C3', '#FEF3BD', '#C1E1C5', '#BEDADC', '#C4DEF6', '#BED3F3', '#D4C4FB'];
return (<div>
<button id="color">Select color</button>
<div className="picker">Text</div>
<div className="picker">
<table>
<tbody>
<tr>
{darkColors.map(color =>
<td style={{backgroundColor: color, width: 20, height: 20}} key={color}>{" "}</td>)}
</tr>
<tr>
{lightColors.map(color =>
<td style={{backgroundColor: color, width: 20, height: 20}} key={color}>{" "}</td>)}
</tr>
</tbody>
</table>
</div>
</div>);
}
}
css
.picker{
display: none;
}
#color:hover + .picker{
display: block !important;
}
The table does not show. I also tried adding a className to GithubPicker from react-color. Didn't work.
I don't want to set a state on hover because I have many components where I want to attach a button and a color picker. In this case, on hovering one button, all the other color pickers will show. I just want one color picker to show. How can I achieve this?
#color:hover + .picker work for element with class .picker just after #color:hover. In your case you have two .picker element. So first .picker will shown but as css second element will not show.
Please wrap both .picker div into a one div and put .picker class on wrapped div element.
Still you will get one more issue. As css you are trying to put hover css for button. When your mouse will move to picker, button hover will clear and again .picker will disappear.
So we have to wrap all element in one div and put hover css for wrapped div.
JSX
<div>
<div className="picker">
<button id="color">Select color</button>
<div className="picker-colors">
<div>Text</div>
<div>
<table>
<tbody>
<tr>
{darkColors.map(color => (
<td
style={{
backgroundColor: color,
width: 20,
height: 20
}}
key={color}
>
{" "}
</td>
))}
</tr>
<tr>
{lightColors.map(color => (
<td
style={{
backgroundColor: color,
width: 20,
height: 20
}}
key={color}
>
{" "}
</td>
))}
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
CSS
.picker-colors {
display: none;
}
.picker:hover .picker-colors {
display: block;
}
Here's a working example https://codesandbox.io/s/9yrr9wx60r

CSS how to hide all but first 3 table rows [duplicate]

This question already has an answer here:
How to display the first 3 list items and hide the rest with CSS nth-child?
(1 answer)
Closed 5 years ago.
Can I somehow hide all but first 3 rows in table via CSS only ? The table is filled by MySQL query and i don't know how long it can be. On button click i toggle it. In first i want to show only 3 rows and hide the rest. What i tryied is
.modal-body table tbody tr:nth-last-child(-n+5) {
display: none;
}
but in this case I am hiding only the last 5 rows. This number ( 5 in the example ) won't be static as i said. Thank in advance!
My table :
<table>
<thead>
<td class="p0 pl5 strong"><?=Yii::t('app','app.product')?></td>
<td class="p0 pl5 strong"><?=Yii::t('app','app.price')?></td>
<td class="p0 strong text-center"><?=Yii::t('app','app.Add')?></td>
</thead>
<?php if((isset($extras)) and !empty($extras)) {
foreach ($extras as $cnt => $extra) {
$cnt++;?>
<tr>
<td><?=$extra->title?></td>
<td><?= Yii::$app->moneyConvertor->getMoney($extra->getPrice()); ?></td>
<td class="p0">
<section title=".slideThree">
<div class="slideThree">
<input type="checkbox" value="<?=$extra->id?>" id="slideThree<?=$cnt?>" onchange="checkBoxValue(this, <?= $product->id ?>)" name="check" checked/>
<label for="slideThree<?=$cnt?>"></label>
</div>
</section>
</td>
</tr>
<?php }
}?>
</table>
Use the n-th child to hide all but first 3 rows
table tr:nth-child(n+4) {
display: none;
}
<table>
<tr><td>Row 1</td></tr>
<tr><td>Row 2</td></tr>
<tr><td>Row 3</td></tr>
<tr><td>Row 4</td></tr>
<tr><td>Row 5</td></tr>
<tr><td>Row 6</td></tr>
<tr><td>Row 7</td></tr>
<tr><td>...</td></tr>
</table>
You can select first three rows by::
tr:nth-child(-n+3) {
color: red;
}
Jsfiddle link here : http://jsfiddle.net/w8g7j4bu/

Resources