Redux-Form Field type number renderField step not working - numbers

I am encountering a strange problem when declaring a Field of type number and using the example renderField component on the redux-form website.
const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
<div>
<label>{label}</label>
<div>
<input {...input} placeholder={label} type={type}/>
{touched && ((error && <span>{error}</span>) || (warning && <span>{warning}</span>))}
</div>
);
Inside my render, I have a component of type number with a step size
<Field name="SmallStepSizeNumber" type='number' step={0.000001}
component={renderField} label="SmallStepSizeNumber"
validate={[ ]}
/>
All I'm trying to replicate is a normal html step size change, but it just steps by 1 ignoring my step size. The same happens when I try to set min/max/etc. Am I specifying this wrong? Is this a bug?

Passing a string instead of a number might works
const renderField = ({ input, label, type, meta: { touched, error, warning } }) => (
<div>
<input type="number" {...input} step="0.1" />
</div>
);
const Form = () => (
<Field
name="foobar"
component={renderField}
/>
);
Here's a jsfiddle https://jsfiddle.net/75rh036o/12/

Related

TypeError on submit handler (Nextjs)

For a new project (next.js) I'd like to add an on submit handler to a form component and map the input of the form at the bottom of the page. However, I get the typeError message claiming that the "addSpending" is not a function.
Here the code for the form component:
import styled from "styled-components";
export default function NewSpendingForm({ addSpending }) {
function handleSubmit(event) {
event.preventDefault();
const formData = new FormData(event.target);
const data = Object.fromEntries(formData);
addSpending(data);
}
return (
<StyledBody>
<StyledIntro>Please fill the form to add your spendings:</StyledIntro>
<StyledAddSpendingForm onSubmit={handleSubmit}>
<StyledFormLabel>Title</StyledFormLabel>
<StyledFormInput type="text" id="title" name="title" required />
<StyledFormLabel>Amount</StyledFormLabel>
<StyledFormInput type="number" id="amount" name="amount" step="0.01" min="0" required />
<StyledFormLabel>Date</StyledFormLabel>
<StyledFormInput type="date" id="date" name="date" required />
<StyledFormLabel>Category</StyledFormLabel>
<StyledFormSelect type="select" id="category" name="category" required >
<option>Food and Drinks</option>
<option>Clothes</option>
<option>Household</option>
<option>Entertainment</option>
<option>Gasoline</option>
<option>Restaurants</option>
<option>Others</option>
</StyledFormSelect>
<StyledFormButton type="submit">Submit</StyledFormButton>
</StyledAddSpendingForm>
</StyledBody>
);
}
And this one for the page:
import styled from "styled-components";
import NewSpendingForm from "../../components/AddSpendingForm";
export default function AddSpendingPage({ spendingInput, addSpendingInput }) {
return (
<>
<StyledHeader>
<StyledTitle>Add Spendings</StyledTitle>
</StyledHeader>
<StyledBody>
<NewSpendingForm addSpending={addSpendingInput} />
<StyledLogTitle> Your Spendings Log</StyledLogTitle>
<StyledLog>
{spendingInput.map((spendingInput) => (
<StyledLogEntry>
{spendingInput.title}
{spendingInput.amount}€
{spendingInput.date}
{spendingInput.category}
</StyledLogEntry>
))}
</StyledLog>
</StyledBody>
</>
);
}
Thanks a lot in advance!
I expected the form input to be mapped and displayed at the bottom of the page. However, after clicking on the "Submit" button I get the mentioned TypeError message.

Vue Formulate validation for two fields at the same time

