0

Let's say I have some properties which can be equal to some possible options. I'll define these both in someConstants.js

const possibleOptions = [
    {key: '1', text: "some text 1", value: "some_text_1"},
    {key: '2', text:  "some text 2", value:  "some_text_2"},
];

const someProperties = {
    flags: []
};


export { someProperties, possibleOptions };

I want someProperties.flags to be updated by possibleOptions upon submission of the form someForm.js

import React from "react";
import { someProperties, possibleOptions } from "./someConstants";
import { Form } from "semantic-ui-react";
import "./styles.css";

class SomeForm extends React.Component {
    state = someProperties;

    handleSubmit = event => {
        event.preventDefault();
        this.props.onSubmit(this.state);
    };

    onChange = event => {
        const {
            target: { name, value }
        } = event;

        this.setState({
            [name]: value
        });
    };

    render() {
        return (
            <Form onSubmit={this.handleSubmit} onChange={this.onChange}>
                <Form.Dropdown
                    label="Flags"
                    placeholder="Flags"
                    name="flags"
                    fluid
                    multiple
                    search
                    selection
                    options={possibleOptions}
                />

                <Form.Button type="submit">Submit</Form.Button>
            </Form>
        );
    }
}

export { SomeForm };

These values will be displayed by showFlags.js

import React from "react";
import "./styles.css";

class ShowFlags extends React.Component {
    displayList = list => {
        return(
            <ol>
                {list.map(flag => (
                    <li key={flag}>{flag}</li>
                ))}
            </ol>
        );
    }

    render() {
        return (
            <div>
                {this.props.flagProps.flags}
            </div>
        );
    }
}

export { ShowFlags };

The interaction of these classes can be shown further in index.js

import React from "react";
import ReactDOM from "react-dom";
import { SomeForm } from "./someForm";
import { ShowFlags } from "./showFlags";

class App extends React.Component {
    state = {
        flagProps: {},
        submitted: false
    };

    handleSubmit = fields => {
        this.setState({
            flagProps: { ...fields },
            submitted: true
        });
        console.log("handleSubmit flagProps:" + this.state.flagProps);
    };

    render() {
        return (
            <>
                <div className="Section">
                    <div className="Title">flagProps form</div>
                    <SomeForm flagProps={this.state.flagProps} onSubmit={this.handleSubmit} />
                </div>
                <div className="Section">
                    <div className="Title">The result</div>
                    {this.state.submitted ? (
                        <ShowFlags flagProps={this.state.flagProps} />
                    ) : (
                        <div>Appears on submission.</div>
                    )}
                </div>
            </>
        );
    }
}

ReactDOM.render(<App />, document.getElementById("root"));

How can I achieve this? To summarize:

Current behavior I am able to choose options, but submission of the form does not yield any display. ShowFlags.render() shows nothing.

Desired behavior I am able to choose options, and those options are displayed by ShowFlags.render() upon submission of the form.

If it matters, this is using semantic-ui.

2
  • Is something preventing this theoretical from working? And if so are there any error messages in the console? Reading it over I'd say "onSubmit" might be a problematic name for a prop because it's the React version of onsubmit. Maybe try replacing it with something like "whenSubmit". Commented Feb 29, 2020 at 2:20
  • @SydneyY Something is preventing it from working, but I am unsure what -- though I can confirm the name of onSubmit is not the issue. Commented Feb 29, 2020 at 23:56

1 Answer 1

2
+50

Here's your fixed code:

  onChange = (event, data) => {
    this.setState({
      [data.name]: data.value
    });
  };

  render() {
    return (
      <Form onSubmit={this.handleSubmit}>
        <Form.Dropdown
          label="Flags"
          placeholder="Flags"
          name="flags"
          fluid
          multiple
          search
          selection
          options={possibleOptions}
          value={this.state.flags}
          onChange={this.onChange}
        />

        <Form.Button type="submit">Submit</Form.Button>
      </Form>
    );
  }

https://codesandbox.io/s/exciting-kare-31l7w?file=/src/SomeForm.jsx

You forgot to apply the onChange handler to the Form.Dropdown in SomeForm, though the way semantic-ui-react works is that the change handlers have the props passed down to them as the second argument to the change function. Then the new value would be data.value.

You also should set the value of the Form.Dropdown to be value={this.state.flags} so it's a fully controlled component since you are bringing it into state anyway.

I also removed the Form's onChange handler as that doesn't affect the Dropdown at all. Semantic UI React (SUI) doesn't have it listed in their Form's Props.

Having an onChange handler on the form is a html property rather than an SUI prop. Which would explain why it doesn't work for Dropdowns. As they don't have a normal input/select html element base. This would also mean that the normal SUI's data argument to the onChange handlers wouldn't exist, so you'd need to get the attributes directly off the element.

Entire form onChange has an example of a form onChange handler, which looks to be very powerful for anything that has a base element that normally goes in a form.

Base html elements being: input, select, and textarea.

Sign up to request clarification or add additional context in comments.

4 Comments

So the Form.Dropdown has to have its onChange set explicitly? I didn't think that would be the case because the other Form components in my actual codebase default to the onChange specified in the parent <Form> attributes
Looks like dropdowns indeed have to have their own onChange handler. I haven't actually seen onChange as a prop on the Form element. I think that that might be just a base html property rather than an SUI prop. Which would explain why it doesn't work for Dropdowns. As they don't have a normal input/select base. stackoverflow.com/questions/10760847/entire-form-onchange has an example of it.
Would you mind editing that into the answer? I'll mark as complete and award the bounty when I am allowed to.
I added it to the answer and did a little reformatting while I was at it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.