react-bootstrap: clear element value - javascript

I'm trying to clear my input fields after an onClick event.
I'm using react-bootstrap library and while there is a getValue() method, there is not setValue(value) method.
I've stumbled upon this discussion .
I did not fully understand what they are suggesting in order to simply clean a form after submission.
After all, If I would use a simple HTML <input> instead of react-bootstrap I could grab the node via element ref and set it's value to be empty string or something.
What is considered a react way to clean my react-bootstrap <Input /> element?

Store the state in your React component, set the element value via props, get the element value via event callbacks. Here is an example:
Here is an example taken directly from their documentation. I just added a clearInput() method to show you you can clear the input by just updating the state of your component. This will trigger a re-render which will cause the input value to update.
const ExampleInput = React.createClass({
getInitialState() {
return {
value: ''
};
},
validationState() {
let length = this.state.value.length;
if (length > 10) return 'success';
else if (length > 5) return 'warning';
else if (length > 0) return 'error';
},
handleChange() {
// This could also be done using ReactLink:
// http://facebook.github.io/react/docs/two-way-binding-helpers.html
this.setState({
value: this.refs.input.getValue()
});
},
// Example of how you can clear the input by just updating your state
clearInput() {
this.setState({ value: "" });
},
render() {
return (
<Input
type="text"
value={this.state.value}
placeholder="Enter text"
label="Working example with validation"
help="Validation is based on string length."
bsStyle={this.validationState()}
hasFeedback
ref="input"
groupClassName="group-class"
labelClassName="label-class"
onChange={this.handleChange} />
);
}
});

For what I'm doing at the moment, I didn't really think it was necessary to control the Input component's value through setState/Flux (aka I didn't want to deal with all the boilerplate)...so here's a gist of what I did. Hopefully the React gods forgive me.
import React from 'react';
import { Button, Input } from 'react-bootstrap';
export class BootstrapForm extends React.Component {
constructor() {
super();
this.clearForm = this.clearForm.bind(this);
this.handleSave = this.handleSave.bind(this);
}
clearForm() {
const fields = ['firstName', 'lastName', 'email'];
fields.map(field => {
this.refs[field].refs['input'].value = '';
});
}
handleSubmit() {
// Handle submitting the form
}
render() {
return (
<div>
<form>
<div>
<Input
ref='firstName'
type='text'
label='First Name'
placeholder='Enter First Name'
/>
<Input
ref='lastName'
type='text'
label='Last Name'
placeholder='Enter Last Name'
/>
<Input
ref='email'
type='email'
label='E-Mail'
placeholder='Enter Email Address'
/>
<div>
<Button bsStyle={'success'} onClick={this.handleSubmit}>Submit</Button>
<Button onClick={this.clearForm}>Clear Form</Button>
</div>
</div>
</form>
</div>
);
}
}

If you use FormControl as an input, and you want to use ref to change/get value from it, you use inputRef instead of ref
<FormControl inputRef={input => this.inputText = input} .../>
and use this to get/change its value:
this.inputText.value

This worked for me in case someone else is looking for an answer :D
You can access the values of react-bootstrap by using
console.log(e.target.form.elements.fooBar.value)
You can clear them by using
e.target.form.elements.fooBar.value = ""
import React from 'react';
import {Button, Form} from 'react-bootstrap';
export default function Example(props) {
const handleSubmit = (e) => {
// Handle submitting the form
}
const resetSearch = (e) => {
e.preventDefault();
e.target.form.elements.fooBar.value = ""
}
render() {
return (
<Form onSubmit={handleSubmit} onReset={resetSearch} >
<Form.Control type="input" name="fooBar" />
<Button type="submit"> Submit </Button>
<Button onClick={resetSearch} type="submit" > Reset </Button>
</Form>
);
}
}

You can also just use ReactDOM:
<FormControl
componentClass="select"
ref="sStrike">
<option value="-">Select…</option>
<option value="1">1</option>
<option value="2">2</option>
</FormControl>
Now a different FormControl fires an onChange={handleChange} and in that handler you can just id the ref and set to the default value:
ReactDOM.findDOMNode(this.refs.sStrike).value = '-';
and that will set the select box to the 'default' value.

Just add a button in-side form with the attribute type="reset"
<Button variant="primary" type="reset">Reset</Button>

Related

How to submit an input field with enter in React

