How can I disable checkbox for multi value selection in react-dropdown-tree-select? - react-dropdown-tree-select

I am new to React and I stumbled upon react-dropdown-tree-select for a specific need I had allowing users to view data in Tree format for selection in DropDown. But, I want the users to only select 1 value at a time. How can i enforce that?

There is no such property available directly in react-dropdown-tree-select. But you can listen to onChange event and reset the entire data which you have passed in data props with the updated data with only one node selected.
Check the following code.
onChange = (currentNode) => {
// keep reference of default data structure.
const updatedData = this.props.defaultData;
// find node related to currentData in your tree and set checked property
this.setState({data : updatedData });
}
render = () => {
return (
<DropdownTreeSelect
data={this.state.data}
onChange={this.onChange}
/>
);
}
This will basically stop the user from selecting multiple options instead of disabling remainig item you are unselecting the previously selected items.

If you just want one element selected at a time you can use mode="radioSelect"

Related

How to call Ag-Grid onSelectionChanged event clicking on same row multiple times?

I am using Ag-grid library for grid view in React app. Following is my Ag-Grid component:
const handleChanged = (gridOptions) => {
const selectedNodes = gridOptions.api.getSelectedNodes()
//TODO
}
<AgGridReact
data-testid="details-data"
columnDefs={DetailsColDef}
rowData={formatDetailsData(
data?.Response,
false
)}
rowSelection="single"
reactNext={true}
defaultColDef={defaultColDef}
onSelectionChanged={handleSelected}
suppressPaginationPanel={true}
domLayout="autoHeight"
suppressMaxRenderedRowRestriction={true}
rowBuffer={5}
suppressColumnVirtualisation={false}
debounceVerticalScrollbar={true}
alwaysShowVerticalScroll={true}
></AgGridReact>
Current Scenario: handleChanged is getting called when we click on Grid row.
Requirement: Need to call handleChanged event every time on multiple click at same time. Currently event is getting called first time only. If we click again on same row, it need's to be called.
You can call gridOptions.api.getSelectedNodes() inside onCellClicked. Every time the row/cell is clicked you will get the data
const onCellClicked = (e) => {
const selectedRows = gridOptions.api.getSelectedNodes();
console.log(selectedRows)
}
<AgGridReact
onCellClicked={onCellClicked}
....
>
</AgGridReact>
Check working example
I think you are trying to use onSelectionChanged out of its scope, if you need to see if a cell is clicked (any number of times, you can use the onCellClicked Event). there are multitudes of events that can be used if that doesn't suit your needs.
https://www.ag-grid.com/react-data-grid/grid-events/#reference-selection
Otherwise if you are going to use this event only one handy way would be to change the selected row at the end of your processing and making this process async. this would be be problematic if the user clicks the row you have chosen to set it to so not the optimal solution i would say.
https://www.ag-grid.com/react-data-grid/row-selection/#node-selection-api

React.js re-render behavior changes when list contents change

This question requires some background to understand:
My app uses various lists of items with Boolean state that the user toggles by clicking.
I implemented this logic with two reusable elements:
A custom hook, useSelections(), which maintains an array of objects of the form { id, name, isSelected }, where isSelected is Boolean and the only mutable element. It returns the array as current state, and a dispatch function that takes an input of the form { id, newValue } and updates the isSelected member of the object with the given id
A function component Selector, which takes as props a single item and the dispatch from useSelections and returns a <li> element whose CSS class depends on isSelected.
Normally, they are used together in the following way, which works fine (i.e., internal state and the color of the list item are synchronized, and toggle when clicked):
function localComponent(props) {
const [items, dispatch] = useSelections(props.data);
return (
<ul>
{items.map(item => <Selector key={item.id} item={item} onChange={dispatch} />)}
</ul>
);
}
It works equally well when useSelections() is elevated to a parent component, and items and dispatch are passed as props.
The trouble started when the array became larger, and I decided to page it:
<ul>
{items.slice(start, end).map(item => <Selector key={item.id} item={item} onChange={dispatch} />)}
</ul>
(start and end are part of component state.)
When my component is first rendered, it works normally. However, once start and end are changed (to move to the next page), clicking an item changes internal state, but no longer triggers a re-render. In UX terms this means that after the first 'next' click, when I click on an item nothing appears to happen, but if I hit 'next' again, and then 'back', the item I just clicked on has now changed.
Any suggestions would be appreciated.
I solved the problem by removing the logic from the reducer function to ignore calls where there is no change:
const hasChanged = modifiedItem.isSelected !== newValue;
modifiedItem.isSelected = newValue;
return hasChanged ? { data } : state;
is now simply:
modifiedItem.isSelected = newValue;
return { data };
There's still something going on with React here that I do not understand, but my immediate problem is solved.

