unset scrollToIndex after setting it - react-virtualized

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>

Related

Material-UI AutoComlete only load values on second click

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.

How to show and update current page number in an input box palceholder Using Tabulator

I am trying to show the current page number in an input box as a place holder the issue is I can't figure out how to update the value when users go to another page.
Here is what I tried:
<input id="currentPage"/>
document.getElementById("currentPage").placeholder = tabulator_table.getPage();
Here is the first part of the question
Here is sample
You want to use the pageLoaded callback on the table instance.
When creating the table, you need to add a property for pageLoaded as a function with a parameter for the page number. This callback is triggered each time the page is loaded.
Here is a working example, https://jsfiddle.net/nrayburn/w68d75Lq/1/.
So you would do something like this, where #table is the element id for the table and input is a reference to your input element where you keep the page number value.
new Tabulator('#table', {
...tableOptions,
pageLoaded: (pageNumber) => {
input.value = pageNumber
}
});

React-virtualized - is it possible to use custom column?

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.

Resetting row heights causes incorrect row offset to get calculated

Inside of an InfiniteLoader I have a List, whose rowRenderer callback creates a <div> wrapped by CellMeasurer (I'm also using a cache for that). The rows can vary wildly in size, but this setup is working well for scrolling purposes.
However, elements within each row can dynamically change in height based on user input. In those cases, I call:
cellMeasurerCache.clear(rowIndex, 0);
this._listRef.recomputeRowHeights(rowIndex);
But in some cases, this causes the rows to jump around -- this is because the top values are getting calculated incorrectly. For example, I'm displaying a document with the following rows rendered in List:
rowIdx height top
3 668px 420px
4 8547 1088
5 2420 9635
Then the height of row 4 increases slightly (~50px). After running the above code with rowIndex == 4, I see the following rows:
rowIdx height top
5 2420px 3088px
6 1156 5508
7 4718 6664
8 1050 11382
As you can see, row 5 now has an incorrect top value, causing the rows to jump around. I'm assuming that the height of row 4 did not get measured correctly.
What's wrong?
Update 2017-11-08: It appears that calling cellMeasurerCache.clear(rowIndex, 0) replaces the height of that row with the value of estimatedRowSize, which is very different. It doesn't seem to re-measure, contrary to what the docs say.
CellMeasurer._maybeMeasureCell() isn't called for row 4 after it gets the default height. My rowRenderer callback (which creates CellMeasurer around my content) is only invoked starting at row 5. So the code has made the decision of which rows to show with row 4 having the much smaller default height, instead of calculating beforehand.
Not sure if this is the correct/best way to handle this, but I was able to get this working like so:
First, I used the callback version of CellMeasurer, storing the measure callback for later use (stored per row):
rowRenderer = ({ key, index, style, isScrolling, parent }) => {
const getContent = measure => {
// store callback for later use
this._measureCallbacks[index] = measure;
// ... get your content ...
return content;
};
return (
<CellMeasurer
key={key}
cache={cellMeasurerCache}
columnIndex={0}
parent={parent}
rowIndex={index}
>
{({ measure }) => (
<div key={key} style={style}>
{getContent(measure)}
</div>
)}
</CellMeasurer>
);
};
Later, when a row height changes, instead of calling cellMeasurerCache.clear(), I run:
// tell row to re-measure
this._measureCallbacks[rowIndex]();
// tell list to recompute row offsets
this._listRef.recomputeRowHeights(minRow);

How can I know an object is not visible when any of parent object is not visible in an HTML page using java script?

Let say I have an text box in an HTML page as follows.
<DIV style = "display:none;">
<DIV style = "display:inline;">
<INPUT type = "text" style = "display:inline;">
</DIV>
</DIV>
In this case, the text box will not be visible to the user. How can I identify that text is not currently visible to the user.
Dont say that, I should travel up to the parent objects to find out if they are set to not visible. I have bunch of fields to be validated like this and this would reduce the application performance.
Is there any other way to find out as this object is not visible to the user?
Thanks in advance.
If you don't need it to be pure JavaScript I would suggest using jQuery. Using the :visible or :hidden selector will accomplish what you want:
if ( $('yourElement').is(":hidden") ) {
// The element is not visible
}
http://api.jquery.com/visible-selector/
http://api.jquery.com/hidden-selector/
If you need pure JavaScript and you don't want to travel up through every ancestor element, you could try checking the element's offsetWidth and offsetHeight. If the element is hidden because of an ancestor element, they should both be 0. Note: I've always used jQuery for this, so I don't know how reliable this is.
var yourElement = document.getElementById('yourElementsId');
if ( yourElement.offsetWidth == 0 && yourElement.offsetHeight == 0) {
// The element is not visible
}
https://developer.mozilla.org/en-US/docs/DOM/element.offsetWidth
https://developer.mozilla.org/en-US/docs/DOM/element.offsetHeight

Resources