I've made an input field in react that takes in a value and is supposed to be submitted using the enter key but I haven't been able to get it to work.
<input
key = "searchBox"
type = "text"
value = {this.state.currentValue}
placeholder = "Search"
onChange = {this.handleChange}
onSubmit = {this.handleSubmit}
/>
At the moment, enter does nothing. I've tried wrapping this in a form element where onSubmit is now part of that form element but when I do that, the entire input field disappears. So, how can I submit this by using enter? Here's the rest of the code.
import React from 'react';
export default class searchClass extends React.Component {
render() {
return (
<form onSubmit = {() => alert("yes")}>
<input
key = "searchBox"
type = "text"
value = {this.state.currentValue}
placeholder = "Search"
onChange = {this.handleChange}
/>
</form>
)
}
}
Here's part of my render function in App.js.
return (
<div className = "tableWrapper">
<div id = "tableScroll">
<table>
<SearchClass />
</table>
</div>
</div>
)
try this.
import React from 'react';
export default class searchClass extends React.Component {
render() {
return (
<form onSubmit={() => alert("yes")}>
<input
key="searchBox"
type="text"
value={this.state.currentValue}
placeholder="Search"
onChange={this.handleChange}
/>
<input type="submit"/>
</form>
)
}
}
Issue
input elements don't really do anything with an onSubmit prop/attribute.
<input
key = "searchBox"
type = "text"
value = {this.state.currentValue}
placeholder = "Search"
onChange = {this.handleChange}
onSubmit = {this.handleSubmit} // useless
/>
Solution
Wrap your input in a form and prevent the default form action from occurring, this is reloading the page, and your app.
class SearchClass extends React.Component {
state = {
currentValue: ""
};
handleChange = (e) => this.setState({ currentValue: e.target.value });
render() {
return (
<form
onSubmit={(e) => {
e.preventDefault(); // <-- prevent the default form action
alert("yes");
}}
>
<input
key="searchBox"
type="text"
value={this.state.currentValue}
placeholder="Search"
onChange={this.handleChange}
/>
</form>
);
}
}
Do you want to make a search box/input? You can use <input type="search"/>. Wrap it with form tag.

How to receive select value in handlesubmit function with formik react js?

