React - Focus on input using name - javascript

I have a component with input, is there any way to focus using the name?
<div onClick={this.handleClick.bind(this)}>
... Some more code ...
<input type="text" name={this.props.name} onChange={this.props.onChange} autoFocus/>
... Some more code ...
</div>
On click of the parent div, I have a on click event attached to it.
handleClick(e) {
// Need to focus may be using refs, but not sure how to do it.
return this.props.onClick(this.props.name);
}

Component:
<div onClick={this.handleClick.bind(this)}>
... Some more code ...
<input type="text" ref={(input) => { this.input = input; }} name={this.props.name} onChange={this.props.onChange} autoFocus/>
... Some more code ...
</div>
Click handler:
handleClick(e) {
this.input.focus();
return this.props.onClick(this.props.name);
}
or
Component:
<div onClick={this.handleClick.bind(this)}>
... Some more code ...
<input type="text" ref={this.props.name} name={this.props.name} onChange={this.props.onChange} autoFocus/>
... Some more code ...
</div>
Click Handler:
handleClick(e) {
this.refs[this.props.name].focus();
return this.props.onClick(this.props.name);
}

Related

How can Prompt be used to stop navigation on formik dirty state

I'm using formik in a reactjs project, and I want to use Prompt from react-router to open a notification before a user leaves and loses changes made to their submission.
I'd expected something like this to work:
<Prompt
when={formik.dirty}
message="You have unsaved changes. Are you sure you want to leave?"
/>
My formik block looks like this:
const formik = useFormik({
initialValues: {
<values>
},
enableReinitialize: true,
validate,
onSubmit: values => {
<submit functional stuff>
}
});
And my form is something like this:
<form id="myForm" onSubmit={formik.handleSubmit}>
<div className="row">
<div className="form-group">
<label htmlFor="name">Name</label>
<input
id="name"
type="text"
onChange={formik.handleChange}
value={formik.values.name}
className="form-control"
placeholder="Enter name"
disabled={isDisabled}
/>
{formik.errors.name ? <div className="text-danger">{formik.errors.name}</div> : null}
</div>
<div className="form-group">
<label htmlFor="subject">Subject</label>
<input
id="subject"
type="text"
onChange={formik.handleChange}
value={formik.values.subject}
className="form-control"
placeholder="Email subject"
disabled={isDisabled}
/>
{formik.errors.subject ? <div className="text-danger">{formik.errors.subject}</div> : null}
</div>
</div>
</form>
but it appears that formik.dirty is either not defined or it's not seen as true (despite making changes to the form).
How would I properly use the dirty prop to trigger the Prompt?
I am not sure what kind of setup you have, but I created a PoC with routing which has two tabs (links) for navigation and I am using prompt on tab with formik form component.
import React from "react";
import { Prompt } from "react-router-dom";
import { useFormik } from "formik";
const MyForm = () => {
const formik = useFormik({
initialValues: {
name: "",
subject: ""
},
enableReinitialize: true,
onSubmit: (values) => {
alert(JSON.stringify(values, null, 2));
},
onChange: (e) => {
console.log(e);
}
});
return (
<div>
<Prompt
when={!!formik.dirty}
message={(location) =>
`Are you sure you want to go to ${location.pathname}`
}
/>
<form id="myForm" onSubmit={formik.handleSubmit}>
<div className="row">
<div className="form-group">
<label htmlFor="name">Name</label>
<input
id="name"
type="text"
onChange={formik.handleChange}
value={formik.values.name}
className="form-control"
placeholder="Enter name"
/>
{formik.errors.name ? (
<div className="text-danger">{formik.errors.name}</div>
) : null}
</div>
<div className="form-group">
<label htmlFor="subject">Subject</label>
<input
id="subject"
type="text"
onChange={formik.handleChange}
value={formik.values.subject}
className="form-control"
placeholder="Email subject"
/>
{formik.errors.subject ? (
<div className="text-danger">{formik.errors.subject}</div>
) : null}
</div>
{formik.dirty && <button tye="submit">Save</button>}
</div>
</form>
</div>
);
};
export default MyForm;
take a look the this codesandbox.

