dash-table
dash-table copied to clipboard
Row selector checkbox styling
The checkboxes for row selection are inserted as <input>
elements only, which cannot be styled reliably across browsers, making it very difficult to create a look and feel of the DataTable that is consistent with the other Dash components.
The aim is to make the row selector checkboxes styleable with CSS -- like the second checkbox from the bottom in this screenshot:
The fix for this is very simple - adding a <label>
tag immediately after the <input>
allows for full css-only customization of the checkboxes by hiding the input control and styling the label. The input element needs an ID that the label can reference, but that's all, really.
To make this use the existing Dash-Bootstrap checkbox component styling, a few classes and a wrapper element are needed, but the principle is the same.
Before:
<td class="dash-select-cell">
<input type="checkbox" name="row-select-datatable-foo" />
</td>
After:
<td class="dash-select-cell">
<div class="custom-checkbox custom-control" style="left: 1rem;">
<input id="row-select-datatable-foo-1" class="custom-control-input" type="checkbox" name="row-select-datatable-foo" />
<label for="row-select-datatable-foo-1" class="custom-control-label" />
</div>
</td>
Implementation notes:
-
The
left: 1rem
style is needed to counteract the padding:0 override that Dash sets on div elements that matchtd > div:not(.cell-markdown)
. Of course this could be done with a change to the reset stylesheet instead of a style property on the tag, but the above is just an example. -
The whole change can be implemented by modifying the
src\dash-table\derived\cell\operations.tsx
script. -
To avoid potentially-unwanted style changes in existing deployments, the styleable HTML could be made optional.
-
Yes I am aware that checkboxes can be styles cross-browser using prefixed
-appearance: none
, but as long as the Dash-Bootstrap components are using the input+label method, I would still propose following the same method here
A simple implementation (without the 'optional' setting) could look something like this:
function rowSelectCell(
id: string,
idx: number,
rowSelectable: Selection,
selectedRows: number[],
setProps: SetProps,
data: Data
) {
return (
<td
key='select'
className='dash-select-cell'
style={{
width: `30px`,
maxWidth: `30px`,
minWidth: `30px`,
textAlign: 'center'
}}
>
<div
className='custom-checkbox custom-control'
style={{
left: `1rem`
}}
>
<input
type={rowSelectable === 'single' ? 'radio' : 'checkbox'}
style={{verticalAlign: 'middle'}}
name={`row-select-${id}`}
id={`row-select-${id}-${idx}`}
className='custom-control-input'
checked={R.includes(idx, selectedRows)}
onChange={() => {
const newSelectedRows =
rowSelectable === 'single'
? [idx]
: R.ifElse(
R.includes(idx),
R.without([idx]),
R.append(idx)
)(selectedRows);
setProps({
selected_rows: newSelectedRows,
selected_row_ids: R.map(
i => data[i].id,
newSelectedRows
)
});
}}
/>
<label
htmlFor={`row-select-${id}-${idx}`}
className='custom-control-label'
/>
</div>
</td>
);
}
Hi, I am interested in customizing the checkboxes in Dash DataTable, but I don't know how to proceed even with the manual provided above. Could I write the change just simply in css? Could you please help me on how to achieve the desired change?
Thank you,
Andrew.
The above is not a manual for achieving it with the current DataTable implementation; rather, it is a proposal to change the DataTable implementation to allow standard methods to work.
However, as mentioned, you can do it with the current DataTable version by using -appearance: none
in your CSS (See CanIUse.com page for compatibility and remember to prefix it as needed), like so:
.dash-select-cell input[type=checkbox] {
appearance: none;
cursor: pointer;
width: 200px;
height: 200px;
background-image: url("https://static.thenounproject.com/png/2303901-200.png");
background-repeat: no-repeat;
background-position: center center;
}
.dash-select-cell input[type=checkbox]:checked {
background-image: url("https://static.thenounproject.com/png/747863-200.png");
}
See demo and code: https://jsfiddle.net/1apdztk3/
Hello Jens, thank you so much for replying and giving me the advice! I have pasted the code to my css, but now I can't see any of the check boxes actually - see the screenshot attached:
In case I can make this work, how would it be done similarly for the check boxes in the header?
Thanks for help!
Andrew
You need to change the styles to use your own images / styling. The example css uses 200x200px images which will not fit in the Dash table
Hmm.. I took the same check box picture(s) and decrease their size to 12px times 12px and converted it to .svg. It should be sufficiently small, but no check boxes are till visible : -/.
The png version of the box: