React-bootstrap FormControl Select placeholder - reactjs

Trying to set up a control for a select field but even with placeholder set it still always auto selects the first item in the list.
It looks like this...
export function renderSelector({input, label, placeholder, meta:{touched, warning, error}, title, mandatory, fieldValues, fieldItemKeyFunc, fieldItemLabelFunc, props}) {
const mappedData = fieldValues.map(v => ({Id: fieldItemKeyFunc(v), Name: fieldItemLabelFunc(v)}));
let custom = props || {};
return (
<FormGroup controlId={input.name} validationState={touched && error ? 'error' : null}>
<Col xs={12}>
{renderLabel(title, label, mandatory)}
</Col>
<Col xs={12}>
<FormControl componentClass="select" placeholder={placeholder} name={input.name} {...input} {...custom}>
{
mappedData.map((item, index) => {
return (
<option key={index} value={item.Id}>{item.Name}</option>
)
})
}
</FormControl>
<FormControl.Feedback/>
{renderErrBlock(touched, warning, error)}
</Col>
</FormGroup>
);
}
When this renders the selector always starts with the first item selected, instead of the placeholder. How can I fix this?? I tried just adding a default first option and adjusting the css, but for Accessibility that doesn't work that well because the contrast levels

A bit late, but check if adding this option helps you:
<option key='blankChoice' hidden value />
Make sure to check the form value to a blank choice as well:
<Form.Control
value=''
>

You can do something like this:
Add a
<option disabled value={-1} key={-1}>
, and set your
<FormControl value={-1} ...
for a similar effect.

Just dropping a late answer, in case someone finds this useful.
React Bootstrap's Form as='select' doesn't seem to allow placeholder out of the box. Adding a blank value to Form.Control would render the input useless. Adding an extra option above mappedData.map(), as follows would work:
<option key = 'blankChoice' hidden value> --Your placeholder text-- </option>

Related

Create Multiple Select Using Bootstrap Form.Control

I'm trying to create a select using React.Form from React-Bootstrap. I expected something like this(this ss is from react-bootstrap-multiselect):
But I got this kind of result:
This is my code:
<Form.Control
required
as="select"
type="select"
id="instructors"
value={instructors}
onChange={handleChange}
multiple
>
<option hidden value key="blankChoice">
Pilih Instruktur...
</option>
{items
? items.map((item, index) => {
return <option value={item.id}>test{index}</option>;
})
: null}
</Form.Control>
Actually I can just use React-Select library, but I try not using too many libraries, and since I already use React-Bootstrap, it will be take another effort to match the style with another library that I will use.
Thanks!

react-bootstrap how to use custom form control component

