Can't update form inside of onBlur in redux-form - reactjs

I have a field AskQuestions where a user enters something and a dropdown appears on each user keystroke with updated results in an array, companyOptions. However, when a user clicks out of a field I am trying to clear current field's value via this.props.dispatch(change..)) but this seems impossible.
<Field
name="company"
type="text"
onBlur={this.onClearSearch}
keyUp={this.renderCompanyList}
component={renderField}
label="Choose Company..."/>
here is my renderField
function renderField(field) {
const { meta: {touched, error} } = field;
return(
<div>
<input type={field.type}
placeholder={field.label}
onKeyUp={field.keyUp ? () => {field.keyUp(field.input.value)} : ""}
onBlur={field.onBlur ? () =>{field.onBlur()} : ""}
{...field.input}
// I also tried putting in after ...input
// onBlur={field.onBlur ? () =>{field.onBlur()} : ""}
/>
<div className="text-danger">
{touched ? error : ''}
</div>
</div>
);
}
I have the following callback associated, but this.props.dispatch does not reset the field.
onClearSearch(){
this.props.dispatch(change('AskQuestion','company',''));
}

it's because there are an default event onBlur which modifies the value of the input after having been modified by your function onClearSearch,
Add an e.preventDefault() at the end of onClearSearch will have to solved your problem, something like this:
onClearSearch(e){
const {companyOptions} = this.state;
if (companyOptions.length){
var company = companyOptions[0];
this.props.dispatch(change('AskQuestion','company',company.label));
}
else {
this.props.dispatch(change('AskQuestion','company',''));
}
// hides the dropdown view
this.setState({showCompanySearch:false})
// here
e.preventDefault();
}
More info here
I hope this can help you

Related

How to fix Type Props Error when onChange Event in Formik/Field Input

When I want to trigger the onChange event of Formik/Field(input).
I don't know how to trigger the onChange Event in Formik/Field. So I tried to trigger onChange event in Formik/Form and get the id of event params. But it is facing the problem of Props in Typescript.
Please check my code snippet and let me know how to fix this problem. Thanks in advance.
const InputCustomerForm = () => {
...
const handleFormChange = (event: FormEvent) => {
if (event.target.id === "mobileNumber"){
const value = phoneConvertor(event.target.value);
setUpdatedPhoneNumber(value);
}
}
return (
<OrderPaymentFormContainer className={`${showAccount === true ? 'show' : 'hidden'}`}>
<Formik
initialValues={initialValues}
enableReinitialize={true}
validationSchema={OrderPaymentFormSchema}
onSubmit={(values, actions) => {
handleSendEmail(values);
actions.setSubmitting(false);
}}
>{
({ handleSubmit, errors, touched, isValid }) => (
<Form onSubmit={handleSubmit} onChange={handleFormChange}>
...
<div>
<label>
Mobile Phone Number
</label>
<div>
<div>
<Field id="countryCode" name="countryCode" as="select">
<option defaultValue="1">US</option>
</Field>
</div>
<div>
<Field id="mobileNumber" name="mobileNumber" placeholder="(201) 555-0123" value={updatedPhoneNumber}/>
</div>
</div>
{errors.mobileNumber && touched.mobileNumber ?
(<div className="order-detail--card-form-item-error">{errors.mobileNumber}</div>) : null
}
</div>
...
</Form>
)
}
</Formik>
</OrderPaymentFormContainer>
)
}
export default InputCustomerForm;
As we can see, I hope to get the changed value of input and want to do some function with changed values and return to Input's current value. But it's not working now. Please let me know the problem how to resolve this problem. Thanks
I tried it by manually using pure function but it's not working.
I hope to resolve this problem in typescript.

How do I get input from user by using <button> and <input> in React?

