“iDid” Part 2 – Responsive Checkboxes with React Material-UI

So I’ve officially graduated from Flatiron School (yay!), and have become infinitely more comfortable with React and Material UI. I wrote about the creation of my app, “iDid” in Part 1, which at its onset was extremely challenging for me. Since then, I’ve gone back to tweak the design and user experience, among other things. Recently I finished a responsive form using checkboxes, so I’d like to share it with you!

First a quick overview of the app’s functionality. There are only two classes that make up most of the app’s functionality, Counter and Action:

So a Counter is the thing you want to count, and an Action is a user-submitted entry counting that thing. Originally, I had the user select the measurement unit on submitting the action, but I decided that for uniformity and ease of use, it would be better to store the measurement unit within the Counter object. This also made it much easier to implement a leaderboard (more on that in the future!) since everyone counting a particular thing will be measuring it the same way.

So if you haven’t read Part 1, I have a pretty little FAB that takes you to the Action form. You then select or type in what you want to count, and the Combo Box will auto-fill to select the Counter you are looking for. However, we want to add something new to count, so let’s click “Count Something Else” and see what I made!

Here is the Counter form. It doesn’t look like much, but let’s take a closer look. Remember, with a Counter, our attributes are name, kind, and I said that I added measurement_unit as well. So the text field handles name, and the checkboxes determine kind. That’s all we need if we are counting, say, how many Cheetos we ate. We only need to provide a measurement unit if necessary, i.e. if we have selected one of the checkboxes!

Using internal state, I am keeping track of kind, like so:

  const [kind, setKind] = React.useState({
    weighted: false,
    timed: false,
  });

For the checkboxes, I am using Material-UI’s FormControl, which allows you to provide an error prop, a boolean, to determine the error status. For that, I created a like-named const to pass to the error prop. Since the kind can’t be bother weighted and timed, it looks like this:

const error = kind.timed && kind.weighted

Then to control the checkbox value with state, I simply provide the correct values to their checked prop:

<FormControlLabel 
  control={<Checkbox onChange={handleChange} name="weighted" checked={kind.weighted} />}
  label="Track weight with this counter"       />

<FormControlLabel
  control={<Checkbox onChange={handleChange} name="timed" checked={kind.timed} />}
  label="This is a timed activity"              />

Finally, I need to provide the select box that allows the user to choose the measurement_unit. I created a UnitSelect element for this purpose, which is displayed like so:

{kind.timed || kind.weighted ? <UnitSelect /> : null}

I also wanted to provide the user with options based on which kind was selected, i.e. you shouldn’t see “seconds” or “minutes” as an option if you selected “weighted”. Since Material-UI’s NativeSelect functions basically the same as an HTML select tag, it was pretty simple:

<NativeSelect
            value={measurementUnit}
            onChange={(e) => setMeasurementUnit(e.target.value)}
            name='measurement_unit'
          >

{kind.timed ? <><option value={'minutes'}>Minutes</option><option value={'seconds'}>Seconds</option></> : null}

{kind.weighted ? <><option value={'lb'}>Pounds (lb)</option><option value={'kg'}>Kilograms (kg)</option></> : null}

...

And that’s it! Thanks for reading, and I hope perhaps seeing my implementation was helpful in some way. Click here to go directly to the counter form on my Github repo for this project, and stay tuned for more as I continue adding features to this app, as I have lots planned!

Leave a comment

Design a site like this with WordPress.com
Get started