Why this onSubmit not calling its function?

Whats wrong with this Form , when i click submit button the signInSubmitHandler() function is not called , i tested it with a simple Button with onClick and it works but if i use Form with submit button it doesnt work. (im using reactjs)
in SignInForm.jsx file:
const SignInForm = (props) => {
return (
<React.Fragment>
<h1>Welcome to ToDo</h1>
<form onSubmit={props.signInSubmitHandler} className={style.signInForm}>
<div className={style.signInFormImportantElements}>
<span className={style.userFormsErrors}>{props.userEmailError}</span>
<input
name="userEmail"
type="email"
placeholder="email"
value={props.currentUserEmailText}
className={style.signInText}
onChange={(e) => {
props.signInOnChangeHandler(e);
}}
onBlur={(e) => props.signInOnBlurHandler(e)}
/>
<span className={style.userFormsErrors}>{props.userPasswordError}</span>
<input
name="userPassword"
type="password"
placeholder="password"
value={props.currentUserPasswordText}
className={style.signInText}
onChange={(e) => {
props.signInOnChangeHandler(e);
}}
onBlur={(e) => props.signInOnBlurHandler(e)}
/>
<input type="submit" value="Submit" className={style.signInSubmit} />
</div>
<div className={style.signInLinks}>
Forget Password
Create Account
</div>
</form>
</React.Fragment>
);
};
in app.jsx file :
signInSubmitHandler() {
console.log('waaaat');
}
Form Code image
props
signInSubmitHandler binding
signInSubmitHandler function
your function has one param
signInSubmitHandler(e) {
console.log('waaaat');
}
so try this
<form onSubmit={(e) => props.signInSubmitHandler(e)} className={style.signInForm}>

How to call a function in a function based ReactJS component?

