How to prevent selecting value while enter key press in react-select - reactjs

I am trying to achieve to prevent the enter key selection while user has nothing typed and press the enter key. In current situation when user click on react-select and hit the enter key then its selecting the first value from the drop down, where user has nothing typed but still its selection first value from drop down. Is anyone has any idea to prevent this functionality.
It should only select when user type something in input box and select or hit enter key.
here is the screen short where user has nothing typed and press enter key then its selecting first value.
here is code:
import React from 'react';
import Select from 'react-select';
class CreateSelectOption extends React.Component {
constructor(props) {
super(props);
this.state = {
selected: this.props.options,
questionsCount: props.questionsCount,
inputValue: '',
}
this.processQuestions = this.processQuestions.bind(this);
}
componentWillReceiveProps(newProps) {
if (newProps.questionsCount.length > 0) {
this.setState({
questionsCount: newProps.questionsCount
})
}
}
onChange = (e, props) =>{
this.props.onChange(e, props.technology, props.id, props.type, props.noc, props.dataTech, props.dataType);
}
onInputValueChange = inputValue => {
this.setState({ inputValue: this.allowOnlyOneSpace(inputValue) });
};
allowOnlyOneSpace = str => {
return str.endsWith(" ") ? str.trim() + " " : str.trim();
};
render() {
const customStyles = {
control: (styles, state) => ({
...styles,
borderRadius: '1px', // default border color
boxShadow: 'none', // no box-shadow
color: '#007bff',
height: '27px',
minHeight: '30px'
}),
singleValue: (styles, state) => ({
...styles,
color: '#007bff',
top: '42%'
}),
dropdownIndicator: (styles, state) => ({
...styles,
padding: "6px"
}),
menuPortal: base => ({ ...base, zIndex: 9999, fontSize: '12px' })
}
const { selectedTech }=this.props;
const selectedVal = selectedTech ? { value: selectedTech , label: selectedTech } : null;
return(
<Select
className="select-width select-color"
menuPortalTarget={document.body}
styles={customStyles}
value={selectedVal}
onChange={(e) => { this.onChange(e, this.props) }}
options={props.technologyArray && props.technologyArray.map(t => ({ value: t, label: t }))}
openMenuOnClick={true}
placeholder="Please select tech"
components={{ IndicatorSeparator: () => null }}
inputValue={this.state.inputValue}
onInputChange={this.onInputValueChange}
disabled={this.state.inputValue.length === 0}
/>
)
}
}
export default CreateSelectOption;

UPD options={this.state.inputValue.length === 0 ? [] : colourOptions}

