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"}
Related
I had a form component with the following content
function Form() {
return (
<div className="form-container">
<div className="form-control">
<label id="text-input">Text </label>
<input type="text"></input>
</div>
<div className="form-control">
<label>Time </label>
<input type="text"></input>
</div>
<div className="form-control" style={{alignItems:"center"}}>
<button className="add-but">Add</button>
</div>
</div>
)
}
I wanted to focus the text element after the component gets rendered.
I was first trying to put {document.querySelector("#txt-in").focus()}, it didn't work and after searching I found I could use the tag autoFocus. and everything would work beautifully.
But I was wondering, what if I want to actually execute javascript code after rendering? or actually do this in javascript? I found answers for class based components but couldn't find for function based components like the one I am using.
how do I execute code I want executed after the element is rendred, in function based components?
You can use React Hooks useEffect for your purpose.
Simply put below code
import React, {useEffect} from "react";
function Form() {
useEffect(() => {
// Do whatever you want after first render
// Put your code here
}, [])
}
Similar to what the components are writing, previously one would use functions likecomponentDidUpdate & componentDidMount to manipulate components after/before being rendered. Funcitonal components realised we could use one 'hook' for this called useEffect where one can trigger a particular action to occur on the basis of a state change to the component.
Here is a link to the docs for useEffect - https://reactjs.org/docs/hooks-effect.html
I have created a VueJS component for dropdown.
<template>
<div>
<select v-bind:value="value" v-on:input="$emit('input', $event.target.value)">
<option v-for="(option, index) in dropdownOptions"
v-bind:key="index">
{{ option }}
</option>
</select>
</div>
</template>
<script>
export default {
props: {
dropdownOptions: Array,
value: String
},
mounted() {
this.value = this.dropdownOptions? this.dropdownOptions[0] : "";
}
}
</script>
And I have used it in parent as -
<div id="selectvideodropdown" class="col">
<Dropdown v-bind:dropdown-options="allVideos" v-model="selectedVideo">
</Dropdown>
</div>
<div id="selectvideodisplaymode" class="col">
<Dropdown v-bind:dropdown-options="allDisplayMode" v-model="selectedDisplayMode">
</Dropdown>
</div>
Parent's script -
<script>
import VideoPlayer from "./Videoplayer.vue"
import Dropdown from "../shared/Dropdown.vue"
export default {
components: {
VideoPlayer,
Dropdown
},
data() {
return {
allVideos: ["Video 1", "Video 2", "Video 3"],
allDisplayMode: ["With Bounding Box", "Without Bounding Box"],
selectedVideo: "",
selectedDisplayMode: "",
}
}
};
</script>
Weirdly, when I select the dropdown, it changes the current value of other dropdown to empty string. It only happens once after page load, and is not repeated again.
There are several issues here.
So, first, I’d recommend reading this which should help illuminate how v-model works.
Now, notice that v-model basically creates a two-way binding between data and a value attribute.
There’s a lot going on all at once, but the basic gist of it is that you’ve got data in your parent component that’s being bound to the value, but when you initialise each component you’re manually setting the value. When Vue updates everything, it ends up resetting the bound attribute in the other dropdown to the value being passed in from its v-model, which happens to be the empty string.
However, as a commenter mentioned, you’re also altering a property in the child component as if it were a data attribute, which is a very bad idea. Make that a separate data value.
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
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.
I have created a select dropdown component, which I am using in a redux-form in a react-redux app. The dropdown works great, and I have no impact to performance, but in the browser I receive the following warning.
Warning: validateDOMNesting(...): <span> cannot appear as a child of <select>.
I am not sure why I recieve this error, as I am not passing in any <span> elements. Here is the code I am using to create the select dropdown (options is an array of object that contains each option's attributes. option.text is a string value that will be viewed by the user. so it could be something like 'Option 1' or 'Option 2'.)
return (
<select {...other}>
<option /> {
options.map((option) => {
return <option key={option.value} value={option.value}>{option.text}</option>
})
} </select>
)
Any ideas on why I would be receiving this warning, and how I can rectify this. I am using react 0.14.3
It seems that some extra spaces in your jsx syntax have created a span.
I've tested your code, and after a correct re-indentation the error disappeared.
Before with the error: https://jsfiddle.net/snahedis/69z2wepo/28561/
And after re-indentation: https://jsfiddle.net/snahedis/69z2wepo/28564/
You have a variable re-definition issue. Your map function parameter is called "option", so when you write <option>, react would try to treat the object referred by the variable option as a react class. Try this instead -
return (
<select {...other}>
<option /> {
options.map((optionNode) => {
return <option key={optionNode.value} value={optionNode.value}>{optionNode.text}</option>
})
} </select>
)