I want to create a form by using <input> and <button> like so:
I'm not sure how to pass the value I get from the text input field into a couple of functions on the frontend when I press the button "Send now". How do I make a <form onSubmit={}> without using forms, rather just an input field and a button?
This is what I've tried so far and it's not working, I'm not sure how to get the input value and pass it into the function like this this.articleOnSubmit(*user input*). And also is the way i incorporated onChange={this.articleOnChange} correct? Here is my code:
const Input = ({ placeholder, name, type, value }) => (
<input
placeholder={placeholder}
type={type}
step="0.0001"
value={value}
name={value}
/>
);
class Publish extends Component {
constructor(props) {
super(props);
this.state = {
articleTitle: '',
};
}
articleOnChange = (event) => {
let title = event.target.value;
this.setState({ articleTitle: title.toLowerCase() });
}
articleOnSubmit = (event) => {
if (this.state.articleTitle) {
console.log(this.state.articleTitle);
this.hash(this.state.articleTitle)
.then(hex => {console.log(hex); return hex;})
.then(hex => this.addArticleHash(hex));
event.preventDefault();
}
return (
<Input placeholder="Article Name" name="article" type="text" onChange={this.articleOnChange} />
<div/>
{false
? (<Loader />)
: (
<button
type="submit"
onClick={this.articleOnSubmit(Input.name)}
>
Send now
</button>
)}
</div>
);
}
To make it work you have to fix 2 issues here:
Since Input is a component, you have to get in its props the onChange prop you pass to it, otherwise it won't work.
const Input = ({ placeholder, name, type, value, onChange }) => (
<input
onChange={onChange}
placeholder={placeholder}
type={type}
step="0.0001"
value={value}
name={value}
/>
);
React onClick should be a function. Not a call. A function. What you did here was onClick={this.articleOnSubmit(Input.name)} - which is a call.
The solution is to change it into a function () => this.articleOnSubmit(Input.name)

ReactJS: OnChange handler auto submitting data before onClick

I'm still relatively new to React/Javascript & working with its functions. I created a component that takes user input and renders a button that allows a user to link to an outside URL.
The button title is created by the user and then the URL is added.
However, when a url is pasted or I begin typing it, the onChange handler automatically creates the button without using the onSubmit function. So if I begin typing a paste a url (even if the data is wrong), the onChange event takes whatever I've input without allowing me to click "submit first".
I'm following this tutorial as a guideline for creating my onChange/onSubmit functions: https://www.youtube.com/watch?v=qH4pJISKeoI&t=304s. His demo does not have the same issue and his input fields solve a different problem.
onChange & onSubmit Functions
this.state = {
links: [],
url: '',
title: ''
}
}
onChange = (e) => {
e.preventDefault(e)
this.setState({
[e.target.name]: e.target.value
})
}
// onSubmit
onSubmit = e => {
e.preventDefault(e)
}
...
render() {
if (this.state.url === '') {
return (
<>
<form>
<input
name="title"
type="text"
placeholder="add button text"
onChange={e => this.setState({ title: e.target.value })}
/>
<input
name="url"
type="url"
placholder="your-link.com"
onClick={(e) => { e.stopPropagation() }}
disabled={this.state.title === ''}
onChange={e => this.setState({ url: e.target.value })}
/>
<br />
</form>
<button onClick={this.onSubmit}>Submit</button>
</>
)
} else {
return (
<>
<div>
<p>{this.state.title}</p>
</div >
</>
)
}
}
}
I've tried separating the onChange events using onChange={this.title} and {this.url} , disabling the URL field until the title is added, and adding onClick={(e) => { e.stopPropagation() }} in the url input field to prevent autosubmission as shown in the code above.
Any help understanding what causes this problem would be appreciated.
Let's check what is happening:
We have onChange on input with url.
When anything is being changed in this input field,
On change is called and it triggers render method.
In render if (this.state.url === '') { this is no longer true so it creates link without needing to submit.
Prevent default will not work while you have params in it:
e.preventDefault(e)
// probably this may be a typo instead?
// it's preventing you to go further line due to error.
Remove e param and it should be fine:
e.preventDefault()
<form onSubmit={this.onSubmit}>
<input
name="title"
type="text"
placeholder="add button text"
onChange={e => this.onChange(e)}
/>
<input
name="url"
type="url"
placholder="your-link.com"
disabled={this.state.title === ''}
onChange={e => this.onChange(e)}
/>
<br />
<button type="submit">Submit</button>
</form>
do changes like this and check

Clear a field's value on input clear in react-final-form

I'm using a custom component with react-final-form. On input change it sets the value to the address field. But when the input is cleared it doesn't update the value of the field. So I'm trying to do it with form mutators.
I have already added a mutator for clearing the field:
mutators={{
clear: ([address], state, { changeValue }) => {
changeValue(state, "address", () => undefined);
}
}}
I tried to add it to my custom onChange function, but it doesn't work.
onChange={event =>
props.input.onChange !== undefined
? props.input.onChange({ value: event })
: form.mutators.clear
}
Or maybe this can be done without mutators at all? I would really appreciate your help. Here is a live example (clearing the field works only on the button click as onClick={form.mutators.clear}).
You can just call form.change('address', undefined) at any time that you'd like to clear the value.
All the default callback are handle by the component. If you want to do a clear with a button click, you can create a custom component and use native callback methods do your thing.
onChange = (event) => {
this.setState({
address:event.target.value
});
}
onClear = () => {
this.setState({
address:''
});
}
<div>
<Field name="address">
<div>
<input
value={this.state.address}
onChange={this.onChange}
/>
</div>
</Field>
<button onClick={this.onClear}>Clear</button>
</div>
The problem is not with the react-final-form in your code, it is due to the react-da data, I have played a lot around your code within 1 day, and checked reset is working with fine with the react-final-form
Just update your render with this code and see reset is working absolutely fine. Yeah! the problem is with react da data. I am not sure about what it does due to less official information for this package.
<div className="App">
<h2>Dadata test</h2>
<Form
mutators={{
clear: ([address], state, { changeValue }) => {
changeValue(state, "address", () => undefined);
}
}}
onSubmit={onSubmit}
render={({ form, handleSubmit, pristine, invalid, values, errors }) => (
<form onSubmit={handleSubmit} noValidate>
<Field name="address" component="input" />
{/* {props => (
<div>
<ReactDadata
token="d19c6d0b94e64b21d8168f9659f64f7b8c1acd1f"
onChange={event =>
props.input.onChange !== undefined
? props.input.onChange({ value: event })
: form.mutators.clear
}
/>
</div>
)}
</Field> */}
<button type="submit" disabled={invalid}>
Submit
</button>
<button type="button" onClick={form.reset}>
Clear
</button>
<Fields names={["address"]}>
{fieldsState => (
<pre>{JSON.stringify(fieldsState, undefined, 2)}</pre>
)}
</Fields>
</form>
)}
/>
</div>
Hope it will help you to resolve the problem.

REACT: conditionally rendering a alert if field left blank

I have the following React form:
import React from 'react';
export default class ChatBar extends React.Component {
mySubmitHandler = event => {
event.preventDefault();
/* you can access the value as below */
const inputName = this.refInputName.value;
const inputEmail = this.refInputEmail.value;
const inputMessage = this.refInputMessage.value;
// const inputStamp = this.convertDate(new Date())
const message = {name: inputName, email: inputEmail, content: inputMessage, stamp: inputStamp}
this.props.addMessage(message)
this.refInputMessage.value = ""
}
render() {
return (
<div>
<h4>Leave a Comment</h4>
<form onSubmit={this.mySubmitHandler}>
<label>Your name
<input
type="text"
name="name"
ref={(node) => (this.refInputName = node)}
/>
</label>
<label>Your email
<input
type="text"
name="email"
ref={(node) => (this.refInputEmail = node)}
/>
</label>
<label>Your message
<textarea ref={(node) => (this.refInputMessage = node)} />
</label>
<br />
<input className="submit-button" type="submit" value="Submit comment" />
</form>
</div>
)
};
};
I need to create a way so that when an input is left black and either submitted or hovered over, it creates a "tool tip" alerting the user the field has been left blank (see attached image). I have tread fooling around with onHover, onClick and onSubmit handlers to render some state of tool tip being "true" and conditionally render the toolTip div however it does not seem to be working and I am rather lost, now starting from scratch again.
Any help is greatly appreciated =)
I recommend react-valida-hook, it's really simple to use, you can add personalized messages, the only thing you need to do is pass the error.
Example:
const displayError = (errs) => {
if (errs.indexOf('required') !== -1) {
return '*Super important required field';
}
if (errs.indexOf('minLength') !== -1) {
return '*Too short man!';
}
if (errs.indexOf('isEmail') !== -1) {
return '*That looks wrong';
}
return '';
};
<div className="errors">
// I use a variable to show only errors wen form is submitted
{submitted && displayError(validation.errors.firstName)}
</div>
You can make two custom CSS class for visibility: hidden, ect.
Then render the toolTip div like such:
<div className="tool-tip" style={this.state.showTip ? visible : hidden}>testing </div>

Resources