Josh
Josh

Reputation: 1235

React/Redux: Need to build a React component with Redux that dynamically generates additional dropdowns based on initial dropdown selection

I need to build a React Component with a Redux action and reducer to handle a selection from a dropdown. Something along the lines of an action UPDATE_NUMBER_OF_DROPDOWNS that will act as the listener on the dropdown to trigger an action/reducer flow. The current layout will be a single dropdown with a set of options for 0, 1, 5 and 13 and depending on what number the user selects that many rows with dropdown fields of their own will populate. So if a user selects 5, an additional section will appear below with 5 rows of fields called Justification each with their own dropdown that lists a subset of options. I'm new to Redux so I'm trying to determine how to accomplish this, but I think I need I've included the base state of my React component below Select Form Component

import React from 'react'
import styled from 'styled-components'
import { Col, Row, Collapse } from 'antd'
import Checkbox from '../elements/Checkbox'
import icon from '../../assets/caretDown.svg'
import Button from '../elements/Button'

const { Panel } = Collapse

const ConfigurationOptions = () => (
  <Container>
    <Row>
      <Col span={12}>
        <StyledCollapse>
          <Panel
            header="Configure Form"
            key="1"
          >
            <div>
              <Row>
                <Col span={12}>
                  <p>Form Fields</p>
                </Col>
                <Col span={12}>
                  <CustomSelect>
                    <option>none</option>
                    <option>5 Form Fields</option>
                    <option>10 Form Fields</option>
                    <option>13 Form Fields</option>
                  </CustomSelect>
                </Col>
              </Row>
              <div>
                <StyledH1>Form Field Justification</StyledH1>
                <Row>
                  <Col
                    span={8}
                    offset={16}
                  >
                    <ButtonContainer>
                      <Button
                        type="primary"
                        Apply to all
                      </Button>
                    </ButtonContainer>
                  </Col>
                </Row>
                <br />
                <Row>
                  <Col span={12}>Field #1</Col>
                  <Col span={12}>
                    <CustomSelect>
                      <option>Select Justification</option>

                    </CustomSelect>
                  </Col>
                </Row>
              </div>
            </div>
          </Panel>
        </StyledCollapse>
      </Col>
    </Row>
</Container>
)

const Container = styled.div`
  text-align: left;
`

const StyledH1 = styled.h1`
  font-weight: 700;
`

const CustomSelect = styled.select`
  padding: 5px 45px 5px 10px;
  font-size: 0.75rem;
  line-height: 1.4rem;
  font-weight: 500;
  color: black;
  border: 2px solid black;
  height: 30px;
  width: 75%;
  background-color: ${({ theme }) => theme.colors.white};
  border-radius: 0;
  appearance: none;
  background-image: url(${icon});
  background-repeat: no-repeat;
  background-position: right 8px center;
`

const ButtonContainer = styled.div`
  display: flex;
  align-items: baseline;
`

// Use for Show/Hide link
/* <Button type="link">APPLY TO ALL</Button> */

export default ConfigurationOptions

Upvotes: 0

Views: 83

Answers (1)

GalAbra
GalAbra

Reputation: 5138

I think the missing pieces for you are the Array.map() and onChange() methods.

  1. You can use some sort of data structure to store the values of your options, then use map to dynamically build your HTML.
  2. You can detect changing the calue of <CustomSelect> by defining a local method that handles the user's progress (i.e. which of the selection elements are rendered).

Of course you have to define onChoosingOption and this.state.value, but eventually it'd look something like this:

const firstLevelOptions = [0, 5, 10, 13];

<CustomSelect onChange={this.onChoosingOption} value={this.state.value}>
  {
    firstLevelOptions.map(x => <option value={x}>
                                 {x === 0 ? 'none' : x + ' Form Fields'}
                               </option>)
  }
/*
Results in
  <option value="0">none</option>
  <option value="5">5 Form Fields</option>
  <option value="10">10 Form Fields</option>
  <option value="13">13 Form Fields</option>
*/
</CustomSelect>

And then you can use pretty much the same thing with the next levels.

Upvotes: 1

Related Questions