Office UI Fabric React - Dropdown not respecting selectedKey prop

I have this code:
<Dropdown
selectedKey={someKeyInState}
onChange={(e,option) => {
// check if the dropdown should be updated
if(someCondition){
// update selected key
}
else {
// don't update selected key
}
}}
options={someOptions}
/>
I want to block updating the selected key if a certain condition is met.
But, Dropdown visually shows the option that I clicked on as selected.
How do I prevent this behavior?
If you are using react, you should not do in this way. Use a global state optionState and try to use conditional checks which state should be shown to use onChange method is triggered. In order to do this. First extract your conditional check to separate function.
myFunction = () => {
// do conditional check and setState for optionState
}
--------------------------
onChange={myFunction}
Then when you select pop the key and value from the option state and update to the selectedState, now react automatically update the state and UI
The problem was my state for selectedKey was undefined it nothing is selected. When you pass in undefined you're basically saying to fabric to control the selectedKey state on it's own. I fixed by passing null instead of undefined. That made the Dropdown fully controlled.

Getting current table data from Ant Design Table

I'm using Ant design table for displaying some data. New data arrives every one second. When user clicks on button, I need to export current table data to XSL.
I'm getting current data in this way:
onChange={(pagination, filter, sorter, currentTable) => this.onTableChange(filter, sorter, currentTable)}.
This thing works and gets me good and filtered data, but when I get new data, I can't get those new data because this function is not triggered while none of the filters or sort settings didn't change. Is there any way to get current table data without dummy changing filter to trigger onChange function?
Title and footer return only current page data.
Code show here
{ <Table
dataSource={this.props.data}
rowKey={(record) => { return record.id}}
columns={this.state.Columns}
pagination={this.state.pageSizeOptions}
rowClassName={(record) => { return
this.getRowClassNames(record) }}
expandedRowKeys={ this.state.expandedRowKeys }
expandedRowRender={record => { return
this.getEventsRows(record) }}
onExpand={(expanded, record) => {
this.onExpandRow(expanded, record.id) }}
expandRowByClick={false}
onChange={(pagination, filter, sorter, currentTable)
=> this.onTableChange(filter, sorter, currentTable)}
/>
}
You can store pagination, sorter and filter data in your component state. Also you can pass these params to your redux state and store there. If you can share your code, i can provide more specific answers.
Below you can find my solution for permanent filter. I was sending filter params to API and get filtered data. If you want to filter it in the component, you can use component lifecycle or render method.
onTableChange(pagination, filter, sorter){
const { params, columns } = this.state;
/** You can do any custom thing you want here. Below i update sort type in my state and pass it to my redux function */
if(sorter.order != null)
params.ordering = (sorter.order === 'descend' ? "-" : "")+ sorter.columnKey.toString();
this.setState({params});
this.props.listUsers(this.state.params);
}
This is because you have taken either columns, datasource varibale as object instead of array.
write
this.state.someVariable=[]
instead of
this.state.someVariable = {}

Clear React Widget DropdownList if not select any item

I'm using React Widgets for the Dropdown List, I want to customize the onChange to get my state as the selected value:
const { selected } = this.state;
return <DropdownList {...rest}
data={fitData} onSearch={this.search}
onChange={this.change}
/>
The onChange simply like this:
change(selected) {
this.setState({selected});
}
It works, but when I close the dropdown list without selecting any value, the selected still chosen. What could I do to remove the selected if I don't choose any value?
The onChange event will get called only on a value change.
if you want to listen to the 'closed without selecting' You should listen to the onToggle event.
You can call the same method as you did on the onChange and check the selected value is null/undefined.
onToggle={this.change}

Resources