Set focus on input - React Component - javascript

I have a react component which has a input field with disable attribute. On click of the component, the input gets enabled and user can type on the field. I'm able to achieve till there, but I need to focus on input field on getting enabled.
Attributes.js
basicAmenitiesList.map(function(item, index){
return <Attribute key={index}
name={item.amenity_id}
type={item.title}
icon={item.icon}
selected={item.isSelected}
value={item.value}
onClick={_this.handleClick.bind(this)}
onChange={_this.handleChange.bind(this)}/>
})
The Attribute file :
<div onClick={this.handleClick.bind(this)}>
...
<input type="text" name={this.props.name}
ref={this.props.name}
placeholder="NO INFO FOUND"
value={this.props.value}
disabled={!this.props.selected}
onChange={this.props.onChange}
/>
</div>
handleClick(e) {
// I need to focus on enabling., that is when **this.props.selected** is true.
return this.props.onClick(this.props.name);
}
UPDATE
I tried onFocus for input,
onFocus(){
this.refs.pets.focus();
}
Right now I'm hard coding the refs name as pets, but is there any way to make it dynamic by sending the name with the onFocus?

you can use autoFocus as property for input
<input type="text" name={this.props.name}
ref={this.props.name}
placeholder="NO INFO FOUND"
value={this.props.value}
disabled={!this.props.selected}
onChange={this.props.onChange}
autoFocus
/>

Related

How to change formik <Field/> component's placeholder?

Basically I'm not able to make date input empty with Formik. I just want it to show nothing initially. This is what I've been dealing for hours.
<Field
name="date"
type="date"
className={`InformationForm__field text-[20px] lg:h-14 px-4 lg:py-4 py-3 outline- none
`}
/>
note: I've tried placeholder, giving empty string as initial value etc.
Anyone have idea?
Yo can try below code
<Field
name="date"
render={({ field, form: { isSubmitting } }) => (
<input {...field} type="date"
placeholder="date" />
)}
/>
Check this link for more info:- https://formik.org/docs/api/field#render
Searching on docs I've found this prop initialValues, try that one.
Reference

React datepicker disable entering date manually

I am using React date-picker for my form. Currently it's working well, but the user can delete the date and enter whatever values. How do I restrict it?
This is my code:
import DatePicker from "react-datepicker";
<DatePicker
name="invoiceDate"
className="form-control form-control-sm"
type="text"
size="sm"
placeholder=""
selected={date}
minDate={new Date()}
value={values.setDate}
onChange={datePickerChange}
dateFormat="dd/MM/yyyy"
/>
Just add this line of code to DatePicker :
onKeyDown={(e) => {
e.preventDefault();
}}
After adding this event, your component's code will be like the below code :
<DatePicker
name="invoiceDate"
className="form-control form-control-sm"
type="text"
size="sm"
placeholder=""
selected={date}
minDate={new Date()}
value={values.setDate}
onChange={datePickerChange}
dateFormat="dd/MM/yyyy"
onKeyDown={(e) => {
e.preventDefault();
}}
/>
I think onBeforeInput should be used in this case, as opposed to onKeyDown.
So just simply:
onBeforeInput={(e) => {
e.preventDefault();
}}
The reason being, that onKeyDown prevents a lot of 'normal' functionality from working when the input is focused. E.g.:
Page reload with CTRL + R
Opening devtools with F12
Going to the next input with Tab
And in case of ReactDatePicker, the customInput property has to be used to pass in an input that has onBeforeInput overridden as explained.

React - Draggable components with inputs lose the ability to focus when clicking that input