In ReactJS would like to have a component from a function, and send a call to a function when a form is posted.
This example doesn't work. How can be fixed?
import React from 'react';
import Link from "react-router-dom/Link";
function AddPhoto(props) {
return (<div>
<h1>Pickture</h1>
<Link className='cancelIcon' to="/"> </Link>
<div>
<form className="form" onSubmit={e => this.handleSubmit(e)}>
<input className='.form input' type='text' placeholder='Link' name='link'/>
<input className='.form input' type='text' placeholder='Description' name='description'/>
<button> post</button>
</form>
</div>
</div>)
}
export function handleSubmit(event) {
console.log("Form has been submitted");
console.log(event.target.element.link.value);
}
I think there are several issues with your code.
You probably want to export your AddPhoto component instead of your handleSubmit function. Assuming that your file is only exporting your AddPhoto component, you don't have to declare a constant and you can straightaway export default your AddPhoto function.
I actually don't see the reason to export your handleSubmit function. So I will include that function inside your AddPhoto component.
There is a - in your this.handleSubmit function, also functional component don't have to use this, furthermore your handleSubmit function is not within your functional component's scope. So it won't work.
You probably don't need the . in your input className props as well.
I've formatted your code to make it look cleaner :)
Here are the codes for you to refer.
const AddPhoto = (props) => {
const handleSubmit = (event) => {
// Add this if you want to prevent the page from reloading and updating your url
event.preventDefault();
console.log("Form has been submitted");
// Assuming you want to get the `link` field's value, you can get it by using this
console.log(event.target.link.value);
}
return (
<div>
<h1>Pickture</h1>
<Link className="cancelIcon" to="/">
{" "}
</Link>
<div>
<form className="form" onSubmit={handleSubmit}>
<input
className="form input"
type="text"
placeholder="Link"
name="link"
/>
<input
className="form input"
type="text"
placeholder="Description"
name="description"
/>
<button type="submit">post</button>
</form>
</div>
</div>
);
}
export default AddPhoto;
Remove this from your handleSubmit since it's declared outside.
Remove export if you're declaring the function in the same file. Otherwise, you would have to define your function in a separate file and then import from there.
function AddPhoto(props) {
return (<div>
<h1>Pickture</h1>
<Link className='cancelIcon' to="/"> </Link>
<div>
{/* Removed this.*/}
<form className="form" onSubmit={e => handleSubmit(e)}>
<input className='.form input' type='text' placeholder='Link' name='link'/>
<input className='.form input' type='text' placeholder='Description' name='description'/>
<button> post</button>
</form>
</div>
</div>)
}
// Removed export
function handleSubmit(event) {
console.log("Form has been submitted");
console.log(event.target.element.link.value);
}
There are quite some issue with your code:
The button doesn’t have a type=“submit” on it, so therefor it won’t even submit the form when pressed.
HandleSubmit is an function specific to AddPhoto, so it should be inside the AddPhoto component. (I also like to use an arrow function in this case because it should be an anonymous function).
There is no need the use this because first of all this keyword is only used in classes to bind functions to the class. So because AddPhoto is an functional component, you don’t have to bind the function to the class.
You should add event.preventDefault();, because otherwise the page will reload (to submit the form) and you will lose your state of your application.
import React from 'react';
import Link from 'react-router-dom/Link';
export default function AddPhoto() {
const handleSubmit = event => {
event.preventDefault();
const link = event.target.link;
const description = event.target.description;
console.log('Form has been submitted');
};
return (
<div>
<h1>Picture</h1>
<Link className="cancelIcon" to="/">
cancel
</Link>
<div>
<form className="form" onSubmit={handleSubmit}>
<input
className="form-input"
type="text"
placeholder="Link"
name="link"
ref={linkInput}
/>
<input
className="form-input"
type="text"
placeholder="Description"
name="description"
ref={descriptionInput}
/>
<button type="submit">post</button>
</form>
</div>
</div>
);
}
Try this:
import React from 'react';
import Link from "react-router-dom/Link";
export function AddPhoto(props) {
return (<div>
<h1>Pickture</h1>
<Link className='cancelIcon' to="/"> </Link>
<div>
<form className="form" onSubmit={handleSubmit}>
<input className='.form input' type='text' placeholder='Link' name='link'/>
<input className='.form input' type='text' placeholder='Description' name='description'/>
<button> post</button>
</form>
</div>
</div>)
}
function handleSubmit(event) {
console.log("Form has been submitted");
console.log(event.target.element.link.value);
}
I think you should be needing to write something like ...
import React from 'react';
import Link from "react-router-dom/Link";
export const AddPhoto = props => {
const handleSubmit = e =>{
return(
console.log("Form has been submitted");
console.log(e.target.element.link.value);
)
}
return (<div>
<h1>Pickture</h1>
<Link className='cancelIcon' to="/"> </Link>
<div>
<form className="form" onSubmit={e => handleSubmit(e)}>
<input className='.form input' type='text' placeholder='Link' name='link'/>
<input className='.form input' type='text' placeholder='Description' name='description'/>
<button> post</button>
</form>
</div>
</div>)
}
AddPhoto.defaultProps = {
onSubmit: ()=>{}
}

React.JS onChange event not working with using unity-webgl

import {Unity} from 'react-unity-webgl';
...
handleChange(event) {
console.log(event.target.value);
}
render() {
<div>
...
<div>
<Unity src="WebGL.json" />
</div>
...
<div>
<input type="text" name="title" id="title" value={this.state.value} onChange={this.handleChange} />
</div>
...
</div>
}
Here onChange(Input) event was working well but after Unity integration it does not work at all. I tried with other input components but same result.
I solved this problem by myself and I posted the answer via below links.
Here are the answer for this question.

Keep code DRY on create/edit form