I'm currently building a form in Vue js and I'm using Vueformulate, the docs have various ways of validation however there is no validation method or implementation that for my use case. I would like the validation to call a custom function because this way I could check if Field1 or Field2 has a value. Is there an implementation like my psuedocode below? thanks in advance!
<FormulateForm #submit="onSubmit" #default="{ hasErrors }">
<FormulateInput
type="text"
label="Field1"
validation="customValidation"
/>
<FormulateInput
type="text"
label="Field2"
validation="customValidation"
/>
<FormulateInput
type="submit"
label="Submit"
input-class="btn btn-primary w-full"
:disabled="hasErrors"
/>
</FormulateForm>
//NOT REAL CODE
customValidation(formValues){
if(formValues.Field1 || formValues.Field2){
return true // CHECK IF EITHER FIELD1 OR FIELD 2 HAS VALUE IF SO MARK THE FIELD AS VALID WHICH ENABLES SUBMIT BUTTON
}
return false
}
You can declare a custom validation rule via <FormulateInput>.validationRules:
<script setup>
const validationRules = {
customValidation({ getFormValues }) {
// property names match the input names
const { field1, field2 } = getFormValues()
if (field1 || field2) {
return true
}
},
}
</script>
<template>
<FormulateInput
type="text"
label="Field1"
name="field1"
validation="customValidation"
:validationRules="validationRules"
/>
<FormulateInput
type="text"
label="Field2"
name="field2"
validation="customValidation"
:validationRules="validationRules"
/>
</template>
But FormulateForm assumes an error state unless all fields are touched (at least in my demo). Not sure how you could get around that.
demo

Redux Form Values Properties Undefined & Refreshes on Submit

I am using redux-form in order to submit a new user signup page in my React Web App, but when I try to grab the input field values on the form of the parameter values, it comes back undefined in mapDispatchToProps. I have read many posts of people claiming their values variable comes back undefined, but that is not the case for me. Only when I console.log(values.[inputName]) do I get undefined. According to the documentation, I cannot tell that I am doing anything incorrectly.
Can someone please help determine what is causing values.email to be undefined? Thanks.
// presentational component
class Signup extends Component {
render() {
const { handleSubmit } = this.props;
return (
<div>
<h1>Signup</h1>
<form onSubmit={handleSubmit}>
<div>
<label>
Email:
<Field component="input" type="email" name="email" />
</label>
</div>
<div>
<label>
Password:
<Field component="input" type="password" name="password" />
</label>
</div>
<button type="submit" >Submit</button>
</form>
</div>
)
}
}
export default reduxForm({
form: 'Signup',
enableReinitialize: true
})(Signup)
// redux container component
const mapDispatchToProps = (dispatch) => {
return {
handleSubmit: (values) => {
console.log(values.email); // outputs undefined!
}
};
}
const SignupContainer = connect(
null,
mapDispatchToProps
)(Signup)
export default SignupContainer;
// reducer index.js
import { reducer as formReducer } from 'redux-form';
export const appReducer = combineReducers({
form: formReducer
})
// store.js
export const store = createStore(
appReducer,
applyMiddleware(
thunkMiddleware,
loggerMiddleware
)
);
Side Note
I have noticed that whenever I first click the submit button on the form, the page refreshes (so I do not see the console.log). All proceeding times does not cause a refresh, but I am unsure as to why. Any explanation of this would be greatly appreciated, too.
Update
After changing my Router from HashHistory to BrowserRouter (react-router), the page refreshes every time I click submit. Seems that I have two problems now.

How to correctly pass props to a custom component with Redux-form v6

I am trying to update my form to redux-form v6.7 and I'm having difficulties wrapping my head about this part.
Say I want to render a select component like so :
<div className="col-md-12">
<Field name="name" component={renderSelect}/>
</div>
Here is my component that was working fine with the previous versions of react-redux, obviously with a form prop named "name" :
<VirtualizedSelect
{...domOnlyProps(name)}
filterOptions={itemsFilter}
options={this.state.items.items}
onChange={name.onChange}
value={name.value}
name="name"
placeholder="Name"
onBlur={() => name.onBlur(name.value)}
autoBlur={true}
simpleValue={true}
multi={true}
clearable={false}
onBlurResetsInput={false}
onCloseResetsInput={false}
delimiter="|"
showNewOptionAtTop={false}
selectComponent={Creatable}
promptTextCreator={(label) => {return "Search for " + label}}
/>
So now I am trying to wrap this component in a renderSelect() function. But I am unsure how to correctly pass the props I need to the custom component. What props should I pass, which props are passed by default, etc.
const renderSelect = ({/*what to pass here?*/ input }) => (
<FormGroup controlId="name" role="form" className="col-md-12">
<div className="group selectW" style={{width: '100%'}}>
<VirtualizedSelect
{...domOnlyProps(name)}
filterOptions={itemsFilter}
options={this.state.items.items}
onChange={name.onChange}
value={name.value}
name="name"
placeholder="Name"
onBlur={() => name.onBlur(name.value)}
autoBlur={true}
simpleValue={true}
multi={true}
clearable={false}
onBlurResetsInput={false}
onCloseResetsInput={false}
delimiter="|"
showNewOptionAtTop={false}
selectComponent={Creatable}
promptTextCreator={(label) => {return "Search for " + label}}
/>
</div>
</FormGroup>
);
Help appreciated.
I figured it out, posting what it looks like as it might help others at some point
const renderSelect = ({input, items, filter}) => (
<FormGroup controlId="name" role="form" className="col-md-12">
<div className="group selectW" style={{width: '100%'}}>
<VirtualizedSelect
filterOptions={filter}
options={items}
onChange={input.onChange}
value={input.value}
name={input.name}
placeholder="Name"
onBlur={() => input.onBlur(input.value)}
autoBlur={true}
simpleValue={true}
multi={true}
clearable={false}
onBlurResetsInput={false}
onCloseResetsInput={false}
delimiter="|"
showNewOptionAtTop={false}
selectComponent={Creatable}
promptTextCreator={(label) => {return "Search for " + label}}
/>
</div>
</FormGroup>
);

