17573: Adds redux-form controlled multi-checkbox selection component.
authorLucas Di Pentima <lucas.dipentima@curii.com>
Wed, 14 Jul 2021 20:55:15 +0000 (17:55 -0300)
committerLucas Di Pentima <lucas.dipentima@curii.com>
Wed, 14 Jul 2021 20:55:15 +0000 (17:55 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>

src/components/checkbox-field/checkbox-field.tsx

index 2b2a8a03e3e92b821239f22ea254777f839f76f2..bfa3714ae95a31bf78a9815f04a9673463f17bc2 100644 (file)
@@ -4,7 +4,14 @@
 
 import React from 'react';
 import { WrappedFieldProps } from 'redux-form';
 
 import React from 'react';
 import { WrappedFieldProps } from 'redux-form';
-import { FormControlLabel, Checkbox } from '@material-ui/core';
+import {
+    FormControlLabel,
+    Checkbox,
+    FormControl,
+    FormGroup,
+    FormLabel,
+    FormHelperText
+} from '@material-ui/core';
 
 export const CheckboxField = (props: WrappedFieldProps & { label?: string }) =>
     <FormControlLabel
 
 export const CheckboxField = (props: WrappedFieldProps & { label?: string }) =>
     <FormControlLabel
@@ -15,5 +22,46 @@ export const CheckboxField = (props: WrappedFieldProps & { label?: string }) =>
                 disabled={props.meta.submitting}
                 color="primary" />
         }
                 disabled={props.meta.submitting}
                 color="primary" />
         }
-        label={props.label} 
-    />;
\ No newline at end of file
+        label={props.label}
+    />;
+
+type MultiCheckboxFieldProps = {
+    items: string[];
+    label?: string;
+    minSelection?: number;
+    maxSelection?: number;
+    helperText?: string;
+    rowLayout?: boolean;
+}
+
+export const MultiCheckboxField = (props: WrappedFieldProps & MultiCheckboxFieldProps) => {
+    const isValid = (items: string[]) => (items.length >= (props.minSelection || 0)) &&
+        (items.length <= (props.maxSelection || items.length));
+    return <FormControl error={!isValid(props.input.value)}>
+        <FormLabel component='label'>{props.label}</FormLabel>
+        <FormGroup row={props.rowLayout}>
+        { props.items.map((item, idx) =>
+            <FormControlLabel
+                control={
+                    <Checkbox
+                        key={idx}
+                        name={`${props.input.name}[${idx}]`}
+                        value={item}
+                        checked={props.input.value.indexOf(item) !== -1}
+                        onChange={e => {
+                            const newValue = [...props.input.value];
+                            if (e.target.checked) {
+                                newValue.push(item);
+                            } else {
+                                newValue.splice(newValue.indexOf(item), 1);
+                            }
+                            if (!isValid(newValue)) { return; }
+                            return props.input.onChange(newValue);
+                        }}
+                        disabled={props.meta.submitting}
+                        color="primary" />
+                }
+                label={item} />) }
+        </FormGroup>
+        <FormHelperText>{props.helperText}</FormHelperText>
+    </FormControl> };
\ No newline at end of file