I use this package https://www.npmjs.com/package/react-step-wizard to animate between forms. Each form is separated components.
How to set focus to input in active form after done slide animation?
Did you try in componentdidmount?
Something like this?
class App extends React.Component{
componentDidMount(){
this.nameInput.focus();
}
render() {
return(
<div>
<input
defaultValue="Won't focus"
/>
<input
ref={(input) => { this.nameInput = input; }}
defaultValue="will focus"
/>
</div>
);
}
}
Related
There is a input text in center in which I want to focus when the page loads, so I have used componentDidMount() and set the focus.
componentDidMount() {
this.inputBar.focus();
}
.
.
<input type="text" ref={(element) => { this.inputBar = element; }}>
but it isn't working as a sidebar pops in as the page loads and shifts the focus from the center input.
I tried to use componentDidUpdate() but then it triggers the focus again and again when I close the sideBar. I only want to focus only at first time when I load the page.
I am new at coding, please suggest something that can be done here.
Thanks in advance.
you have to create ref , then in your lifecycle method use that ref, you have forgotten to use current when you are using ref in lifecycle method, your code will be like this:
class GroupDetail extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
}
componentDidMount(){
this.ref.current.focus()
}
render(){
return(
<input type="text" ref={this.inputRef}/>
)
}
}
If you want to focus a single Input then you can simply do
<input type="text" autofocus>
If you just want to focus an element when it mounts (initially renders) a simple use of the autoFocus attribute will do.
<input type="text" autoFocus />
Or if you want to do it with componentDidMount and to control focus dynamically you can go with the below snippet
class App extends React.Component{
componentDidMount(){
this.nameInput.focus();
}
render() {
return(
<div>
<input defaultValue="Won't focus"/>
<input ref={(element) => { this.nameInput = element; }} defaultValue="will focus"/>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
I have a ReactJs function that displays a simple dialogue box, and is intended to update a value for the parent component. The function looks like this:
export function MyDialogue(props: IMyProps) {
var myValue = 0;
return (
<div style={style}>
<label>Enter a number here: </label>
<input type="text" value={myValue} />
<button onClick={() => props.updateFunc(myValue)}>Update</button>
</div>
);
}
I've tried several variations of this; for example, passing in props.myValue, and even changing the function to a class and passing this.state.myValue in. In all but this example, myValue remains as it was in the parent class, and in this version, always 0.
updateFunc simply calls setState on the parent class, and having traced through it, it never gets called with the changed value.
I've seen some documentation that says to essentially handle the onChange event - is this the only way to make this work, or is there a way to implement data binding in React?
Just bind back your input to the parent's state via props.value;
MyDialogue.js
export function MyDialogue(props: IMyProps) {
return (
<div style={style}>
...
<input type="text" value={props.value} />
...
</div>
);
}
Parent.js
....
render(){
const { dialogueValue } = this.state;
return <MyDialuge value={dialogueValue} updateFunc={this.handleUpdate} />
}
You are using uncontrolled input because You are not keeping value of input inside state.
Solution is
With uncontrolled:
export class MyDialogue extends React.Component<IMyProps, {}>{
constructor() {
super();
this.input = React.createRef();
}
return (
<div style={style}>
<label>Enter a number here: </label>
<input type="text" ref={this.input} />
<button onClick={() => props.updateFunc(this.input.current.value)}>Update</button>
</div>
);
}
With controlled:
Maintain myValue state in parent and pass it to child.
and on change on input event call a function of parent which change myValue using setState,
Maintain myValye state inside MyDialogue and onClick pass it to parent.
You need to change this component to a stateful component
then do a two-way binding for your textbox and have it talk to local state and then use that state value to update parent component.
export class MyDialogue extends React.Component<IMyProps, {}>{
constructor() {
super();
this.state = {
myValue: 0
}
}
onChangeHandler = (event:any) =>{
this.setState({myValue:event.target.value});
}
return (
<div style={style}>
<label>Enter a number here: </label>
<input type="text" value={this.state.myValue} onChange={this.onChangeHandler}/>
<button onClick={() => props.updateFunc(this.state.myValue)}>Update</button>
</div>
);
}
I have a component in a React class in my Laravel project which is a simple form with one input field. It houses a phone number which I have retrieved from the database and passed back through the reducer and into the component as a prop. Using this, I have passed it through to the module as a prop which then populates the field with the currently saved value:
<OutOfOfficeContactNumberForm
show={props.showOutOfOffice}
value={props.outOfOfficeNumber}
handleChange={console.log("changed")}
/>
I have a handleChange on here which is supposed to fire a console log, but it only ever displays on page load. Here is my form module class:
class OutOfOfficeContactNumberForm extends React.Component {
render() {
const { show, value, handleChange } = this.props;
if(!show) return null;
return (
<div>
<p>
Please supply an Out of Office contact number to continue.
</p>
<InputGroup layout="inline">
<Label layout="inline" required={true}>Out of Office Contact Number</Label>
<Input onChange={handleChange} value={value} layout="inline" id="out-of-office-number" name="out_of_office_contact_number" />
</InputGroup>
</div>
);
}
}
export default (CSSModules(OutOfOfficeContactNumberForm, style));
The form is embedded in my parent component, as follows:
return (
<SectionCategoriesSettingsForm
isSubmitting={this.state.isSubmitting}
page={this.props.page}
show={this.props.show}
categories={this.props.categories}
submitSectionCategoriesSettings={this._submit.bind(this, 'add')}
updateSelectedCategories={this._updateSelectedCategories.bind(this)}
selectedCategoryIds={this.state.selectedCategoryIds}
storedUserCategories={this.props.selectedCategories}
outOfOfficeNumber={this.state.outOfOfficeNumber}
onUpdateContactNumber={this._updateContactNumber.bind(this)}
/>
);
In my componentWillReceiveProps() function, I set the state as follows:
if (nextProps.selectedCategories && nextProps.selectedCategories.length > 0) {
this.setState({
outOfOfficeNumber: nextProps.outOfOfficeNumber,
selectedCategoryIds: nextProps.selectedCategories.map(c => c.id)
});
}
I'm pretty sure the reason it's not changing is because it's pre-loaded from the state which doesn't change - but if I cannot edit the field how can I get it to register a change?
EDIT: Just to clarify there are also checkboxes in this form for the user to change their preferences, and the data retrieved for them is set the same way but I am able to check and uncheck those no problem
Changes:
1- onChange expect a function and you are assigning a value that's why, put the console statement inside a function and pass that function toOutOfOfficeContactNumberForm component , like this:
handleChange={() => console.log("changed")}
2- You are using controlled component (using the value property), so you need to update the value inside onChange function otherwise it will not allow you to change means input values will not be not reflect in ui.
Check example:
class App extends React.Component {
state = {
input1: '',
input2: '',
}
onChange = (e) => this.setState({ input2: e.target.value })
render() {
return(
<div>
Without updating value inside onChange
<input value={this.state.input1} onChange={console.log('value')} />
<br />
Updating value in onChange
<input value={this.state.input2} onChange={this.onChange} />
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app' />
I think the best way is when you get data from database put it to state and pass the state to input and remember if you want to see input changes in typing, use a function to handle the change and that function should change state value.
class payloadcontainer extends Component {
constructor(props) {
super(props)
this.state = {
number:1
}
}
render() {
return (
<div>
<input value={this.state.number} onChange={(e)=>this.setState({number:e.target.value})}></input>
<button onClick={()=>this.props.buyCake(this.state.number)}><h3>buy {this.state.number} cake </h3></button>
</div>
)
}
}
I am building a small feature that has a checkbox styled as slider that, when turned on and off, should display another component - BatchWidget. The way I have it currently set up, it works on initial page load, and then hides as intended. However, when I go to "toggle" it back on to show the component again, it does not work. Is there an easy solution to this?
const Slider = (props) => {
return (
<div className="slider-container">
<label className="switch">
<input type="checkbox" checked={props.checked} onClick= {props.showWidget} />
<span className="slider round" />
</label>
<p className="batch-slider-title"> Batch Widget </p>
</div>
);
};
const Settings = ({showSlider}) => {
return (
<div className="settings">
<i className="icon-gear" onClick={() => showSlider()} />
</div>
);
}
class WidgetContainer extends Component {
constructor() {
super();
this.state = {
checked: true,
isSliderDisplayed: false,
};
this.showWidget = this.showWidget.bind(this);
this.showSlider = this.showSlider.bind(this);
}
showWidget() {
this.setState({
checked: !this.state.checked,
});
}
showSlider() {
this.setState({
isSliderDisplayed: !this.state.isSliderDisplayed,
});
}
render() {
const displayBatchWidget = this.state.checked ? <BatchWidget /> : null;
const displaySlider = this.state.isSliderDisplayed ? <Slider checked={this.state.checked} showWidget={this.showWidget} /> : null;
return (
<div>
<Settings showSlider={this.showSlider} />
{displaySlider}
{displayBatchWidget}
</div>
);
}
}
When I try to debug, it shows:
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 `Slider`.
I think it is self-explanatory.
I've changed the line with checkbox to:
<input type="checkbox" checked={props.checked} onChange= {props.showWidget} />
Now, the batchWidget should hide and show on each click.
Reactjs matrial ui table check box hide
first do
<Table selectable={false}>
<TableHeader displaySelectAll={false} adjustForCheckbox={false}>
this method hide table header check box
then do <TableBody displayRowCheckbox={false}>
it hide table body checkbox
it work perfect.
reactjs
How to set focus to an input element when it enters the DOM?
Scenario
When a button is clicked the input element is displayed. How to set the focus to this element?
Code-Snippet
class Component extends React.Component{
constructor(props) {
super(props);
this.state = {
showInput: false
}
}
render() {
return (
<div>
<div onClick={() => {
this.setState({showInput: true});
ReactDOM.findDOMNode(this.refs.myInput).focus() // <- NOT WORKING
}}>
Show Input
</div>
{
(this.state.showInput) ? (
<input
type="text"
ref="myInput"
/>
) : ""
}
</div>
);
}
}
Calling ReactDOM.findDOMNode(this.refs.myInput).focus() after state change does not work. Also changing just the style or type property on state change does not work.
Assuming you only need one visible input on the page at a time to have autofocus Poh Zi How's suggestion of using the autofocus is probably the simplest.
<input type="text" autofocus/>
should do the trick, no JS needed!
In the componentDidMount and componentDidUpdate hooks do this:
ReactDOM.findDOMNode(this.refs.myInput).focus()
you should use ref
<input ref={(input) => { this.inputSearch = input; }} defaultValue="search ... " />
and use this code for focus
this.inputSearch.focus();
I had to define the variable as HTMLInputElement 1st...
private inputSearch: HTMLInputElement;
And then add this into the control:
ref={(input) => { this.inputSearch = input; }}
THEN I could get this to build/work:
this.inputSearch.focus();
From the docs:
"findDOMNode only works on mounted components (that is, components that have been placed in the DOM). If you try to call this on a component that has not been mounted yet (like calling findDOMNode() in render() on a component that has yet to be created) an exception will be thrown."
As mentioned by Piyush.kapoor, you need to place that incomponentDidMount and/or componentDidUpdate.