I am using react-virtualized to render my table. Is it possible at all to replace the default Column component with a custom one? I keep getting this error
Failed prop type: Table only accepts children of type Column
Yes of course,you can do that by using cellRenderer prop in Column which is callback function and it will give you bunch of parameters and you need return the custom component that will render in cell
<Column key={column.dataKey + column.label + index} dataKey={column.dataKey}
cellRenderer={
({ cellData, rowIndex, dataKey }) => (
<CheckBox
cellData={cellData}
changeCheckBox={changeCheckBoxHandler.bind(
this,
rowIndex,
dataKey
)}
/>
)
}/>
you can find out in detail here. https://github.com/bvaughn/react-virtualized/blob/master/docs/Column.md#cellrenderer
Why would you want to do this? You have to use the Column component to define every column, and then you can render whatever you want inside each Column.
Related
this one should be simple for tabulator experts (but not for me)...
i have a tabulator table. I've made one column, "edit" clickable as shown below. it works fine and returns the value of the cell i clicked. HOWEVER, that's not what i need. I need to get the value of ANOTHER cell in the same row (column "transactionID"). I know how you would do it in other languages, just use x and y values to move over 3 columns and get the value. but how is it done in tabulator? by the cloumn name? I can't find any example code on how to accomplish this.
This is the snippet from my tabulator init :
{title:"edit" , name:"edit", formatter:myformatter, cellClick:function(e, cell){alert("cell clicked - " + cell.getValue())}},
i just need to make it return value for "transactionID" instead of "edit"
and before anyone asks, no, i can't just make "transactionID" clickable. I need the clickable cell to be separate.
thanks for your help!
ok so since i got no answers to this question, i slogged thru and figured it out myself eventually. To save others time who run into this in the future, i am posting how i solved it. code with comments below :
// this goes in your tabulator column definitions. In my example, "edit" is a column
with an image button that on clicking, redirects to another page depending on what cell was clicked
{title:"" , name:"edit", formatter:openIcon, headerSort:false, cellClick:function(e, cell){
var re = cell.getRow(cell); // get the row of the cell that was clicked
var thenum = re.getData().id; // gets the value of column "id" in the same row
var theurl = "editTransaction.php?trans="+thenum; // creates my url
console.log(theurl); // perform whatever action you need to do. replace this.
}},
If you are using react-tabulator and you want to access some column data to perform a specific action ,here is the snippet for your help.
import { reactFormatter } from "react-tabulator";
// your React Component to use in a cell
function CustomFormatter(props: any) {
const rowData = props.cell._cell.row.data;
return <a onClick={() => alert(rowData.customField)}{cellData.customField }</a>;
}
const columns = [{ title: 'Custom', field: 'custom', align: 'center', formatter: reactFormatter(<CustomFormatter />) },
]
On my react app I have 3 droplist
the first drop has the primary values (ex: a, b) the next drop will filter the values in the array using the value selected in the first drop
I'm using the ui and Autocomplete material for the dropboxes
when I select the value in the first drop the component returns the value in the event of the click to the parent, and then I call the second drop with these values
<Grid item xs={4}>
<Dropdownlist
required
name='opt1'
texto='where:'
click={click1}
options={options}
optionsList1={optionsList1}
filter='regiao'
/>
</Grid>
<Grid item xs={4}>
{optionNameShow2 === 'hidden' ? null
: <Dropdownlist
required
name='opt2'
select3='hidden'
texto=' '
click={click2}
options={options2}
valueforFilter={selectState1 ? selectState1.optionValue : ''}
optionsList2={optionsList2}
filter='local'
/>}
</Grid>
the problem is that the values are only loading when I click the second time.
the probleme is on chrome and FF so far tested
and shoud be on first click.
working exemple is on : https://codesandbox.io/s/muddy-haze-6c1kj?file=/src/App.js
TL;DR: Your filterlists() triggers a state change, but if (value) {... is using the values before that call changes are actually reflected in the current state. I fixed your pastebin.
NL;PR: setStates are scheduled to run after the function that calls them ends, thus the values you are currently using are still before the changes have taken place. Take care of those setStates separately with an effect hook.
<example name="One"></example>
<example name="Two"></example>
<example name="Three"></example>
Next render looks like this:
<example name="Four"></example>
<example name="Three"></example>
LitElement will remove the last element and update the first two with new properties.
How do I change this so that LitElement removes all elements except name="three" and a new element is created with name="Four" on first position?
Using React, this would be accomplished by giving them a key property. I want to achieve the same result using LitElement.
<example key="1" name="One"></example>
<example key="2" name="Two"></example>
<example key="3" name="Three"></example>
For this you want to use the lit-html repeat directive. From the docs:
The repeat directive performs efficient updates of lists based on
user-supplied keys:
repeat(items, keyFunction, itemTemplate)
Where:
items is an Array or iterable.
keyFunction is a function that takes a single item as an argument and returns a guaranteed unique key for that item.
itemTemplate is a template function that takes the item and its current index as arguments, and returns a TemplateResult.
For example:
const employeeList = (employees) => html`
<ul>
${repeat(employees, (employee) => employee.id, (employee, index) => html`
<li>${index}: ${employee.familyName}, ${employee.givenName}</li>
`)}
</ul>
`;
If you re-sort the employees array, the repeat directive reorders
the existing DOM nodes.
To use repeat you'll need to import it from lit-html:
import {repeat} from 'lit-html/directives/repeat';
I'm using an InfiniteLoader with a Table and I have the indices of some entries that match a specific criteria stored in state. If the user would want to go through those entries, I would have to pass down to the Table each index (following a button click) and use it in scrollToIndex. However, after it's passed down, I would have to make it null again, otherwise if the user were to scroll up/down the Table, he would always end to the same index specified by scrollToIndex instead of the current scroll position.
Is there a better way to do that, other than setting the state twice, once with an index and then with a null value?
Hope my question is clear.
Table (and Grid and List) also have public methods for setting a 1-time scroll index. For Table the method is scrollToRow and you just pass it the index you want to scroll to. Maybe that would be more to your liking?
Edit: In response to the follow-up question of how you get a reference to Table if you also need to pass it to InfiniteLoader:
<InfiniteLoader {...infiniteLoaderProps}>
{({ onRowsRendered, registerChild }) => (
<Table
{...tableProps}
onRowsRendered={onRowsRendered}
ref={(ref) => {
this._tableRef = ref // Store for yourself
registerChild(ref) // And pass on to InfiniteLoader
}}
>
{/* Columns ... */}
</Table>
)}
</InfiniteLoader>
So right now if you want to sort a data table you can give the column a sortBy attribute and when you click the header it will sort by whatever that attribute is.
Is there a way in which I can call my own custom function instead when you click the header?
You can bind a handler to all of the column headers of a data table with the following script.
jQuery('th').children().bind('click', function(evt) {
alert(evt);
//Insert logic to determine which header was clicked and do stuff
});