I need to add select input in my form, but there are too many options, so the default way to do it looks really ugly(
<Form.Control as="select">
{props.options.map(
(o) => <option>{o}</option>
)}
</Form.Control>
So I've decided to use react-bootstrap-typeahead because it's already being used in my project and it supports search. However, it didn't work properly in that case.
<Form>
<Form.Group>
<Form.Label>Provider</Form.Label>
<Form.Control
as={Typeahead}
id="id"
options={props.options}
/>
</Form.Group>
</Form>
It looks like this:
Might I've done it not properly, but I can't figure out how to do it in another way(
https://react-bootstrap.github.io/components/forms/#form-control-props
Ther has a props "as". See exemle bellow.
export default function Input(props) {
const CustomFormControl = React.forwardRef(({ children, onChange}, ref) => (
<>
<p>Insert your elements for yout form</p>
<p>{props.test}</p>
</>
));
return (
<>
<Form.Control
as = {CustomFormControl}
test = {"hellow world"}
/** and here u can inser the props you need **/
/>
</>
}

Material-ui's Menu Item not working with a Select within a redux-form Field (redux form 8.2)

I'm trying to create a select (dropdown) using Material-UI within a redux-form. There's an example for using M-UI's selects within a redux form on their website.
I'd like to do the same type of example except using Material UI's MenuItem's instead of the option tags used in the example.
It seems as though simply replacing the options with MenuItems does not work, and the MenuItems do not appear under the children for the select field. I have gotten this to work with options:
Here is the renderSelectField used to create the select component. This is working:
renderSelectField = ({ input, label, meta: { touched, error }, children, ...custom }) => (
<FormControl className={this.props.classes.formControl} error={touched && error}>
<InputLabel>{label}</InputLabel>
<Select
native
{...input}
{...custom}
>
{children}
</Select>
{this.renderFormHelper({ touched, error })}
</FormControl>
)
And here is the render:
render() {
return (
<div>
<form onSubmit={this.props.handleSubmit(this.props.submitForm)}>
<Field name={"sheetType"} component={this.renderSelectField} label={"Sheet Type"}>
<MenuItem value={"basic"} primaryText={"Basic"}>Basic</MenuItem>
<MenuItem value={"advanced"} primaryText={"Advanced"}>Advanced</MenuItem>
</Field>
<Button onClick={this.props.onCancel}>Cancel</Button>
<Button type="submit" color={"secondary"}>Next</Button>
</form>
</div>
)
}
I expect there to be two dropdown menu items passed in as the children of MenuItem, but i believe there needs to be some property passed into MenuItem itself.
Replacing menu item with option tags work.
You are mixing between simple Select and native Select. If you going to use native change <MenuItem> to <option> otherwise just remove native property.
Native pattern:
<Select native>
<option value="item">item</option>
</Select>
Simple Select pattern:
<Select>
<MenuItem value="item">item</MenuItem>
</Select>

Updating multi-select options from state doesn't trigger material_select so options don't appear

I am updating the options of the select based on the state of my component.
The state is initially set to an empty array but once loaded from an API, the state is updated so the options should update.
While this does happen (and can be seen in the dev tools), it looks like material_select needs to be called to update how it looks.
I can get this to appear correctly by calling $("select").material_select() from the console.
I think that the line causing the issue is here: https://github.com/react-materialize/react-materialize/blob/master/src/Input.js#L38
Is there a way that I can manually call this while inside my component?
Please note that I'm using create-react-app.
<Row>
<Input
id="categories"
type="select"
label="Categories"
multiple={true}
onChange={this.handleChange}
s={12}
>
{this.state.categories.map(category => {
return (
<option key={category._id} value={category._id}>
{category.name}
</option>
);
})}
</Input>
</Row>
You can fix the problem by rendering the Input component once your options arrive from API.
You can initailize your state as null as opposed to empty array:
state = {
categories: null;
}
So in your render method, render the component conditionally (only if options are available):
render() {
return (
<Row>
{this.state.categories ? (
<Input
id="categories"
type="select"
label="Categories"
multiple={true}
onChange={this.handleChange}
s={12}
>
{this.state.categories.map(category => {
return (
<option key={category._id} value={category._id}>
{category.name}
</option>
)
})}
</Input>
) : null}
</Row>
)
}

How to set focus on FormControl - Select? (react)

I have material-ui - select and would like to programmatically focus on this element.
<FormControl
className="select100">
<Select
ref={(formControll) => { this.formControll = formControll; }}
native
value={value}
input={<Input id="integer" />}
>
{possibleOptions.map((item, key) => {
return (<option value={item} key={key}>{item}</option>)
})}
</Select>
I tried with the ref and write this.formControll.focus(); but react is telling me that focus() is not a function. With a button for example the ref is working.
PS: I don't need autoFocus
Thanks
You can pass the Input inside the Select the autoFocus prop and this will apply to the Select.
<Select
native
value={value}
input={<Input id="integer" autoFocus={true} />}
>
{possibleOptions.map((item, key) => {
return (<option value={item} key={key}>{item}</option>)
})}
</Select>
Edit
When i posted the answer i have missed the part that you don't need the autoFocus.
If you are using an input inside your Select then you can use the inputRef prop and this will focus the underline input "attached" to the select.
Code example and Docs.
<Select
ref="selectRef"
native
value={value}
input={<Input id="integer" />}
>
{possibleOptions.map((item, key) => {
return (<option value={item} key={key}>{item}</option>)
})}
</Select>
To access, use
this.refs.selectRef.focus()
Here's a reference github link

Resources