why selected option is hidden in react? - javascript

I made a simple demo of form using react material, in which I have only one select field .I used this link to make select option
https://material-ui.com/demos/selects/
using api I am able to show label at top (using this shrink={true})and show disabled value using this displayEmpty.
so my form look like this without any validation
https://codesandbox.io/s/8x4wnjnrz8
Now i try to validate my form using this plugin
https://www.npmjs.com/package/react-material-ui-form-validator
but my default option is hidden and select box label is also look awkward and with become small
here is my code
https://codesandbox.io/s/8x4wnjnrz8
import ReactDOM from "react-dom";
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import Input from "#material-ui/core/Input";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormHelperText from "#material-ui/core/FormHelperText";
import { FormControl, Button } from "#material-ui/core";
import Select from "#material-ui/core/Select";
import "./styles.css";
import {
ValidatorForm,
TextValidator,
SelectValidator
} from "react-material-ui-form-validator";
function App() {
return (
<div className="App">
<ValidatorForm onSubmit={() => {}} className="" autoComplete="off">
<FormControl>
<InputLabel shrink={true} htmlFor="age-simple">
Age
</InputLabel>
<SelectValidator
required
value=""
name="name"
displayEmpty
validators={["required"]}
errorMessages={["this field is required", "email is not valid"]}
inputProps={{
name: "age",
id: "age-simple"
}}
input={<Input id="age-simple" />}
className=""
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</SelectValidator>
</FormControl>
<Button type="submit"> submit</Button>
</ValidatorForm>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

You have three issues that are preventing your select component from working properly.
You've created a functional (stateless) component. Learn More.
The dropdown component is not provided an onChange, so when you're selecting an option, the component is not doing anything to register this new state.
Even if you were storing the dropdown state using an onChange, you're passing a null value={} to your component.
Here's a working solution which contains solutions to those three issues:
https://codesandbox.io/s/j2855wrmq5
Notice that I've converted your functional component to a Class. You can read more about the conversion process here.
Now that your component is a Class, it can have state. This means two things, we're now handling the onChange event by setting our state to the provided value, and we're injecting this value into our component so it can display your selection value.

If I understand your issue correctly,
You are unable to see the default value (i.e. None) as selected.
Label is messed up.
Below are the reason(s):
The selected value you have mentioned is empty string (""). Change it to a valid value (Non Empty).
But the tweak here is if you have a default value, the validator passes as the set has a valid value. Not sure why you are trying to get the validator in this situation.
The way the validator works is slightly different. It accepts TextField component and renders it as select.
So label needs to be sent as props.
Below is the sample code (Adding external link as inbuilt snippet runner doesn't support)
Hope this helps

Related

MUI how to implement a free text filter with multiple values

I am trying to implement a free text filter view with MUI. The Autocomplete component already has that view implemented (when the 'multiple' attribute is set). But I don't want to choose values from a predefined list of options. I want to be able to enter free text sentences.
Any idea on how to implement that?
Thanks #RyanCogswell for this suggestion.
Attached are a link to the solution and the code below:
import * as React from "react";
import Autocomplete from "#mui/material/Autocomplete";
import TextField from "#mui/material/TextField";
export default function KeywordFilter() {
return (
<Autocomplete
multiple
freeSolo
id="keyword-filter"
options={[]}
getOptionLabel={(option) => option}
renderInput={(params) => (
<TextField
{...params}
variant="standard"
label="Filter Keywords"
/>
)}
/>
);
}

How to import Bootstrap components in React?

I'm trying to integrate checkboxes from bootstrap or reactstrap in React. I'm getting a common error, looked into relevant posts, still cannot figure it out. How do I fix this error:
Error Element type is invalid: expected a string (for built-in
components) or a class/function (for composite components) but got:
undefined. You likely forgot to export your component from the file
it's defined in, or you might have mixed up default and named imports.
Source of Error
The problem should be here in these two lines, which I'm not sure what it is.
import { InputGroup, InputGroupAddon, InputGroupText } from 'reactstrap';
import FormControl from 'react-bootstrap/FormControl';
If we'd remove these lines and the HTML copied below, it does not give any Error.
HTML
<div>
<InputGroup className="mb-3">
<InputGroup.Prepend>
<InputGroup.Checkbox aria-label="Checkbox for following text input" />
</InputGroup.Prepend>
<FormControl aria-label="Text input with checkbox" />
</InputGroup>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Radio aria-label="Radio button for following text input" />
</InputGroup.Prepend>
<FormControl aria-label="Text input with radio button" />
</InputGroup>
</div>
Demo
[Thanks! I'm new to React.]
prepend is one value of the addonType prop of InputGroupAddOn or InputGroupButton. it's not a property of the InputGroup import. InputGroup.Prepend is undefined, which is why React is complaining.
according to the reactstrap docs, you want this:
InputGroupAddOn.propTypes = {
tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
addonType: PropTypes.oneOf(['prepend', 'append']).isRequired,
className: PropTypes.string
};
InputGroupButton.propTypes = {
tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
addonType: PropTypes.oneOf(['prepend', 'append']).isRequired,
children: PropTypes.node,
groupClassName: PropTypes.string, // only used in shorthand
groupAttributes: PropTypes.object, // only used in shorthand
className: PropTypes.string
};
In your component you camelcase inputGroupAddOn when declaring the prop types. When you imported it you didn't camel case the add on part, you're importing InputGroupAddon. That might be another issue you're having.
The Latest version of reactstrap doesn't support the use of InputGroupAddon. Use it directly from bootstrap.
<div className="input-group-append">
<span className="input-group-text" id="basic-addon2">Search</span>
</div>

React and Material CSS

I am using React and Material CSS.
I have a drop-down component ,like so
return (
<div>
<label>{label}</label>
<select {...input} className="browser-default">
<option />
{this.generateValues(indexes)}
</select>
</div>
);
}
}
I want to use the material-css look and feel ,but this component does not seem to work if I remove the "browser-default" className. How do I get around this ?
Try adding the Select initialization code into the componentDidMount() method.
componentDidMount(){
$('select').formSelect();
}
The better option would be to use the Input component with type 'select' from MaterializeCSS React component library.
You can use more than one className e.g.
className={"browser-default another-class"}

Where is the datepicker in material ui next?

I am try use next branch of material ui https://github.com/callemall/material-ui/tree/next. Because i want use layout component. But i can not find DatePicker component!
How use DatePicker in next branch?
import {DatePicker} from 'material-ui'
WARNING in ./app/Resources/js/components/FormConstructor/Field.js
208:47-57 "export 'DatePicker' was not found in 'material-ui'
Firstly, I am in the same boat. And I dearly miss the DatePicker from the stable release of material-ui (dated 10/04/2018). I too upgraded to the #next, at the moment at v1.0.0-beta.41 and reached the state of shock to not have found the elegant DatePicker.
This is what I have noticed and now changing to -
https://material-ui-next.com/demos/pickers/
It has a date picker, which is actually based out of the TextField component having the type set to "date".
Copying as is -
<TextField
id="date"
label="Birthday"
type="date"
defaultValue="2017-05-24"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
/>
A small suggestion would be to check if the path exists under the local node_modules. You can also quickly check the component catalogue (at https://material-ui-next.com/) for the version you are using.
Hope this helps.
At the moment to write this answer (2017-06-12) it's still not supported. See https://material-ui-1dab0.firebaseapp.com/getting-started/supported-components
As an alternative to the native controls you can use the Mobiscroll Calendar and Date picker.
Pretty customizable and comes with material styling that fits well with the general look & feel.
Calendar component
Date picker component
Full disclosure: this is a commercial component, and I am one of the makers, just though it could help someone looking for a solution.
Import as DatePickers, TimePickers, DateAndTimePickers in latest material-ui version V1.0.0-beta.26.
Eg:
import {DatePickers, TimePickers, DateAndTimePickers} from 'material-ui';
Importing Datepicker as like below is no more valid in latest version.
Eg:
import DatePicker from 'material-ui/DatePicker';
You can check out here where I did an example of creating a datepicker using material-ui (next branch)
You can either import the component or just check out the source code to learn how to create a datepicker on your own
use this
import DatePicker from 'material-ui/DatePicker';
also visit this link for completed details about material-ui date-picker.
Don't forget to install material-ui i.e npm install --save material-ui
sample code below
const DatePickerExampleSimple = () => (
<div>
<DatePicker hintText="Portrait Dialog" />
<DatePicker hintText="Landscape Dialog" mode="landscape" />
<DatePicker hintText="Dialog Disabled" disabled={true} />
</div>
);
export default DatePickerExampleSimple;

ReactJS error warning

I'm creating my first application with ReactJS and I found this warning when I run my code :
Warning: Failed form propType: You provided a checked prop to a form
field without an onChange handler. This will render a read-only
field. If the field should be mutable use defaultChecked. Otherwise,
set either onChange or readOnly. Check the render method of
Login.
Can someone tell me how I fix it please ?
React has 2 ways of working with form controls - Controlled Components and Uncontrolled Components
You get this warning when you don't supply the element neither the attributes needed for controlled nor those needed for an uncontrolled component:
Warning: Failed form propType: You provided a checked prop to a form
field without an onChange handler. This will render a read-only field.
If the field should be mutable use defaultChecked. Otherwise, set
either onChange or readOnly. Check the render method of Login.
Controlled Components
Attributes needed:
value - <input> (not checkbox or radio), <select>, <textbox> or checked for (checkbox or radio).
onChange
React handles the condition of the element by updating the value or checked attribute (depending on the element) from the props or the state. We need to notify react when we make a change, like inserting data, or checking the box, so react can update the element's condition when it rerenders the component. To do so, we must include an onChange handler, in which we will update the state or notify the component's parent, so it will update the props.
<input
type="checkbox"
checked={ this.props.checked }
onChange={ this.checkboxHandler }
/>
const { render } = ReactDOM;
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
checked: true
};
this.checkboxHandler = this.checkboxHandler.bind(this);
}
checkboxHandler(e) {
this.setState({
checked: e.target.checked
});
}
render() {
return (
<input
type="checkbox"
checked={ this.state.checked }
onChange={ this.checkboxHandler }
/>
);
}
}
render(
<Demo />,
document.getElementById('demo')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.1/react-dom.js"></script>
<h1>The Checkbox</h1>
<div id="demo"></div>
Uncontrolled Components
Attributes needed:
defaultValue - <input> (not checkbox or radio), <select>, <textbox> or defaultChecked for (checkbox or radio).
React sets the initial value using defaultValue or defaultChecked, and the update of the element's state is controlled by the user, usually via the DOM using refs.
<input
type="checkbox"
defaultChecked={ this.props.checked }
/>
The defaultChecked may not be updated if the component is re-rendered in future so use this approach with caution.
You may be better off just using a blank function to remove the warning. Especially if you want to handle click on the whole div which includes the checkbox and the associated text.
<div onClick={this.handleClick}>
<input type="checkbox" checked={this.props.checked} onChange={()=>{}}/>
{this.props.text}
</div>
You need to add defaultChecked attribute to your checkbox:
<div>
<input type='checkbox' defaultChecked />
</div>
For those that prefer a Functional Component instead of a Class Component this Controlled Component approach is simple and easy to implement. If you don't know what a Controlled Component is then please refer to #Ori Drori's well explained answer in this thread.
import {useState} from "react";
export default function YourComponentName(){
const [checked, setChecked] = useState(true);
return (
<>
<input
type="checkbox"
checked={checked}
onChange={() => setChecked(!checked)}
/>
</>
);
};
If your confronting with this warning, You can add "readOnly" to your input. like this code:
<div>
<input type='checkbox' checked={ props.checkBoxChecked } readOnly />
</div>
Or You can add an onChange event like an empty arrow function or what kind of function you care about to your input. like this:
<div>
<input type='checkbox' checked={ props.checkBoxChecked } onChange={() => {}} />
</div>
Also you must care about the value property, too.
This solution fixed my issue with the same warning, hope to be useful.

Categories

Resources