How to have a searchbar in "Select" Component native-base - javascript

I would love to have a search bar in "Select" component from the library native-base in react-native.
I have tried adding a "TextInput" component inside the "Select" component. In UI it aligns perfectly, but when I click on the "TextInput" it gets selected and the list drops down.
Following is the code I tried:
<Select
w={w}
h={h}
variant="outline"
selectedValue={selectedValue}
minWidth="200"
// borderColor={primaryColor}
accessibilityLabel={accessibilityLabel?accessibilityLabel: "Choose Service" }
placeholder={placeholder?placeholder: "Choose Service"}
_selectedItem={{
bg:"coolGray.200",
// endIcon: <CheckIcon size="5" />
}}
mt={1}
onValueChange={onValueChange}
>
<Input
placeholder="Search"
variant="filled"
width="100%"
h={heightPercentageToDP("6%")}
borderRadius="10"
py="1"
px="2"
borderWidth="0"
/>
{
data?.map(item => {
return(
<Select.Item
label={item.label}
value={item.value}
/>
)
})
}
</Select>

Select box of native base has prop _actionSheetBody, it contains IFlatListProps so you can use ListHeaderComponent in there. So can use this way.
You use a state to save search value:
const [searchValue, setSearchValue] = React.useState<string>('');
Edit select box
`
<Select w={w} h={h} variant="outline" selectedValue={selectedValue}
minWidth="200"
accessibilityLabel={accessibilityLabel?accessibilityLabel: "Choose Service" }
placeholder={placeholder?placeholder: "Choose Service"}
_selectedItem={{
bg:"coolGray.200",
// endIcon: <CheckIcon size="5" />
}}
mt={1}
onValueChange={onValueChange}
_actionSheetBody={{
ListHeaderComponent: <FormControl px={3} mb={3}>
<Input
px={15}
py={2}
fontSize={16}
value={searchValue}
placeholder=""
_focus={{ bg: colors.white['50'], borderColor: 'darkBlue.600' }}
type='text'
onChangeText={(value: string) => {
setSearchValue(value);
}}
/>
</FormControl>
}}
>
<Input
placeholder="Search"
variant="filled"
width="100%"
h={heightPercentageToDP("6%")}
borderRadius="10"
py="1"
px="2"
borderWidth="0"
/>
{
(data && data.length)?data.filter((item)=>{
// you filter with searchValue
return true;
}).map(item => {
return(
<Select.Item
label={item.label}
value={item.value}
/>
)
})
}
</Select>

Related

onChange Event not Triggered in React JS

export default function ActionRolesPage(props) {
const [authorities, setAuthorities] = useState([]);
const [name, setName] = useState("");
let list = [];
useEffect(() => {
getAuthorities();
}, []);
const getAuthorities = () => {
doGetAllAuthorities()
.then((res) => {
getValidatedData(res.data, "array").map((data) => (
list.push({ authority: data})
))
setAuthorities(list);
}).catch((e) => {
console.log(e);
})
}
const handleChange = (e) => {
console.log(e);
const { name, checked } = e.target
console.log(name,checked);
let tempUser = authorities.map((user) => (
user.authority === name ? { ...user, isChecked: checked } : user
));
setAuthorities(tempUser);
}
if(authorities.length){
console.log(authorities);
}
return (
<React.Fragment>
<Suspense fallback={<div>Loading....</div>}>
<div className="page-content">
<MetaTags>
<title>Add Role | IG One</title>
</MetaTags>
<Container fluid>
<Breadcrumb
title="Add Role"
breadcrumbItems={[{ title: "Settings" }, { title: "Roles" }, { title: "Add" }]}
/>
<Form onSubmit={handleSubmit}>
<Card>
<CardBody>
<Row className="mb-3">
<label
htmlFor="example-text-input"
className="col-md-2 col-form-label"
>
Name
</label>
<div className="col-md-8 mx-0">
<Input
className="form-control"
type="text"
name="name"
required
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Name Of User "
/>
</div>
</Row>
<br></br>
<br></br>
<Row className="mb-3">
<CardTitle>
Authorities
</CardTitle>
<div className="col-md-2">
{
authorities.map((data,index) => (
<>
<div key={index} style={{ display: "flex" }}>
<div className='col-md-10 mx-0 mt-2'>
<Input type={"checkbox"}
checked={data?.isChecked || false}
name={data.authority}
onChange={(e) => console.log(e)}
className="form-control"
style={{ cursor: "pointer", paddingLeft: "1rem" }}
/></div>
<div>
<label style={{ cursor: "pointer" }} htmlFor={data.authority} className="col-md-50 col-form-label"> {data.authority}</label>
</div>
</div>
</>
))
}
</div>
</Row>
<Row className="d-flex justify-content-center mt-4">
<Button color="dark" type='submit' className="btn-xs" style={{ width: "40%", cursor: "pointer" }}
>
Add Role
</Button>
</Row>
</CardBody>
</Card>
</Form>
</Container>
</div>
</Suspense>
</React.Fragment>
)
}
Here is the whole code. I want to handle multiple checkboxes but onChange Event not triggered. There is a function handleChange it calls when onChange triggered but in my case there is no error seen in console as well as not display any event at console please resolve my doubt.
I also need to update the form getting respose from backend is checked authority name array How to handle checked state in checkbox.
If you have created a custom component for input, pass your onChange handler as prop and call inside the component as onChage event of <input> field. Or if you used any third-party lib, then you just need to pass a callback as prop. Otherwise Try this: <input> instead of <Input>
<input type={"checkbox"}
checked={data?.isChecked || false}
name={data.authority}
onChange={(e) => console.log(e)}
className="form-control"
style={{ cursor: "pointer", paddingLeft: "1rem" }}
/>

Set different React Popper tooltip for each element

I am using React popper for displaying additional information for input fields in my form. The problem is that, when i am displaying Tooltip for more than 1 element, it displays the same tooltip. How can i display different tooltips for each field.
Here is the code i am using inside my Component
https://codesandbox.io/s/hungry-gould-modgk?fontsize=14&hidenavigation=1&theme=dark
// Popper Tooltip Props;
const {
getArrowProps,
getTooltipProps,
setTooltipRef,
setTriggerRef,
visible,
} = usePopperTooltip({
trigger: 'hover',
placement: 'right',
closeOnOutsideClick: false,
visible: controlledVisible,
onVisibleChange: setControlledVisible
})
return (
<TextBox
label="Title"
className="title-field"
name="title"
type="text"
isRequired={true}
/>
<div className="field-info" ref={setTriggerRef}>
<Icon size="medium">
<FontAwesomeIcon icon={faInfoCircle} size="lg" />
</Icon>
</div>
{visible && (
<div
ref={setTooltipRef}
{...getTooltipProps({ className: 'tooltip-container' })}
>
Tooltip element
<div {...getArrowProps({ className: 'tooltip-arrow' })} />
</div>
)}
<TextBox
label="Price"
className="price-field"
name="price"
type="text"
isRequired={true}
/>
<div className="field-info" ref={setTriggerRef}>
<Icon size="medium">
<FontAwesomeIcon icon={faInfoCircle} size="lg" />
</Icon>
</div>
{visible && (
<div
ref={setTooltipRef}
{...getTooltipProps({ className: 'tooltip-container' })}
>
Tooltip element
<div {...getArrowProps({ className: 'tooltip-arrow' })} />
</div>
)}
)
[1]: https://i.stack.imgur.com/oHuBA.png
Each tooltip needs its own visible state variable. Can you create your own tooltip component like so:
const MyTooltip = ({tooltipText}) => {
const [isVisible, setIsVisible] = useState(false)
const {
getArrowProps,
getTooltipProps,
setTooltipRef,
setTriggerRef,
visible,
} = usePopperTooltip({
trigger: 'hover',
placement: 'right',
closeOnOutsideClick: false,
visible: isVisible,
onVisibleChange: setIsVisible
})
return (
<>
<div className="field-info" ref={setTriggerRef}>
<Icon size="medium">
<FontAwesomeIcon icon={faInfoCircle} size="lg" />
</Icon>
</div>
{visible && (
<div
ref={setTooltipRef}
{...getTooltipProps({ className: 'tooltip-container' })}
>
{tooltipText}
<div {...getArrowProps({ className: 'tooltip-arrow' })} />
</div>
)}
</>
)
}
Then you can use the component like this:
<TextBox
label="Title"
className="title-field"
name="title"
type="text"
isRequired={true}
/>
<MyTooltip tooltipText="Tooltip Element 1" />
<TextBox
label="Price"
className="price-field"
name="price"
type="text"
isRequired={true}
/>
<MyTooltip tooltipText="Tooltip Element 2" />

None of the Tabs' children match with `[object Object]`. You can provide one of the following values: 0, 1

I am building header using material UI Tab Component but I see below error:
index.js:2178 Material-UI: The value provided to the Tabs component is invalid.
None of the Tabs' children match with [object Object].
You can provide one of the following values: 0, 1.
I tried console.log the newValue to see what value it is getting and I can see 0 and 1 while navigating through tabs.
Note : Removed Some Code for better visibility
Here is my component:
const Header = (props) => {
const { classes } = props;
const [value, setValue] = useState(0);
const [modalIsOpen, setIsOpen] = React.useState(false);
const openModal = () => {
setIsOpen(true);
};
const closeModal = () => {
setIsOpen(false);
};
const handleTabChange = (event, newValue) => {
console.log(newValue);
setValue({ newValue });
};
return (
<div>
<div className="topnav">
<img src={logo} className="logo" alt="Movies App Logo" />
<div className="topnav-right">
<Button variant="contained" color="default" onClick={openModal}>
Login
</Button>
</div>
<div className="topnav-right">
<Button variant="contained" color="default">
Logout
</Button>
</div>
</div>
<Modal
ariaHideApp={false}
isOpen={modalIsOpen}
onRequestClose={closeModal}
contentLabel="Login"
aria-labelledby="Modal"
aria-describedby="Modal for Login and Registration"
style={customStyles}
>
<Paper className={classes.Paper}>
<CardContent>
<Tabs
className="tabs"
value={value}
onChange={handleTabChange}
centered
>
<Tab label="Login" />
<Tab label="Register" />
</Tabs>
{value === 0 && (
<div>
<FormControl required>
<InputLabel htmlFor="username" className={classes.inputLable}>
Username
</InputLabel>
<Input
className={classes.Input}
id="username"
type="text"
username={username}
onChange={usernameChangeHandler}
/>
<FormHelperText>
<span className="red">required</span>
</FormHelperText>
</FormControl>
<br />
<br />
<FormControl required>
<InputLabel
htmlFor="loginPassword"
className={classes.inputLable}
>
Password
</InputLabel>
<Input
className={classes.Input}
id="loginPassword"
type="password"
password={password}
onChange={passwordChangeHandler}
/>
<FormHelperText>
<span className="red">required</span>
</FormHelperText>
</FormControl>
<br />
<br />
{loggedIn === true && (
<FormControl>
<span className="success-text">Login Successful!</span>
</FormControl>
)}
<br />
<br />
<Button
variant="contained"
color="primary"
onClick={loginHandler}
>
LOGIN
</Button>
</div>
)}
{value === 1 && (
<div>
<h1>something</h2>
</div>
)}
</CardContent>
</Paper>
</Modal>
</div>
);
};
export default withStyles(styles)(Header);
For some reason you enclosed the value in an object (curly braces syntax).
Replace setValue({ newValue }) with setValue(newValue).

Both Material-UI radio button are checked

I have a file which renders RadioGroup, FormControlLabel and FormControl. Below is the code for this
import React from 'react';
import PropTypes from 'prop-types';
import Radio from '#material-ui/core/Radio';
import RadioGroup from '#material-ui/core/RadioGroup';
import FormControl from '#material-ui/core/FormControl';
import FormLabel from '#material-ui/core/FormLabel';
import FormControlLabel from '#material-ui/core/FormControlLabel';
export const RenderRadioGroup = ({ label, children }) => {
return (
<FormControl>
<FormLabel
style={{
margin: '20px 0 20px 0',
color: '#000000',
fontSize: '20px',
fontWeight: 'bold',
}}
>
{label}
</FormLabel>
<RadioGroup row>{children}</RadioGroup>
</FormControl>
);
};
export const RenderRadioButtonWrapper = props => {
return <FormControlLabel control={<CustomRadioButton />} {...props} />;
};
export const CustomRadioButton = props => {
return <Radio {...props} />;
};
RenderRadioGroup.propTypes = {
children: PropTypes.node.isRequired,
label: PropTypes.string,
};
RenderRadioButtonWrapper.propTypes = {
label: PropTypes.string,
};
CustomRadioButton.propTypes = {
label: PropTypes.string,
};
In the main file, I am calling these components as follows
<form>
<Field
name="typeofintimation"
label="Type of intimation"
component={RenderRadioGroup}
>
<Field
label="Via Call"
name="viacall"
value="viacall"
component={RenderRadioButtonWrapper}
/>
<Field
label="Via Email"
name="viaemail"
value="viaemail"
component={RenderRadioButtonWrapper}
/>
</Field>
<Field component={renderTextFieldGroup} label="Caller Details">
<Field component={renderTextField} label="Caller Name" />
<Field component={renderTextField} label="Caller Email" />
<Field component={renderTextField} label="Caller Contact" />
</Field>
</form>
I am getting the radio fields but both are checked. I cannot select or deselect the radio buttons.
What am I missing here? Is there some props which I need to pass in either the component or the main file?
I am also using redux-form here so I need some assitance in that.
You need to explicitly supply a name in the props so that the system knows that the two radio buttons belong to the same group. The documentation for the API in its list of props says:
name string The name used to reference the value of the control. If
you don't provide this prop, it falls back to a randomly generated
name.
See https://material-ui.com/api/radio-group/ for the full list.
Radio buttons are grouped by name - so if you click one of the buttons in a group all the others are cleared. You have the two radio buttons but they have different names so the system thinks they are in different groups and so both can be checked.
If you try replacing:
<Field
label="Via Call"
name="viacall"
value="viacall"
component={RenderRadioButtonWrapper}
/>
<Field
label="Via Email"
name="viaemail"
value="viaemail"
component={RenderRadioButtonWrapper}
/>
with
<Field
label="Via Call"
name="viamethod"
value="viacall"
component={RenderRadioButtonWrapper}
/>
<Field
label="Via Email"
name="viamethod"
value="viaemail"
component={RenderRadioButtonWrapper}
/>
you can only select one in 'naked' HTML. However, where you are creating the radio buttons using the API you need to explicitly set name: and make it the same name for both e.g. name: 'viamethod' otherwise you will get random names and the two radio buttons won't be in the same group.
start with radioValue's state as "".
<RadioGroup row className={classes.FormGroup}>
<FormControlLabel
classes={{ label: classes.label }}
control={
<Radio
name="Yes"
checked={this.state.radioValue[key]}
onClick={(e) => {this.handleRowClick(e, row, index)}}
value="Y"
/>
}
label="Yes"
labelPlacement="end"
/>
<FormControlLabel
classes={{ label: classes.label }}
control={
<Radio
name="No"
checked={this.state.radioValue[key]}
onClick={(e) => {this.handleRowClick(e, row)}}
color="secondary"
value="N"
/>
}
label="No"
labelPlacement="end"
/>
</RadioGroup>

How to make a 'Select' component as required in Material UI (React JS)

I want to display like an error with red color unless there is a selected option.
Is there any way to do it.
For setting a required Select field with Material UI, you can do:
class SimpleSelect extends React.PureComponent {
state = {
selected: null,
hasError: false
}
handleChange(value) {
this.setState({ selected: value });
}
handleClick() {
this.setState(state => ({ hasError: !state.selected }));
}
render() {
const { classes } = this.props;
const { selected, hasError } = this.state;
return (
<form className={classes.root} autoComplete="off">
<FormControl className={classes.formControl} error={hasError}>
<InputLabel htmlFor="name">
Name
</InputLabel>
<Select
name="name"
value={selected}
onChange={event => this.handleChange(event.target.value)}
input={<Input id="name" />}
>
<MenuItem value="hai">Hai</MenuItem>
<MenuItem value="olivier">Olivier</MenuItem>
<MenuItem value="kevin">Kevin</MenuItem>
</Select>
{hasError && <FormHelperText>This is required!</FormHelperText>}
</FormControl>
<button type="button" onClick={() => this.handleClick()}>
Submit
</button>
</form>
);
}
}
Working Demo on CodeSandBox
Material UI has other types of Select(native) also where you can just use plain HTML required attribute to mark the element as required.
<FormControl className={classes.formControl} required>
<InputLabel htmlFor="name">Name</InputLabel>
<Select
native
required
value={this.state.name}
onChange={this.handleChange}
inputProps={{
name: 'name',
id: 'name'
}}
>
<option value="" />
<option value={"lala"}>lala</option>
<option value={"lolo"}>lolo</option>
</Select>
</FormControl>
P.S. https://material-ui.com/demos/selects/#native-select
The required prop only works when you wrap your elements inside a <form> element, and you used the submit event to submit the form.
this is not related to react, this is pure HTML.
In MUI v5 (2022), it works like this:
const handleSubmit = (e)=>{
e.preventDefault()
// ...
}
return (
<form onSubmit={handleSubmit}>
<Select required value={val} onChange={handleChange} required>
<MenuItem value="yes">Yes</MenuItem>
<MenuItem value="no">No</MenuItem>
</Select>
<Button type="submit">Submit</Button>
</form>
)
As you can see, it works the same way you think it should work, so what your code should probably be similar to this.
But the required prop only works when you wrap your elements inside a element, and you used the submit event to submit the form.
And if you're using <FormControl>, but the required prop on both elements:
<FormControl required>
<Select required>
// ...
</FormControl>

Categories

Resources