<Draggable axis="y"
grid={[135,135]}
onStop={this.handleStop}
defaultPosition={{x: this.props.task.positionX, y: this.props.task.positionY,}}>
<div id="edit-task-component">
<form onSubmit={this.handleSubmit} id="edit-task-form" className="edit-task-form">
<input type="text" name="name" onChange={this.handleChange} placeholder="Name" value={this.state.name} required/>
<input type="text" name="description" onChange={this.handleChange} placeholder="Description" value={this.state.description} required/>
<button className="btn submit-btn" type="submit">Save </button>
</form>
</div>
</Draggable>
What happens is I will click on the input and it will focus for a split second then loses focus -- so i cant type in the input. I have to click on it a few times for it to actually focus, therefore allowing me to type in the input. How can I get it to stay focused after clicking once? I have tried setting autofocus to true after clicking the input but that didnt work either. Any ideas ?
Use enableUserSelectHack, this will not interfere with existing style
eg <Draggable enableUserSelectHack={false}>
Use cancel prop
eg: give any class name, it doesn't matter
<Draggable cancel=".just-name">
<input className="just-name" placeholder="Add text here" />
</Draggable>
Via a handle to enable drag is better and you can also avoid this kind of issue easily.
Here is the demo given by the official doc:
return (
<Draggable
axis="x"
handle=".handle"
start={{x: 0, y: 0}}
grid={[25, 25]}
zIndex={100}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}>
<div>
<div className="handle">Drag from here</div>
<div>This readme is really dragging on...</div>
</div>
</Draggable>
);
check its doc
the handle here is a CSS selector

Submit Form using Button in Parent Component in React

So I have to implement a form in modal, as you can see, the button in the modal are not the buttons in the form. I created the form as a child component of the modal. How can I submit the form using the button in the parent component. I am using React Semantic-UI react as my UI framework.
I think if I can hide the button in the form and trigger it using JavaScript. I think this might be achieved via getElementById, but is there a react way of doing it?
My current Modal looks like this:
<Modal open={this.props.open} onClose={this.props.onClose} size="small" dimmer={"blurring"}>
<Modal.Header> Edit Activity {this.props.name} </Modal.Header>
<Modal.Content>
<ActivityInfoForm/>
</Modal.Content>
<Modal.Actions>
<Button negative onClick={this.props.onClose}>
Cancel
</Button>
<Button positive
content='Submit'
onClick={this.makeActivityInfoUpdateHandler(this.props.activityId)} />
</Modal.Actions>
</Modal>
My form code looks like this:
<Form>
<Form.Group widths='equal'>
<Form.Input label='Activity Name' placeholder='eg. CIS 422' />
<Form.Input label='Activity End Date' placeholder='Pick a Date' />
</Form.Group>
<Form.Group widths='equal'>
<Form.Input label='Total Capacity' placeholder='eg. 30' />
<Form.Input label='Team Capacity' placeholder='eg. 3' />
</Form.Group>
</Form>
The simplest solution would be to use HTML form Attribute
Add "id" attribute to your form: id='my-form'
<Form id='my-form'>
<Form.Group widths='equal'>
<Form.Input label='Activity Name' placeholder='eg. CIS 422' />
<Form.Input label='Activity End Date' placeholder='Pick a Date' />
</Form.Group>
<Form.Group widths='equal'>
<Form.Input label='Total Capacity' placeholder='eg. 30' />
<Form.Input label='Team Capacity' placeholder='eg. 3' />
</Form.Group>
</Form>
Add the appropriate "form" attribute to the needed button outside of the form: form='my-form'
<Button positive form='my-form' content='Submit' value='Submit' />
What does your makeActivityInfoUpdateHandler function look like?
I assume you did it by the following way, and just continue adding more code to make it work for you:
1/ Add ref to your Form, then you can access the Form in the parent (Modal):
<Modal>
<Modal.Content>
<ActivityInfoForm ref="activityForm" />
</Modal.Content>
</Modal>
2/ Then in the makeActivityInfoUpdateHandler function:
makeActivityInfoUpdateHandler = (activityId) => {
// ...
this.refs.activityForm.getWrappedInstance().submit();
// ...
}
The above code is the way you should do, please post here some more details in case this doesn't work yet!
===========
EDITED VERSION BELOW: (after discussion with the author, and we together found a good way around!):
The idea now is put the ref on a button (this button has type="submit", and it belongs to the form), then when the button outside is clicked, we just need to call the "click()" function of the ref button [which is a smart thinking from the author himself]
(Actually, component from semantic-ui is a modified and improved version, no longer the standard form, so my previous way above may not work when it tries to submit the form, however, the below way will work)
The code will now look like:
1/ Add ref to the button on the form:
<Form onSubmit={ this.handleSubmit} >
<button style={{}} type='submit' ref={ (button) => { this.activityFormButton = button } } >Submit</button>
</Form>
2/ Then in the makeActivityInfoUpdateHandler function, trigger click() of the above button:
makeActivityInfoUpdateHandler = (activityId) => {
// ...
this.activityFormButton.click();
// ...
}
The selected answer was useful. But the method in it doesn't seem to work any longer. Here's how I went about it.
You can give a ref to the child component when it is being created.
<ChildComponent ref={this.childComponent}/>
And use it in the button's onClick method. (This is the code for the button)
<Button variant= "light" onClick={this.onClick}>
Submit
</Button>
(This is the onClick method)
onClick = (event) => {
this.childComponent.current.handleSubmit(event);
}
I'm calling a method in the child component called handleSubmit. It can look like this.
handleSubmit = (event)=> {
event.preventDefault();
//Your code here. For example,
alert("Form submitted");
}

