Handle controlled checbox

60 Views Asked by At

I have a form where I am rendering checkbox from map, how can I handle when someone unchecked box? Now i am using isChecked to set it.

import React, {ChangeEvent, Fragment, useCallback, useEffect, useState} from 'react';

import Button from '@atlaskit/button/standard-button';
import {Checkbox} from '@atlaskit/checkbox';
import {Grid, GridColumn} from '@atlaskit/page';

import Form, {CheckboxField, Field, FormFooter} from '@atlaskit/form';
import {ValueType as Value} from "@atlaskit/select/types";
import Select from "@atlaskit/select";
import {sentinelVulnerabilities} from "../constants";
import {invoke} from "@forge/bridge";

interface Option {
    label: string;
    value: string;
}

BasicConfiguration.defaultProps = {
    jiraIssuePriorities: [],
}

const columns = 12;
export default function BasicConfiguration({jiraIssuePriorities, initPriorites, allowedVulnerabilities}: any) {


    const [allowedVul, setAllowedVul] = useState<any | null>(undefined);

    useEffect(() => {
        (async () => {
            await invoke("getStorage", {name: 'vulnerabilities_allowed'}).then(setAllowedVul);
        })();
    }, [])

    const jiraIssuePrioritiesOptions = jiraIssuePriorities.map(({name, id}: any) => ({
        label: name,
        value: id,
    }));

    const shouldBySelected = (prioritySentinel: string) => {
        if (initPriorites === undefined || Object.keys(prioritySentinel).length === 0.)
            return '';

        return initPriorites[prioritySentinel];
    }

    const shouldBeChecked = (vulnName: string): boolean => {

        if (allowedVul === undefined || Object.keys(allowedVul).length === 0.) {
            return false;
        }
        return allowedVul.includes(vulnName);
    }

    const onSubmit = async (data: any) => {
        //Store mapping
        await invoke("setStorage", {name: "vulnerabilities_allowed", data: data.vulnerabilities});

        let priorities = {
            note: undefined,
            critical: undefined,
            high: undefined,
            medium: undefined,
            low: undefined
        };
        if (data.hasOwnProperty('critical')) {
            priorities.critical = data.critical.label;
        }

        if (data.hasOwnProperty('high')) {
            priorities.high = data.high.label;
        }

        if (data.hasOwnProperty('medium')) {
            priorities.medium = data.medium.label;
        }

        if (data.hasOwnProperty('low')) {
            priorities.low = data.low.label;
        }

        if (data.hasOwnProperty('note')) {
            priorities.note = data.note.label;
        }

        await invoke("setStorage", {name: 'vuln_priorities', data: priorities});
    }


    return (
        <div style={{
            display: 'flex',
            width: '600px',
            margin: '0 auto',
            flexDirection: 'column',
            paddingTop: 50,
        }}>

            <h3>Map Sentinel Vulnerabilities and Jira Issues</h3>
            <Form onSubmit={onSubmit}>
                {({formProps}) => (
                    <form {...formProps}>

                        {
                            sentinelVulnerabilities.map((element) => {
                                const isChecked = shouldBeChecked(element.value);
                                return <div>

                                    <Grid spacing="compact" columns={columns}>

                                        <GridColumn medium={4} css={{paddingTop: '5px'}}>
                                            <CheckboxField name="vulnerabilities" value={element.value}>
                                                {({fieldProps}) => <Checkbox {...fieldProps} label={element.label} isChecked={isChecked}
                                                />}
                                            </CheckboxField>


                                        </GridColumn>
                                        <GridColumn medium={8}>
                                            <Field<Value<Option>>
                                                name={element.value}
                                                isRequired={true}
                                                defaultValue={{
                                                    value: shouldBySelected(element.value).toLowerCase(),
                                                    label: shouldBySelected(element.value)
                                                }}

                                            >

                                            </Field>
                                        </GridColumn>
                                    </Grid>
                                </div>
                            })
                        }


                        
        </div>
    );
}

What i want to achive is when page render have checkbox checked based on function shouldBeChecked() but I want that user can uncheck the box and submit the form. For now user is not able to unchecked the box, checkbox is always checked.

1

There are 1 best solutions below

0
Enfield Li On

isChecked should be in a state, so it's value can be changed between different renders, otherwise it's value will always be the same returend from const isChecked = shouldBeChecked(element.value); on the first render within the map function.

And it's better to evaluate isChecked outside map function, because every time the component renders, the shouldBeChecked function will be running again which assins value to isChecked. So it'd be better to put this const isChecked = shouldBeChecked(element.value); in useEffect with empty dependency.