I have a few inputs that are used in my form for both create and update. I decided to make them a component.
// used for CRU on the event record
import React from 'react';
class Form extends React.Component {
render() {
return (
<div className="slds-form">
<div className="slds-form-element">
<label className="slds-form-element__label">Assigned To</label>
<div className="slds-form-element__control">
<input ref={(input) => this.assigned = input} type="text" className="slds-input" disabled/>
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Related To</label>
<div className="slds-form-element__control">
<input ref={(input) => this.related = input} type="text" className="slds-input" disabled/>
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Location</label>
<div className="slds-form-element__control">
<input ref={(input) => this.location = input} type="text" className="slds-input" />
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Event Start</label>
<div className="slds-form-element__control">
<input ref={(input) => this.start = input} type="text" className="slds-input" />
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Event End</label>
<div className="slds-form-element__control">
<input ref={(input) => this.end = input} type="text" className="slds-input" />
</div>
</div>
<div className="slds-form-element">
<label className="slds-form-element__label">Contact</label>
<div className="slds-form-element__control">
<input ref={(input) => this.contact = input} type="text" className="slds-input" disabled/>
</div>
</div>
<button type="button" className="slds-button slds-button--neutral">Cancel</button>
<button type="submit" className="slds-button slds-button--brand">{this.props.buttonLabel}</button>
</div>
);
}
}
export default Form;
I then attempted to use this component in my <Create /> component.
// used for Create on the event record
import React from 'react';
import Form from './Form';
class Create extends React.Component {
createEvent(e) {
console.log("createEvent() has fired.");
e.preventDefault();
const event = {
assigned: this.assigned.value,
related: this.related.value,
location: this.location.value,
start: this.start.value,
end: this.end.value,
contact: this.contact.value
}
console.log(event);
}
render() {
return (
<form onSubmit={(e) => this.createEvent(e)}>
<Form buttonLabel="Create" />
</form>
);
}
}
export default Create;
When I try to hit the Create button on my <Create /> component I get an error
Uncaught TypeError: Cannot read property 'value' of undefined
at Create.createEvent (webpack:///./src/components/Event/Create.js?:42:32)
at onSubmit (webpack:///./src/components/Event/Create.js?:59:27)
at Object.ReactErrorUtils.invokeGuardedCallback (webpack:///./~/react/lib/ReactErrorUtils.js?:70:16)
at executeDispatch (webpack:///./~/react/lib/EventPluginUtils.js?:89:21)
at Object.executeDispatchesInOrder (webpack:///./~/react/lib/EventPluginUtils.js?:112:5)
at executeDispatchesAndRelease (webpack:///./~/react/lib/EventPluginHub.js?:44:22)
at executeDispatchesAndReleaseTopLevel (webpack:///./~/react/lib/EventPluginHub.js?:55:10)
at Array.forEach (native)
at forEachAccumulated (webpack:///./~/react/lib/forEachAccumulated.js?:25:9)
at Object.processEventQueue (webpack:///./~/react/lib/EventPluginHub.js?:231:7)
I then check the console and see the refs belong in my <Form /> component, and not my <Create /> component.
Is there a way to pass the refs from my child component, <Form />, to its parent, <Create />?
That's a lot of refs! Good news, you really don't need them, at all. As a very very general rule, you should only be using refs if you are interacting with an external library that doesn't "understand" React (d3, Greensock, TinyMCE, etc).
Tackling it in an uncontrolled way can be done like:
const User = (props) => (
<div>
<input name="foo" className="form-control" />
<input name="foo2" className="form-control" />
<button type="submit" className="btn btn-primary">{props.buttonLabel}</button>
</div>
);
class App extends React.Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onChange(e) {
this.setState({
[e.target.name]: e.target.value,
});
}
onSubmit(e) {
e.preventDefault();
console.log(this.state);
}
render() {
return (
<div className="container">
<br />
<form onChange={this.onChange} onSubmit={this.onSubmit}>
<User buttonLabel="Create"/>
</form>
</div>
);
}
};
ReactDOM.render(<App />, document.getElementById('app'));
Codepen example:
http://codepen.io/cjke/pen/zNXxga?editors=0010

Categories

Resources