react rerendering form causes focus/blur issue on state change

I have a form in a react component that has two change handlers, one for my two draftjs textareas, and one for my other text inputs:
onChangeEditor = (editorStateKey) => (editorState) => {
this.setState({ [editorStateKey]: editorState });
}
handleInputChange(event) {
event.preventDefault();
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
In my render method I have two views that I switch between depending on which view mode I am in, read or edit:
render () {
const Editable = () => (
<div className="editor">
<form className="editor-inner">
<h3>Redigerar: Anbudsbrev</h3>
<h4>Rubrik</h4>
<input type="text" key="text01" name="title" defaultValue={this.state.title} onBlur={this.handleInputChange} />
<h4>Text 1</h4>
<RichEditor editorState={this.state.editorState1} onChange={this.onChangeEditor('editorState1')} name="text01"/>
<h4>Citat</h4>
<input type="text" key="text02" name="quote01" defaultValue={this.state.quote01} onBlur={this.handleInputChange} />
<h4>Text 2</h4>
<RichEditor editorState={this.state.editorState2} onChange={this.onChangeEditor('editorState2')} name="text02" />
<EditorFooter {...this.props} submitForm={this.saveForm} />
</form>
</div>
);
const Readable = () => (
<div>
<h1 className="header66">{this.state.title}</h1>
<div className="text66">{this.state.text01}</div>
<div className="quote100">{this.state.quote01}</div>
<div className="text66">{this.state.text02}</div>
</div>
);
return (
<div>
{ this.props.isInEditMode ? <Editable /> : <Readable /> }
</div>
);
}
When I switch between inputs in my browser I have to click twice in order to get the focus on the right input.
I suspect that this is because a change is triggered on the "blur" event of each input, causing the form to rerender because state is changed. And when the form rerenders, it goes through the { this.props.isInEditMode ? <Editable /> : <Readable /> } which causes the input to lose focus.
The problem is that I don't know how to get around this.
I solved it myself.
It turns out that it was not a good idea to place the Editable and Readable inside of my component as I did. Instead I moved them out to their own components, and it works properly now.
class Editable extends React.Component {
render() {
return (
<div className="editor">
<form className="editor-inner">
<h3>Redigerar: Anbudsbrev</h3>
<h4>Rubrik</h4>
<input type="text" name="title" defaultValue={this.props.title} onChange={this.props.handleInputChange} />
<h4>Text 1</h4>
<RichEditor editorState={this.props.editorState1} onChange={this.props.onChangeEditor('editorState1')} name="text01" />
<h4>Citat</h4>
<input type="text" name="quote01" defaultValue={this.props.quote01} onChange={this.props.handleInputChange} />
<h4>Text 2</h4>
<RichEditor editorState={this.props.editorState2} onChange={this.props.onChangeEditor('editorState2')} name="text02" />
<EditorFooter {...this.props} submitForm={this.props.saveForm} />
</form>
</div>
);
}
};
class Readable extends React.Component {
render() {
return (
<div>
<h1 className="header66">{this.props.title}</h1>
<div className="text66">{this.props.text01}</div>
<div className="quote100">{this.props.quote01}</div>
<div className="text66">{this.props.text02}</div>
</div>
);
}
};