4

I have a Form with an Input field, a TextArea and two (2) Buttons in a footer within the Form. The first button is for resetting the form and the second to update it. My problem is when I press "enter" in the Input field, the Form is submitted but it seems that it always triggers the logic of the first button (in my case resetting the form). If I switch the order of the buttons so that the Update button is first, then the form is updated upon pressing "enter". Only the update button has the "submit" type.

I have looked in the documentation and could not find anything regarding this behavior. I have also checked the source code a little bit and didn't see what could cause this. I tried setting up the onSubmit callback of the Form to the same function of the update button but the "cancel" logic is still being called first.

How can I control the "enter" logic of the Input field within the form?

Here's the code:

import React from 'react';
import PropTypes from 'prop-types';
import { Form, Input, TextArea, Button } from 'semantic-ui-react';
import I18n from '../../shims/i18n_global';

export default class SpaceDetails extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      details: {
        id: props.id,
        name: props.name,
        description: props.description,
      },
      formError: false,
      formDisabled: true,
    };

    this.originalDetails = Object.assign({}, this.state.details);

    this.handleNameUpdate = this.handleNameUpdate.bind(this);
    this.handleDescriptionUpdate = this.handleDescriptionUpdate.bind(this);
    this.handleDetailsUpdate = this.handleDetailsUpdate.bind(this);
    this.handleResetForm = this.handleResetForm.bind(this);
  }

  setFormStatus(error = false, disabled = false) {
    this.setState({ formError: error, formDisabled: disabled });
  }

  setDetailsValue(detailProp, value) {
    this.setState({
      details: Object.assign(
        {},
        this.state.details,
        {
          [detailProp]: value,
        },
      ),
    });
  }

  get trimmedDetails() {
    return Object.assign(
      {},
      this.state.details,
      { name: this.state.details.name.trim() },
      { description: this.state.details.description.trim() },
    );
  }

  handleNameUpdate(event) {
    this.setFormStatus(event.target.value.trim() === '');
    this.setDetailsValue('name', event.target.value);
  }

  handleDescriptionUpdate(event) {
    this.setFormStatus();
    this.setDetailsValue('description', event.target.value);
  }

  handleDetailsUpdate() {
    this.props.onUpdate(Object.assign(
      { icon: null },
      this.trimmedDetails,
    ));
    this.resetFileInputField();
  }

  handleResetForm() {
    this.setFormStatus(false, true);
    this.setState({ details: this.originalDetails });
  }

  render() {
    return (
      <Form >
        <h2 >{I18n.t('space.edit.details.title')}</h2 >
        <Form.Field
          className="field-full"
        >
          <Input
            id="name"
            type="text"
            name="name"
            placeholder={I18n.t('space.edit.details.placeholders.name')}
            size="large"
            error={this.state.formError}
            value={this.state.details.name}
            onChange={this.handleNameUpdate}
          />
        </Form.Field >
        <Form.Field
          className="field-full"
        >
          <TextArea
            id="description"
            className="field-full"
            rows="4"
            cols="50"
            placeholder={I18n.t('space.edit.details.placeholders.description')}
            value={this.state.details.description}
            onChange={this.handleDescriptionUpdate}
          />
        </Form.Field >
        <div className="form-footer" >
          <Button
            size="big"
            className="btn-xxl"
            content="Reset"
            onClick={this.handleResetForm}
          />
          <Button
            type="submit"
            primary
            size="big"
            className="btn-xxl"
            content="Save"
            disabled={this.state.formDisabled}
            onClick={this.handleDetailsUpdate}
          />
        </div >
      </Form >
    );
  }
}

SpaceDetails.defaultProps = {
  name: '',
  description: '',
};

SpaceDetails.propTypes = {
  id: PropTypes.number.isRequired,
  name: PropTypes.string,
  description: PropTypes.string,
  onUpdate: PropTypes.func.isRequired,
};

Thanks!

Whyves
  • 491
  • 5
  • 13
  • can you please share a minimal code example of what you are doing? I have a guess as to the problem you are having, but I'd need to see your code to be sure so I can submit a proper answer. – brianespinosa May 23 '18 at 13:42
  • @brianespinosa, I have added the code ... sorry, it's not a sample but since it was not that big and self contained, I posted it. Thanks for looking into it! – Whyves May 23 '18 at 16:37

1 Answers1

3

Whyves, I think because the first button does not have a type defined, it is being used to submit automatically. Try defining that first button as type="reset" and I think that will do it. The default prop for SUIR buttons appears to be "button" but it seems that is not being respected by your browser being that there should technically be two <button/> tags rendered from this JSX.

brianespinosa
  • 2,408
  • 12
  • 22