i am developing a form in reactjs using formik plugin plugin link. when i submit form i am getting text fields values but dropdown values are coming empty...
this is my dropdown select
<div className="form-group">
<Field component="select" id="category" name="category" value={this.state.value} className={"form-control"} onChange={ this.handleChange }>
<option value="lokaler">Lokaler</option>
<option value="jobb">Jobb</option>
<option value="saker-ting">Saker & ting</option>
<option value="evenemang">Evenemang</option>
</Field>
</div>
handle submit function
export default withFormik({
enableReinitialize: true,
mapPropsToValues({ category }) {
return {
category: category || ''
}
},
handleSubmit(values, { setStatus, setErrors }){
console.log("data is this: ");
console.log(values); //here i am getting all form fields values except select value returning empty value
console.log("category: "+values.category);// here i always get empty value but not getting selected value
}
i am getting all text fields values in handle submit function but i am not able to get dropdown selected value....kindly tell me how to get dropdown select value in handle submit function ?
I also faced this problem yesterday. My problem was to submit form that contains ant design dropdown. I finally make it work after hours of:
revisiting the Formik Docs
watch Andrew Mead's video Better React Form with Formik again.
also viewing Jared Palmer's Working with 3rd-party inputs #1: react-select
The doc said you need to set onChange, onBlur events to setFieldValue, setFieldTouched props respectively like 3rd-party input example:
<MySelect
value={values.topics}
onChange={setFieldValue}
onBlur={setFieldTouched}
error={errors.topics}
touched={touched.topics}
/>
So to my problem, I need to change a bit:
<Select
{...field}
onChange={(value) => setFieldValue('fruitName', value)}
onBlur={()=> setFieldTouched('fruitName', true)}
value={values.fruitName}
...
>
...
</Select>
Hope this will help.
Here is my CodeSandbox
A more robust way to handle select components whilst using Formik would be to also use Jed Watsons react-select component. The two work together nicely and abstract away a lot of the boilerplate you would normally need to implement to get the component working seamlessly with Formik.
I have forked a simple example from Jared Palmer's react-select / Formik example on codesandbox and adjusted it to reflect your code above.
import "./formik-demo.css";
import React from "react";
import { render } from "react-dom";
import { withFormik } from "formik";
import Select from "react-select";
import "react-select/dist/react-select.css";
const options = [
{ value: "lokaler", label: "Lokaler" },
{ value: "jobb", label: "Jobb" },
{ value: "saker-ting", label: "Saker & ting" },
{ value: "evenemang", label: "Evenemang" }
];
const MyForm = props => {
const {
values,
handleChange,
handleBlur,
handleSubmit,
setFieldValue
} = props;
return (
<form onSubmit={handleSubmit}>
<label htmlFor="myText" style={{ display: "block" }}>
My Text Field
</label>
<input
id="myText"
placeholder="Enter some text"
value={values.myText}
onChange={handleChange}
onBlur={handleBlur}
/>
<MySelect value={values.option} onChange={setFieldValue} />
<button type="submit">Submit</button>
</form>
);
};
class MySelect extends React.Component {
handleChange = value => {
// this is going to call setFieldValue and manually update values.topcis
this.props.onChange("option", value);
};
render() {
return (
<div style={{ margin: "1rem 0" }}>
<label htmlFor="color">Select an Option </label>
<Select
id="color"
options={options}
onChange={this.handleChange}
value={this.props.value}
/>
</div>
);
}
}
const MyEnhancedForm = withFormik({
mapPropsToValues: props => ({
myText: "",
option: {}
}),
handleSubmit: (values, { setSubmitting }) => {
console.log(values);
}
})(MyForm);
const App = () => <MyEnhancedForm />;
render(<App />, document.getElementById("root"));
There are a few gotchas, you have to include the react select css for the component to display properly
import "react-select/dist/react-select.css";
the function mapPropsToValues option field should be initialised to an object
mapPropsToValues: props => ({
myText: "",
option: {}
Finally here is a link to the codesandbox example

How to pass select dropdown's data from redux-form to backend api in redux

I have a redux form where I have 2 input fields and one select drop-down. I wan to store the values of the inputs to a backend api. I am able to get the values from the inputs and pass it to the server, but for some reason I am not able to correctly get the select drop-down value and pass it to the back-end server. I know I am doing some silly mistake with the state, but I am not able to figure out what is that.My file is as shown below:
import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import { createPosts } from '../actions/posts_action';
class CreatePost extends Component {
constructor() {
super();
this.state = {
selectValue : 'react'
};
this.handleChange = this.handleChange.bind(this);
this.renderCategory = this.renderCategory.bind(this);
}
renderField(field) {
return(
<div className="title-design">
<label className="label-design"> {field.label} </label>
<input
type="text"
className="title-input"
{...field.input}
/>
<div className="text-help has-danger">
{field.meta.touched ? field.meta.error : ''}
</div>
</div>
);
}
handleChange(e) {
this.setState({selectValue: e.target.value});
console.log(this.state.selectValue);
}
renderCategory(field) {
return(
<div className="title-design">
<label className="label-design">{field.label} </label>
<select
name="categories"
className="title-input"
value={this.state.selectValue}
onChange={this.handleChange} >
<option value="react">React</option>
<option value="redux">Redux</option>
<option value="udacity">Udacity</option>
</select>
{this.state.selectValue}
</div>
);
}
onSubmit(values) {
this.props.createPosts(values, () => {
this.props.history.push('/');
});
}
render() {
const { handleSubmit } = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Title for Post"
name="title"
component={this.renderField}
/>
<Field
label="Post Content"
name="body"
component={this.renderField}
/>
<Field
label="Category"
name="category"
component={this.renderCategory}
/>
<button type="submit" className="btn btn-primary">Submit</button>
<Link to="/">
<button className="cancel-button">Cancel</button>
</Link>
</form>
);
}
}
function validate(values) {
const errors = {} ;
if (!values.title) {
errors.title = "Enter a title";
}
if (!values.body) {
errors.body = "Enter some content";
}
return errors;
}
export default reduxForm({
validate : validate, //validate
form : 'CreatePostForm'
})(
connect(null,{ createPosts })(CreatePost)
);
NOTE: Also,I want to generate a unique id for each of the records that is passed to the server so that I can refer to them when I want to retrieve data and display it.Can anyone please guide me how to proceed with both the issues?
setState is not synchronous, it has a callback so you should have something like:
handleChange(e) {
this.setState({selectValue: e.target.value}, () => {
console.log(this.state.selectValue);
});
}
To set the value of the field, you can use change whose signature is:
change(field:String, value:any)
So your handler will just become:
handleChange(e) {
const value = e.target.value;
this.props.change("categories", value);
this.setState({ "selectValue": value }, () => {
console.log(value);
});
}
and in your renderCategory you can remove the value attribute:
...
<select
name="categories"
className="title-input"
onChange={this.handleChange} >
...
To set some random id for every submission, you can find lots of libraries to generate a random one; to assign to the record, use again change method and field "id" will be sent to the server:
this.props.change('id', <random generated Id>)
See this sandbox a rough implementation

Creating a form in React that saves data

I am trying to create a customer details form in react (currently using react-json-form) where I can reuse the values in the inputs to create a saved file that the app can refer to. I have created the form and can output the results but I am unsure how to save the input values for future use or call them back once they are saved.
If anyone has any suggestions or examples of a form that does this then I would be greatly appreciative.
My code is as follows:
import React, { Component } from 'react';
import JSONTree from 'react-json-tree';
import { BasicForm as Form, Nest, createInput } from 'react-json-form';
const Input = createInput()(props => <input type="text" {...props} />);
const UserFields = () => (
<section>
<h3>User</h3>
<div>Name: <Input path="name" /></div>
<div>Email: <Input path="email" /></div>
</section>
);
export default class ExampleForm extends Component {
state = { data: {} };
updateData = data => this.setState({ data });
render() {
return (
<Form onSubmit={this.updateData}>
<Nest path="user">
<UserFields />
</Nest>
<button type="submit">Submit</button>
<JSONTree data={this.state.data} shouldExpandNode={() => true} />
</Form>
);
}
}
A more simple solution would be to use a form, like a semanti-ui-react form, store the information to the state onChange, then convert the info to JSON for storage.
import { Form, Button } from 'semantic-ui-react'
export default class App extends Component {
constructor() {
super()
this.state = {
name: "",
email: ""
}
}
handleChange = (e, {name, value}) => {
console.log(name, value)
this.setState({[name]: value})
}
render() {
return (
<div>
<Form onSubmit={this.sendDataSomewhere}>
<Form.Field>
<Form.Input name="name" value={this.state.name} onChange={this.handleChange}/>
</Form.Field>
<Form.Field>
<Form.Input name="email" value={this.state.email} onChange={this.handleChange}/>
</Form.Field>
<Button type="submit">Submit</Button>
</Form>
</div>
)
}
}
I use a dynamic method of receiving the input from different fields using the name and val attributes. The values captured in state are then accessible by this.state.whatever
Hope this helped

Clear an input field with Reactjs?

I am using a variable below.
var newInput = {
title: this.inputTitle.value,
entry: this.inputEntry.value
};
This is used by my input fields.
<input type="text" id="inputname" className="form-control" ref={el => this.inputTitle = el} />
<textarea id="inputage" ref={el => this.inputEntry = el} className="form-control" />
<button className="btn btn-info" onClick={this.sendthru}>Add</button>
Once I activate {this.sendthru} I want to clear my input fields. However, I am uncertain how to do so.
Also, as shown in this example, it was pointed out to me that I should use the ref property for input values. What I am unclear of is what exactly does it mean to have {el => this.inputEntry = el}. What is the significance of el in this situation?
Let me assume that you have done the 'this' binding of 'sendThru' function.
The below functions clears the input fields when the method is triggered.
sendThru() {
this.inputTitle.value = "";
this.inputEntry.value = "";
}
Refs can be written as inline function expression:
ref={el => this.inputTitle = el}
where el refers to the component.
When refs are written like above, React sees a different function object each time so on every update, ref will be called with null immediately before it's called with the component instance.
Read more about it here.
Declare value attribute for input tag (i.e value= {this.state.name}) and if you want to clear this input value you have to use this.setState({name : ''})
PFB working code for your reference :
<script type="text/babel">
var StateComponent = React.createClass({
resetName : function(event){
this.setState({
name : ''
});
},
render : function(){
return (
<div>
<input type="text" value= {this.state.name}/>
<button onClick={this.resetName}>Reset</button>
</div>
)
}
});
ReactDOM.render(<StateComponent/>, document.getElementById('app'));
</script>
I'm not really sure of the syntax {el => this.inputEntry = el}, but when clearing an input field you assign a ref like you mentioned.
<input type="text" ref="someName" />
Then in the onClick function after you've finished using the input value, just use...
this.refs.someName.value = '';
Edit
Actually the {el => this.inputEntry = el} is the same as this I believe. Maybe someone can correct me. The value for el must be getting passed in from somewhere, to act as the reference.
function (el) {
this.inputEntry = el;
}
I have a similar solution to #Satheesh using React hooks:
State initialization:
const [enteredText, setEnteredText] = useState('');
Input tag:
<input type="text" value={enteredText} (event handler, classNames, etc.) />
Inside the event handler function, after updating the object with data from input form, call:
setEnteredText('');
Note: This is described as 'two-way binding'
You can use input type="reset"
<form action="/action_page.php">
text: <input type="text" name="email" /><br />
<input type="reset" defaultValue="Reset" />
</form>
Now you can use the useRef hook to get some magic if you do not want to use the useState hook:
function MyComponent() {
const inputRef = useRef(null);
const onButtonClick = () => {
// #ts-ignore (us this comment if typescript raises an error)
inputRef.current.value = "";
};
return (
<>
<input ref={inputRef} type="text" />
<button onClick={onButtonClick}>Clear input</button>
</>
);
}
As I mentioned, if you are using useState that is the best way. I wanted to show you also this special approach.
Also after React v 16.8+ you have an ability to use hooks
import React, {useState} from 'react';
const ControlledInputs = () => {
const [firstName, setFirstName] = useState(false);
const handleSubmit = (e) => {
e.preventDefault();
if (firstName) {
console.log('firstName :>> ', firstName);
}
};
return (
<>
<form onSubmit={handleSubmit}>
<label htmlFor="firstName">Name: </label>
<input
type="text"
id="firstName"
name="firstName"
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
/>
<button type="submit">add person</button>
</form>
</>
);
};
You can use useState:
import React, { useState } from 'react';
const [inputTitle, setInputTitle] = useState('');
then add value to your input component:
render() {
<input type="text" onChange={(e) => setInputTitle(e.target.value)}
value={inputTitle} />
<button onClick={handleSubmit} type="submit">Submit</button>
}
On your submit handler function:
setInputTitle('');
document.querySelector('input').defaultValue = '';
On the event of onClick
this.state={
title:''
}
sendthru=()=>{
document.getElementByid('inputname').value = '';
this.setState({
title:''
})
}
<input type="text" id="inputname" className="form-control" ref={el => this.inputTitle = el} />
<button className="btn btn-info" onClick={this.sendthru}>Add</button>
I used the defaultValue property, useRef, and onClick to achieve this.
let ref = useRef()
and then inside the return:
<input type="text" defaultValue="bacon" ref={ref} onClick={() => ref.current.value = ""} />
also if you want to use onChange for the input it wouldn't require any more configuration and you can just use it. If you want to have a dynamic defaultValue then you absolutely can, with useState.
A simple way to reset the input in React is by implementing the onBlur inside the input.
onBlur={cleanSearch}
ej:
const [search, setSearch] = useState('')
const handleSearch = ({target}) =>{
setSearch(target.value)
}
const cleanSearch = () =>setSearch('')
<input
placeholder="Search…"
inputProps={{ 'aria-label': 'search' }}
value={search}
onChange={handleSearch}
onBlur={cleanSearch}
/>
The way I cleared my form input values was to add an id to my form tag.
Then when I handleSubmit I call this.clearForm()
In the clearForm function I then use document.getElementById("myForm").reset();
import React, {Component } from 'react';
import './App.css';
import Button from './components/Button';
import Input from './components/Input';
class App extends Component {
state = {
item: "",
list: []
}
componentDidMount() {
this.clearForm();
}
handleFormSubmit = event => {
this.clearForm()
event.preventDefault()
const item = this.state.item
this.setState ({
list: [...this.state.list, item],
})
}
handleInputChange = event => {
this.setState ({
item: event.target.value
})
}
clearForm = () => {
document.getElementById("myForm").reset();
this.setState({
item: ""
})
}
render() {
return (
<form id="myForm">
<Input
name="textinfo"
onChange={this.handleInputChange}
value={this.state.item}
/>
<Button
onClick={this.handleFormSubmit}
> </Button>
</form>
);
}
}
export default App;

Categories