Date field does not appear properly In react

I have one input field whose type is date and placeholder is "Enter your date". But what happened was placeholder does not show up in the mobile app. (we are building the mobile app using html, css, bootstrap and react.js and porting via cordova"). So I am following this link, to get the label appeared and when clicked date pop should appear. But this seems to be not working, when inspected the element in chrome, onfocus and onblur seem to be disappearing. Is there anyway to make it work in react.
<ElementsBasket name='nextActionDate'
data={this.props.newLead.get('actions').get('nextActionDate')}>
<div className="form-group">
<input type="text" className="form-control" onfocus="(this.type='date')" onblur="(this.type='date')"
placeholder="Type your date here.."
value={this.props.newLead.get('actions').get('nextActionDate')}
onChange={onFieldChanged.bind(this, 'actions.nextActionDate')}
/>
</div>
</ElementsBasket>
ps: I am following this link
Not showing placeholder for input type="date" field
In React your events should be called onFocus and onBlur (note capitalisation)
https://facebook.github.io/react/docs/events.html
edit:
The other issue is that you are setting the handlers to a string - onFocus="(this.type='date')" and they should be a function. So set them like you set your onChange event -
<input type="text" onFocus = {this._onFocus} onBlur={this._onBlur}
Now this refers to the object that contains your render function so you need to implement the appropriate function in that object.
eg.
_onFocus: function(e){
e.currentTarget.type = "date";
},
_onBlur: function(e){
e.currentTarget.type = "text";
e.currentTarget.placeholder = "Enter a Date";
},
this is simpler
<input
type="text"
onFocus={
(e)=> {
e.currentTarget.type = "date";
e.currentTarget.focus();
}
}
placeholder="dd/mm/yyyy"
/>
Basically the date type appears with default placeholder i.e. mm/dd/yyyy, that's why our placeholder attribute is not displayed as it is in text type.
So we can use event handlers onFocus and onBlur to make it work.
We can add these handlers in arrow function structure like this -
<input
type="text"
onFocus={(e) => (e.currentTarget.type = "date")}
onBlur={(e) => (e.currentTarget.type = "text")}
placeholder="No date found"
/>
output will be like this
ReactDOM.render(
<input
type="text"
className="form-control"
onFocus={(e) => (e.currentTarget.type = "date")}
onBlur={(e) => (e.currentTarget.type = "text")}
placeholder="No date found"
/>,
document.getElementById("react")
);
.form-control {
padding: 10px;
font-size: 18px;
}
<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="react"></div>
Hope it helps you, thanks
Obviously you can't bring in the place holder when the input type is Date , one way to solve this issue is dynamically changing the input type on-focus , but that is not a good practice , my suggestion is not to go with the default date pickers instead you can use the drop downs
You can also refer this question .Hope this helps you :)
<input
type="text"
className="form-control"
onFocus={(e) => (e.currentTarget.type = "date")}
onBlur={(e) => (e.currentTarget.type = "text")}
placeholder="plz select your date"
/>

Categories