Ad

How To Clear A 'React Boostrap-validation' Form?

- 1 answer

I have a form on a page where the form submit button is adding rows to the page - this operation can be done repeatedly before the page itself is finally closed

<div className="panel-body line-items">
     {/* A line-item row for each existing line item.  These update if they are typed in... */}
     {this.state.lineItems.map( (li, index) =>
         <LineItem key={index} item={li} } />
     )}
     {/* And a line-item form where we can add another one...*/}
     <CreateLineItemForm onSubmit={this.submitLineItem.bind(this)}/>
 </div>

The form looks like this:

const CreateLineItemForm = ({onSubmit}) => (
    <Form onValidSubmit={onSubmit} className="panel form-horizontal">
        <div className="line-item line-item-input-row">
           <ValidatedInput type="text" name="summary"/>
           $<ValidatedInput type="number" name="cost"/>
           <Button type="submit" id="createLineItem" className="btn">
              <i className="fa fa-plus-square fa-lg"/></Button>
        </div>
    </Form>
)

submitLineItem() on the form adds the line item defined by the summary and cost inputs into this.state, which causes a re-render with that new line item appearing in the line-items panel.

This all works the way I want, except that the form input fields ("summary" and "cost") are not cleared when I hit the button. This means that those inputs always contain a "duplicate" of the newly created line item row, after the first row has been entered.

How can I clear these form fields (either as part of submitLineItem() or some other way)?

<Form> and <ValidatedInput> come from react-bootstrap-validation.

Ad

Answer

If you find yourself repeating a grouping of code over and over again, then that's usually a good candidate for a component. Why not break

<div key={index}>
    <Input type="text" name={"lineItem"+index} value={li.summary} onChange={this.onLineItemDescriptionChange.bind(this, index)}/>
   $<Input type="number" step="0.01" wrapperClassName="line-item-cost" name={"lineItemCost"+index} value={li.cost}
onChange={this.onLineItemValueChange.bind(this, index)}/>
</div>

For example:

   React.createClass({
     getInitialState() {
       return {
        someState: true
       }
     }
     render() {
      return (
        <div key={index}>
         <Input type="text" name={"lineItem"+index} value={li.summary} onChange={this.onLineItemDescriptionChange.bind(this, index)}/>
         $<Input type="number" step="0.01" wrapperClassName="line-item-cost" name={"lineItemCost"+index} value={li.cost}
        onChange={this.onLineItemValueChange.bind(this, index)}/>
        </div>
      )
     }
   })

If you're looking to reset the state of the form that initially holds the data, you could easily do it in the creation handler. You'd probably want to assign it to a button or something that gets clicked, if possible. You can also listen for a return keyUp I believe.

function handleCreateNewLineItem(e) {
  e.preventDefault() // if using a form element
  // update your state
  this.setState({
     li.cost: 0,
     li.summary: ''
  })
}

Into a component, give it either default props or an initial state, and then when you create a new one it'll be empty/cleared?

Ad
source: stackoverflow.com
Ad