try these properties
openMenuOnFocus={false}
openMenuOnClick={false}
and I guess (can't check that right now though) that also this is working too (if selectedVal is present, then it turns to true else false)
openMenuOnFocus={selectedVal}
openMenuOnClick={selectedVal}

Related

react-select, AsyncSelect only able to select one option even i added isMulti after that it display no options

I can select first option successfully, but after that it doesn't display any option, can't add second option and I even added isMulti.
import React from "react";
import AsyncSelect from "react-select/async";
import makeAnimated from "react-select/animated";
import { options } from "../colorOptions";
import chroma from "chroma-js";
const animatedComponents = makeAnimated();
export const SelectBox = () => {
const loadOptions = (searchValue, callback) => {
console.log(searchValue);
setTimeout(() => {
const filteredOptions = options.filter((option) =>
option.name.toLowerCase().includes(searchValue.toLowerCase())
);
console.log(filteredOptions);
callback(filteredOptions);
}, 1000);
};
const colorStyles = {
control: (styles) => ({ ...styles, backgroundColor: "white" }),
option: (styles, { data, isDesable, isFocused, isSelected }) => {
return { ...styles, color: data.colorCode };
},
multiValue: (styles, { data }) => {
const color = chroma(data.colorCode);
return {
...styles,
backgroundColor: color.alpha(0.1).css(),
color: data.colorCode
};
},
multiValueLabel: (styles, { data }) => ({
...styles,
color: data.colorCode
})
};
return (
<AsyncSelect
key={options.length}
loadOptions={loadOptions}
option={options}
closeMenuOnSelect={false}
components={animatedComponents}
isMulti
defaultOptions
styles={colorStyles}
/>
);
};
code sandbox link:
https://codesandbox.io/s/dreamy-water-j2m55v?file=/src/components/SelectBox.jsx:0-1401
code sandbox link:
https://codesandbox.io/s/dreamy-water-j2m55v?file=/src/components/SelectBox.jsx:0-1401
my mistake
i should provide my collection of option in this format
export const options = [ { id: 1, value: "Red", colorCode: "#FF0000", label: "Red" }, ];
when i change to this format the code works

React-Select with Formik Reset/Clear button

What i want, a "reset/clear" button on the first page to refresh the searchable drop down list of react-select with Formik.This is the first page,the one after is the second,the problem iam facing is to refresh the code from a clear button in the first page,i tried everything i can to change,i added some props that are not needed.
<SearchableDropDownList
onChange={(value) =>
formik.setFieldValue('formDay', value || null)}
resetValue={resetValue}
value={formik.values.formDay}
options={dayOptions}
formik={formik}
/>
import React from 'react';
import Select from 'react-select';
import CreatableSelect from 'react-select/creatable';
import chroma from 'chroma-js';
import { StylesConfig } from 'react-select';
// https://codesandbox.io/s/1j4zxl8bq
export default ({ inputRef, onChange, options, value, className, resetValue, onBlur, formik }) => {
// -----------Creating design for react-select----------------------------For Creatable--umust
// --u must set this line as well : const color = chroma(data.color ?? 'black'); because there is no data on creatable
// so i must handle the empty created by the user input
const dot = (color = 'white') => ({
alignItems: 'center',
display: 'flex',
':before': {
backgroundColor: color,
borderRadius: 10,
content: '" "',
display: 'block',
marginRight: 8,
height: 10,
width: 10,
},
});
const colourStyles = {
control: (styles) => ({
...styles,
backgroundColor: '#212529',
borderRadius: 10,
borderColor: '#323232',
}),
option: (styles, { data, isDisabled, isFocused, isSelected }) => {
const randomColor = 'black';
const color = chroma(data.color ?? 'black');
return {
...styles,
backgroundColor: isDisabled
? undefined
: isSelected
? randomColor
: isFocused
? color.alpha(0.1).css()
: undefined,
color: isDisabled
? '#ccc'
: isSelected
? chroma.contrast(color, 'white') > 2
? 'white'
: 'blue'
: randomColor,
cursor: isDisabled ? 'not-allowed' : 'default',
':active': {
...styles[':active'],
backgroundColor: !isDisabled
? isSelected
? randomColor
: color.alpha(0.3).css()
: undefined,
},
};
},
input: (styles) => ({
...styles,
...dot(),
color: 'grey',
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
placeholder: (styles) => ({
...styles,
...dot('#ccc'),
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
singleValue: (styles, { data }) => ({
...styles,
...dot('white'),
color: 'grey',
borderColor: '#6c5dd3',
text: 'john#domain.com',
}),
};
if (resetValue === true) {
value = null;
// formik.setFieldValue('formDay', null)
resetValue = false;
}
const handleChange = (event) => {
// Overwrite the event with your own object if it doesn't exist
if (!event || value === null) {
event = {
target: inputRef,
value: '',
};
}
onChange(event);
};
const defaultValue = (options, value) => {
return options ? options.find((option) => option.value === value) : null;
// return {value:'developer',label:'Software Developer'};
};
// const randomColor = `#`.concat( Math.floor(Math.random()*16777215).toString(16))
// const color = chroma.random();
// const color = chroma(data.color ?? 'black');
// https://nibes.cn/blog/22525
return (
<div className={className}>
<CreatableSelect
value={defaultValue(options, value)}
styles={colourStyles}
onChange={handleChange}
isClearable
ref={inputRef}
options={options}
/>
</div>
);
};

how to set checked item true or false in multi checkbox react native

I have a small request
I want to know how to set checked item true or false in multi checkbox by Sub Terms react native
In the following code, when I click on the checkbox, I want to change the relevant item in the array in function onchecked() and update the component.
import React, { useState, useEffect } from "react";
import {
StyleSheet,
Text,
View,
CheckBox,
TouchableOpacity,
} from "react-native";
const terms = [
{
term_id: 21,
name: "Clothing",
checked: false,
children: [
{
term_id: 24,
name: "Accessories",
checked: false,
children: [
{
term_id: 25,
name: "Scarf",
checked: false,
children: [],
},
{
term_id: 22,
name: "Tshirts",
checked: false,
children: [],
},
],
},
],
},
];
export default function Categoris() {
const [unSelectedterms, setSelectionTerms] = useState(terms);
const onchecked = (id) => {
console.log(id);
setSelectionTerms(unSelectedterms);
};
const recursive = (data, level = 0) => {
return data.map((item, key) =>
item.children?.length ? (
<>
{renderItem(level, item.name, item.term_id, item.checked, key)}
{recursive(item.children, level + 1)}
</>
) : (
renderItem(level, item.name, item.term_id, item.checked, key)
)
);
};
const renderItem = (level, name, id, checked, key) => (
<TouchableOpacity
style={{ flexDirection: "row", alignItems: "center" }}
key={key}
onPress={() => {
onchecked(id);
}}
>
<CheckBox
value={checked}
onValueChange={() => {
onchecked(id);
}}
/>
<Text style={{ fontWeight: "bold" }}>
{name}
{id} {level > 0 && "- ".repeat(level)}
</Text>
</TouchableOpacity>
);
return <View style={styles.container}>{recursive(unSelectedterms)}</View>;
}
const styles = StyleSheet.create({
item: {
fontSize: 20,
},
container: {
backgroundColor: "#fff",
padding: 50,
},
});
In the following code, when I click on the checkbox, I want to change the relevant item in the array in function onchecked() and update the component.
One option would be to write some code to traverse the terms tree and update the correct checked value, but I might suggest another approach. Instead store the checked state separately from the terms tree to simplify state updates.
const [checkedStates, setCheckedStates] = useState({});
const onChecked(id) => {
// this will toggle based on the current value of the checkbox
setCheckedStates(current => ({
...current,
[id]: !current[id],
});
}
...
// and then in the recursive call
{renderItem(level, item.name, item.term_id, !!checkedStates[item.id], key)}
This approach should avoid a more complicated tree traversal and update at the cost of an extra piece of state. If there isn't a need to update other properties in terms that's the tradeoff I would choose, but if other pieces of terms can be updated then maybe the tree traversal is a better option.

Is it possible to prevent default onDeselect, (select input multiple ant design)?

What I´m trying to do is to control the onDeselect event, I want to ask a question before the event finish. And then if the user accept delete the option could be deleted.
This is my select and the props:
<Select
mode="multiple"
style={{ width: '100%' }}
placeholder="Select at least one"
allowClear={false}
onSelect={this.addNewClassroom}
onDeselect={this.deleteClasroom}
>
{classroomSelect}
</Select>
This is the function that I use:
deleteClasroom(val, e){
//e.preventDefault();
confirm({
title: 'Are you sure?',
content: 'Delete this...',
onOk() {
// -----------> delete the item
},
onCancel() {
// -----------> keep the item
},
});
}
onDeselect happens after the event and does not expose such a functionality. However you can convert the component into a controlled component and implement your use case.
class App extends Component {
constructor() {
super();
this.state = {
values: ['a10', 'c12'],
};
}
onDeselect = (value) => {
const that = this;
confirm({
title: 'Are you sure delete this task?',
content: 'Some descriptions',
okText: 'Yes',
okType: 'danger',
cancelText: 'No',
onOk() {
that.setState(prevState => ({
values: prevState.values.filter(item => item !== value),
}));
},
onCancel() {
;
},
});
}
onSelect = (value) => {
console.log(value)
this.setState(prevState => ({
values: [...prevState.values, value],
}));
}
render() {
return (
<div>
<Select
mode="multiple"
style={{ width: '100%' }}
placeholder="Please select"
value={this.state.values}
onSelect={this.onSelect}
onDeselect={this.onDeselect}
>
{children}
</Select>,
</div>
);
}
}
See working example here.

Want to show data onMouseDown event in my REACT app

I have a console.log showing the correct information onMouseDown event in my REACT app, how do I change it so it shows the data in a pop up window?
I am happy to use Modal or hover over event, whatever it takes to display the data. Data Consists of:
on item click
{id: 3, group: 1, title: "resiting", bgColor: "#ff9800", start_time: Moment, …}
bgColor: "#ff9800"
end_time: Moment {_isAMomentObject: true, _i: "2018-10-11T15:08:00", _f: "YYYY-MM-DDTHH:mm:ss", _isUTC: false, _pf: {…}, …}
group: 1
id: 3
start_time: Moment {_isAMomentObject: true, _i: "2018-10-11T10:29:00", _f: "YYYY-MM-DDTHH:mm:ss", _isUTC: false, _pf: {…}, …}
title: "resiting"
__proto__: Object
import React, { Component } from "react";
import moment from "moment";
import Timeline from "react-calendar-timeline";
import generateFakeData from "../../generate-fake-data";
export default class App extends Component {
constructor(props) {
super(props);
const { groups, items } = generateFakeData();
const defaultTimeStart = moment()
.startOf("day")
.toDate();
const defaultTimeEnd = moment()
.startOf("day")
.add(1, "day")
.toDate();
this.state = {
groups,
items,
defaultTimeStart,
defaultTimeEnd
};
}
itemRenderer = ({
item,
timelineContext,
itemContext,
getItemProps,
getResizeProps
}) => {
const { left: leftResizeProps, right: rightResizeProps } = getResizeProps();
const backgroundColor = itemContext.selected
? itemContext.dragging
? "red"
: item.selectedBgColor
: item.bgColor;
return (
<div
{...getItemProps({
style: {
backgroundColor,
color: "#ffffff",
borderColor: "none",
borderStyle: "none",
borderWidth: 0,
borderRadius: 0,
borderLeftWidth: itemContext.selected ? 1 : 1,
borderRightWidth: itemContext.selected ? 1 : 1
},
onMouseDown: () => {
console.log("on item click", item);
}
})}
>
{itemContext.useResizeHandle ? <div {...leftResizeProps} /> : null}
<div
style={{
height: itemContext.dimensions.height,
overflow: "hidden",
paddingLeft: 3,
textOverflow: "ellipsis",
whiteSpace: "nowrap"
}}
>
{itemContext.title}
</div>
{itemContext.useResizeHandle ? <div {...rightResizeProps} /> : null}
</div>
);
};
render() {
const { groups, items, defaultTimeStart, defaultTimeEnd } = this.state;
return (
<Timeline
groups={groups}
items={items}
sidebarContent={<div>Vehicle</div>}
sidebarWidth={60}
lineHeight={20}
headerLabelGroupHeight={20}
fullUpdate={false}
itemsSorted
itemTouchSendsClick={false}
stackItems
itemHeightRatio={0.98}
showCursorLine
canMove={true}
canResize={true}
defaultTimeStart={defaultTimeStart}
defaultTimeEnd={defaultTimeEnd}
itemRenderer={this.itemRenderer}
/>
);
}
}
You can find it here on https://still-river-97856.herokuapp.com/tracking
Try something like this, you can use a ant design modal or a react-modal for the Modal(data={item}). But the logic is that once you click ok/away on the modal the clickedItem is set to null so that the modal is not displayed anymore.
Take a look at this code,
onMouseDown: () => {
console.log("on item click", item);
this.setState({clickedItem: item});
}
onModalOkClick = () => {
this.setState({clickedItem: null})
}
render() {
const { groups, items, defaultTimeStart, defaultTimeEnd, clickedItem } = this.state;
return (
<div>
<Timeline
groups={groups}
items={items}
sidebarContent={<div>Vehicle</div>}
sidebarWidth={60}
lineHeight={20}
headerLabelGroupHeight={20}
fullUpdate={false}
itemsSorted
itemTouchSendsClick={false}
stackItems
itemHeightRatio={0.98}
showCursorLine
canMove={true}
canResize={true}
defaultTimeStart={defaultTimeStart}
defaultTimeEnd={defaultTimeEnd}
itemRenderer={this.itemRenderer}
/>
{clickedItem ? <Modal data={clickedItem}> : null}
</div>
);
}
Let me know if you need help with the modal or you are still unsure how to proceed.
The dashboard looks nice btw. :)

Resources