react-hook-form#Controller JavaScript Examples
The following examples show how to use
react-hook-form#Controller.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TagSelector.jsx From tinkerun with MIT License | 6 votes |
TagSelector = () => {
const {control} = useFormContext()
return (
<Controller
name='tag'
control={control}
defaultValue='local'
render={({
field: {value, onChange},
}) =>
<Select
height={majorScale(3)}
value={value}
onChange={e => onChange(e.target.value)}
>
<option value="local">local</option>
<option value="testing">testing</option>
<option value="development">development</option>
<option value="staging">staging</option>
<option value="production">production</option>
</Select>
}
/>
)
}
Example #2
Source File: DocumentForm.jsx From saasgear with MIT License | 6 votes |
DocumentForm = ({ editorContent, onSubmit, register, control, formErrors, apiError, isSubmitting, }) => ( <form onSubmit={onSubmit}> <FormGroup> <FormGroupLabel>Name</FormGroupLabel> <Input name="name" ref={register} /> {formErrors?.name && <ErrorText message={formErrors.name.message} />} </FormGroup> <FormGroup> <FormGroupLabel>Body</FormGroupLabel> <Controller name="body" control={control} defaultValue="" render={({ onChange }) => ( <WYSIWYGEditor editorContent={editorContent} onChange={onChange} /> )} /> {formErrors?.body && <ErrorText message={formErrors.body.message} />} </FormGroup> {apiError && <ErrorText message={apiError} />} <ButtonGroup> <SaveBtn color="primary" type="submit" disabled={isSubmitting}> {isSubmitting ? 'Please wait' : 'Save'} </SaveBtn> </ButtonGroup> </form> )
Example #3
Source File: index.js From hook-form-mui with MIT License | 6 votes |
function FormCheckBox(props) {
const { control } = useFormContext();
const { name, label } = props;
return (
<React.Fragment>
<Controller
as={MuiCheckbox}
name={name}
control={control}
defaultValue={false}
label={label}
{...props}
/>
</React.Fragment>
);
}
Example #4
Source File: OverSSHButton.jsx From tinkerun with MIT License | 6 votes |
OverSSHButton = props => {
const {control} = useFormContext()
return (
<Controller
name='is_over_ssh'
control={control}
defaultValue={false}
render={({
field: {value, onChange},
}) => (
<Button
height={majorScale(3)}
onClick={() => onChange(!value)}
isActive={value}
{...props}
>
<FormattedMessage id='connections.over_ssh'/>
</Button>
)}
/>
)
}
Example #5
Source File: FileInput.js From ultimate-react-hook-form-form with MIT License | 6 votes |
FileInput = ({ control, name }) => {
const styles = useStyles();
return (
<Controller
control={control}
name={name}
defaultValue={[]}
render={({ onChange, onBlur, value }) => (
<>
<Dropzone onDrop={onChange}>
{({ getRootProps, getInputProps }) => (
<Paper
variant="outlined"
className={styles.root}
{...getRootProps()}
>
<CloudUpload className={styles.icon} />
<input {...getInputProps()} name={name} onBlur={onBlur} />
<p>Drag 'n' drop files here, or click to select files</p>
</Paper>
)}
</Dropzone>
<List>
{value.map((f, index) => (
<ListItem key={index}>
<ListItemIcon>
<InsertDriveFile />
</ListItemIcon>
<ListItemText primary={f.name} secondary={f.size} />
</ListItem>
))}
</List>
</>
)}
/>
);
}
Example #6
Source File: CreateTopicEditor.js From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal | 6 votes |
CreateTopicEditor = ({
control,
inputError,
modules,
formats,
inputName,
}) => {
return (
<Controller
name={inputName}
control={control}
render={(props) => {
return (
<QuillNoSSRWrapper
modules={modules}
value={props.value}
onChange={props.onChange}
formats={formats}
theme="snow"
className={`mt-1 form-input border ${
!inputError.description
? "border-gray-300 focus:border-blue-300"
: "border-red-300 focus:border-red-300"
} rounded-md shadow-sm`}
/>
)
}}
/>
)
}
Example #7
Source File: index.js From plataforma-sabia with MIT License | 5 votes |
Editor = ({ config, form, name, disabled, onChange, defaultValue, renderWithController }) => {
const { control, setValue } = form;
if (renderWithController) {
return (
<Controller
name={name}
render={({ field }) => (
<CKEditor
// eslint-disable-next-line react/jsx-props-no-spreading
{...field}
editor={ClassicEditor}
config={config}
onChange={(_, editor) => {
const editorData = editor.getData();
if (onChange) {
onChange(editorData);
}
return field.onChange(editorData);
}}
data={defaultValue}
/>
)}
control={control}
disabled={disabled}
/>
);
}
let timerOnChange = null;
const handleChangeDebounced = (_, editor) => {
clearTimeout(timerOnChange);
timerOnChange = setTimeout(() => {
const editorData = editor.getData();
setValue(name, editorData, { shouldDirty: true });
if (onChange) {
onChange(editorData);
}
}, 500);
};
return (
<CKEditor
editor={ClassicEditor}
config={config}
name={name}
onChange={handleChangeDebounced}
data={defaultValue}
/>
);
}
Example #8
Source File: Input.js From ponce-tournois-mario-kart with MIT License | 5 votes |
Input = React.forwardRef(
(
{
children,
name,
validationSchema,
label,
type,
defaultValue,
...rest
},
ref
) => {
const { register, errors, control } = useFormContext();
return (
<div className="inputWrapper">
{label && <label className="inputLabel">{label}</label>}
{type === 'checkbox' ? (
<Checkbox
name={name}
validationSchema={validationSchema}
ref={ref}
{...rest}
/>
) : (
<Controller
name={name}
control={control}
defaultValue={defaultValue}
render={(field) => (
<input
name={name}
ref={mergeRefs([
register(validationSchema),
ref,
])}
className={errors[name] ? 'inputInvalid' : ''}
type={type}
defaultValue={defaultValue}
min={validationSchema?.min?.value}
max={validationSchema?.max?.value}
onChange={(e) => {
let { value, min, max } = e.target;
if (type === 'number' && value) {
value = Math.max(
Number(min),
Math.min(Number(max), Number(value))
);
}
field.onChange(value);
}}
{...rest}
/>
)}
/>
)}
{children}
{errors[name] && errors[name].message && (
<div className="inputErrorMessage">
{errors[name].message}
</div>
)}
</div>
);
}
)
Example #9
Source File: DeploymentNameModal.js From akashlytics-deploy with GNU General Public License v3.0 | 5 votes |
DeploymentNameModal = ({ dseq, onClose, onSaved, getDeploymentName }) => {
const classes = useStyles();
const formRef = useRef();
const { enqueueSnackbar } = useSnackbar();
const { handleSubmit, control, setValue } = useForm({
defaultValues: {
name: ""
}
});
useEffect(() => {
if (dseq) {
const name = getDeploymentName(dseq);
setValue("name", name || "");
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [dseq, getDeploymentName]);
const onSaveClick = (event) => {
event.preventDefault();
formRef.current.dispatchEvent(new Event("submit", { cancelable: true, bubbles: true }));
};
function onSubmit({ name }) {
updateDeploymentLocalData(dseq, { name: name });
enqueueSnackbar(<Snackbar title="Success!" iconVariant="success" />, { variant: "success", autoHideDuration: 1000 });
onSaved();
}
return (
<Dialog open={!!dseq} onClose={onClose} maxWidth="xs" fullWidth>
<DialogTitle>Change Deployment Name {dseq ? `(${dseq})` : ""}</DialogTitle>
<DialogContent dividers className={classes.dialogContent}>
<form onSubmit={handleSubmit(onSubmit)} ref={formRef}>
<FormControl fullWidth>
<Controller
control={control}
name="name"
render={({ field }) => {
return <TextField {...field} autoFocus type="text" variant="outlined" label="Name" />;
}}
/>
</FormControl>
</form>
</DialogContent>
<DialogActions className={classes.dialogActions}>
<Button onClick={onClose}>Close</Button>
<Button variant="contained" color="primary" onClick={onSaveClick}>
Save
</Button>
</DialogActions>
</Dialog>
);
}
Example #10
Source File: reactHookForm.jsx From intergalactic with MIT License | 4 votes |
export default function App() {
const { register, handleSubmit, control, errors } = useForm({
mode: 'onBlur',
shouldFocusError: false,
});
const inputMaskRef = useRef(null);
const [filter, updateFilterValue] = useState('');
const [option, updateOption] = useState(listActuallyCountryCodes['Russia']);
const [value, updateValue] = useState(option.dial_code);
const [valueMask, updateValueMask] = useState(`${option.dial_code} (___)___-____`);
const [valueInput, setValueInput] = useState('');
const [valueBigInput, setValueBigInput] = useState('');
const [valueDate, setValueDate] = useState('');
const [valueTime, setValueTime] = useState('');
const [tags, updateTags] = useState(['vk', 'fk', 'twitter', 'instagram']);
const [valueTag, updateValueTag] = useState('');
const [valueSelect, setValueSelect] = useState(null);
const [valueRadio, setValueRadio] = useState('');
const [checked, setChecked] = useState(false);
let country;
const options = selectOptions.map((option) => ({
value: option,
children: option,
}));
useEffect(() => {
updateValueMask(`${option.dial_code} (___)___-____`);
}, [option]);
useEffect(() => {
if (value === valueMask) {
const position = getAfterPositionValue(value);
inputMaskRef?.current.setSelectionRange(position, position);
}
}, [value, valueMask]);
const handleAppendTags = (newTags) => {
updateTags((tags) => [...tags, ...newTags]);
updateValueTag('');
};
const handleRemoveTag = () => {
if (tags.length === 0) return;
updateTags(tags.slice(0, -1));
updateValueTag(tags.slice(-1)[0] + ` ${valueTag}`);
};
const handleCloseTag = (e) => {
const { dataset } = e.currentTarget;
updateTags(tags.filter((tag, ind) => ind !== Number(dataset.id)));
};
const isDateInvalid = useCallback(
(date) => {
return dayjs(date).isValid();
},
[valueTime],
);
const onSubmit = (data) => {
confirm(`Will be send ${JSON.stringify(data)}`);
};
return (
<div>
{/* "handleSubmit" will validate your inputs before invoking "onSubmit"*/}
<Box tag="form" w={390} onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<Flex direction="column" mb={4}>
<Text size={100}>Label</Text>
<Tooltip
interaction={errors['inputControl'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="You need to feel this useless field"
>
<Controller
as={
<Input mr={4} mt={1} w={390} state={errors['inputControl'] ? 'invalid' : 'normal'}>
<Input.Value
value={valueInput}
onChange={setValueInput}
placeholder="placeholder"
/>
</Input>
}
control={control}
rules={{ required: true, validate: (value) => value !== '' }}
name="inputControl"
defaultValue=""
/>
</Tooltip>
</Flex>
<Flex direction="column" mb={4}>
<Text size={100}>Label</Text>
<Tooltip
interaction={errors['inputBig'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="You need to feel this useless field"
>
<Textarea
w={390}
minRows={4}
maxRows={10}
ref={register({ required: true, validate: (value) => value !== '' })}
placeholder="placeholder"
value={valueBigInput}
onChange={setValueBigInput}
name="inputBig"
state={errors['inputBig'] ? 'invalid' : 'normal'}
/>
</Tooltip>
</Flex>
<Flex direction="column" mb={4}>
<Text size={100}>Date</Text>
<Tooltip
interaction={errors['inputDate'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="You need to feel this useless field"
>
<InputMask mr={4} mt={1} w={390} state={errors['inputDate'] ? 'invalid' : 'normal'}>
<Input.Addon>
<CalendarM />
</Input.Addon>
<InputMask.Value
name="inputDate"
ref={register({ required: true, validate: (value) => isDateInvalid(value) })}
mask="99.99.9999"
value={valueDate}
onChange={setValueDate}
placeholder="dd.mm.yyyy"
onSuccess={isDateInvalid}
/>
</InputMask>
</Tooltip>
</Flex>
<Tooltip
interaction={errors['timepicker'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="You need to choose the time"
>
<Controller
as={
<TimePicker
value={valueTime}
onChange={setValueTime}
state={errors['timepicker'] ? 'invalid' : 'normal'}
w={120}
mb={4}
>
<TimePicker.Hours />
<TimePicker.Separator />
<TimePicker.Minutes />
<TimePicker.Format
style={
errors['timepicker'] ? { borderColor: '#ff7f00' } : { borderColor: '#a6b0b3' }
}
/>
</TimePicker>
}
control={control}
rules={{ required: true, validate: (value) => value !== '' }}
name="timepicker"
defaultValue=""
/>
</Tooltip>
<br />
<Tooltip
interaction={errors['inputPhone'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="You need to enter the phone number"
>
<NeighborLocation controlsLength={2}>
<Select
value={option}
state={errors['inputPhone'] ? 'invalid' : 'normal'}
onChange={(value) => {
country = listActuallyCountryCodes[value];
updateOption(country);
updateValue(country.dial_code);
inputMaskRef?.current.focus();
}}
>
<Select.Trigger>
<Flag iso2={option.code} />
</Select.Trigger>
<Select.Popper>
<>
<Select.InputSearch
cleared
placeholder="Search"
value={filter}
onChange={updateFilterValue}
/>
<Select.List hMax="240px" w="232px">
{Object.keys(listActuallyCountryCodes)
.filter((countryName) => countryName.toLowerCase().includes(filter))
.map((countryName) => (
<Select.Option key={countryName} value={countryName}>
<Text size={200} mr={2} style={{ flexShrink: 0 }}>
<Flag iso2={listActuallyCountryCodes[countryName].code} />
</Text>
<Text size={200} mr={2}>
{countryName}
</Text>
<Text size={200} color="gray60">
{listActuallyCountryCodes[countryName].dial_code}
</Text>
</Select.Option>
))}
</Select.List>
</>
</Select.Popper>
</Select>
<Controller
as={
<InputMask w={180} state={errors['inputPhone'] ? 'invalid' : 'normal'}>
<InputMask.Value
ref={inputMaskRef}
value={value}
onChange={updateValue}
mask={valueMask.replace(/_/g, '9')}
/>
{value !== valueMask && (
<Input.Addon>
<CloseXS
interactive
onClick={() => {
updateValue(valueMask);
}}
/>
</Input.Addon>
)}
</InputMask>
}
control={control}
rules={{ required: true, validate: (value) => !/_/i.test(value) }}
name="inputPhone"
defaultValue={null}
/>
</NeighborLocation>
</Tooltip>
<br />
<Tooltip
interaction={errors['inputTag'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="You need to feel this useless field"
>
<Controller
as={
<InputTags
my={4}
h={80}
w={390}
size="l"
state={errors['inputTag'] ? 'invalid' : 'normal'}
onAppend={handleAppendTags}
onRemove={handleRemoveTag}
>
{tags.map((tag, idx) => (
<Tooltip key={idx}>
<Tooltip.Trigger tag={InputTags.Tag} use="primary" theme="asphalt" editable>
<InputTags.Tag.Text>{tag}</InputTags.Tag.Text>
<InputTags.Tag.Close data-id={idx} onClick={handleCloseTag} />
</Tooltip.Trigger>
<Tooltip.Popper>tag</Tooltip.Popper>
</Tooltip>
))}
<InputTags.Value value={valueTag} onChange={updateValueTag} />
</InputTags>
}
control={control}
name="inputTag"
rules={{ required: true, validate: (value) => value?.length > 0 }}
defaultValue={tags?.length === 0 ? null : tags}
/>
</Tooltip>
<Flex direction="column" mb={4}>
<Text size={100}>Label</Text>
<Tooltip
interaction={errors['select'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="You need to choose something"
>
<Controller
as={
<Select
mr={4}
mt={1}
w={390}
value={valueSelect}
onChange={setValueSelect}
state={errors['select'] ? 'invalid' : 'normal'}
options={options}
placeholder="Select"
/>
}
control={control}
rules={{ required: true, validate: (value) => value !== '' }}
name="select"
defaultValue={null}
/>
</Tooltip>
</Flex>
<Tooltip
interaction={errors['radioButton'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="Please choose something from the list"
>
<Controller
as={
<RadioGroup
mb={4}
name="radio"
state={errors['radioButton'] ? 'invalid' : 'normal'}
value={valueRadio}
onChange={setValueRadio}
>
<Radio mr={2}>
<Radio.Value value="1" />
<Radio.Text>Option 1</Radio.Text>
</Radio>
<Radio mr={2} mt={2}>
<Radio.Value value="2" />
<Radio.Text>Option 2</Radio.Text>
</Radio>
</RadioGroup>
}
control={control}
name="radioButton"
rules={{ required: true }}
defaultValue={null}
/>
</Tooltip>
<br />
<Tooltip
interaction={errors['checkbox'] ? 'focus' : 'none'}
placement="right"
theme="warning"
title="Please check this field"
>
<Checkbox mb={4} mt={4} state={errors['checkbox'] ? 'invalid' : 'normal'}>
<Checkbox.Value
checked={checked}
name="checkbox"
ref={register({ required: true })}
onChange={setChecked}
/>
<Checkbox.Text>label</Checkbox.Text>
</Checkbox>
</Tooltip>
<br />
<Button type="submit">Submit</Button>
</Box>
</div>
);
}
Example #11
Source File: index.jsx From product-collector with MIT License | 4 votes |
export default function Filters() {
const { filter, setFilter, countries, setCountries } = useContext(
TrendContext
);
const { control, errors, setValue } = useForm();
const query = `
{
countries
}
`;
const requestData = useRequestData(query);
useEffect(() => {
if (requestData.countries) {
const values = ['Todos', ...requestData.countries];
setCountries(values);
}
}, [JSON.stringify(requestData)]);
useEffect(() => {
Object.entries(filter).map(([key, value]) => {
setValue(key, value);
});
}, [filter.toString()]);
const handleChange = ([event]) => {
const {
target: { name, value },
} = event;
const currentFilter = { [name]: value };
setFilter({ ...filter, ...currentFilter });
return value;
};
return (
<section className={styles.filters}>
<FormControl
className={styles.formControl}
error={Boolean(errors.country)}
>
<InputLabel>Por paÃs</InputLabel>
<Controller
as={
<Select>
{countries.map((item, index) => (
<MenuItem key={index} value={index}>
{item}
</MenuItem>
))}
</Select>
}
name='country'
rules={{ required: 'Valor requerido' }}
control={control}
defaultValue={0}
onChange={handleChange}
/>
<FormHelperText>
{errors.country && errors.country.message}
</FormHelperText>
</FormControl>
<FormControl className={styles.formControl} error={Boolean(errors.date)}>
<InputLabel>Por fecha</InputLabel>
<Controller
as={
<Select>
{dateFilters.map(({ label }, index) => (
<MenuItem key={index} value={index}>
{label}
</MenuItem>
))}
</Select>
}
name='date'
rules={{ required: 'Valor requerido' }}
control={control}
defaultValue={0}
onChange={handleChange}
/>
<FormHelperText>{errors.date && errors.date.message}</FormHelperText>{' '}
</FormControl>
</section>
);
}
Example #12
Source File: checkbox&radio.jsx From intergalactic with MIT License | 4 votes |
Demo = () => {
const [selected, updateSelected] = React.useState(false);
const [selectedValue, updateSelectedValue] = React.useState([]);
const [selectedFirst, updateSelectedFirst] = React.useState(0);
const defaultValues = {
export: 'all',
};
const { handleSubmit, control, reset, errors, setError } = useForm({
defaultValues,
});
const onSubmit = (data) => {
if (data.export === 'first') {
if (!selectedFirst) {
setError('export', { message: 'Require enter value' });
return;
} else {
data.export = 'first ' + selectedFirst;
}
}
if (data.export === 'selected') {
if (!selectedValue.length) {
setError('export', { message: 'Require chouse value' });
return;
} else {
data.export = 'selected [' + selectedValue.join(',') + ']';
}
}
reset(defaultValues);
updateSelected(false);
updateSelectedValue([]);
updateSelectedFirst(0);
alert(JSON.stringify(data));
};
const optionsFirst = [100, 500].map((value) => ({ value, children: value }));
const onChangeSelect = (value) => {
reset({ export: 'first' });
updateSelectedFirst(value);
};
const onChangCheckbox = (checked, e) => {
const { value } = e.target;
const tmpArray = checked ? [...selectedValue, value] : selectedValue.filter((v) => v !== value);
tmpArray.length && reset({ export: 'selected' });
updateSelectedValue(tmpArray);
};
const onSelectedRadio = () => {
updateSelected(!selected);
};
return (
<Flex tag="form" onSubmit={handleSubmit(onSubmit)} direction="column" alignItems="flex-start">
<Flex direction="column" mb={4}>
<Text size={200} tag="label" mb={4}>
Export data
</Text>
<Controller
render={({ value, ...props }) => (
<RadioGroup {...props} value={value} size="l">
<Radio mb={3}>
<Radio.Value value="all" />
<Radio.Text>All</Radio.Text>
</Radio>
<Radio mb={3}>
<Radio.Value value="selected" onChange={onSelectedRadio} />
<Radio.Text>Selected</Radio.Text>
{selected &&
[100, 500].map((v) => (
<Checkbox
size="l"
ml={2}
key={v}
state={value.includes('selected') && errors['export'] ? 'invalid' : 'normal'}
>
<Checkbox.Value value={v} onChange={onChangCheckbox} />
<Checkbox.Text children={v} />
</Checkbox>
))}
</Radio>
<Radio style={{ alignItems: 'center' }}>
<Radio.Value value="first" />
<Radio.Text>First</Radio.Text>
<Select
size="l"
ml={2}
state={value.includes('first') && errors['export'] ? 'invalid' : 'normal'}
tag={ButtonTrigger}
options={optionsFirst}
onChange={onChangeSelect}
/>
</Radio>
</RadioGroup>
)}
control={control}
name="export"
/>
</Flex>
<Button type="submit" use="primary" theme="info" size="l">
Excel
</Button>
</Flex>
);
}
Example #13
Source File: ReportForm.js From pandoa with GNU General Public License v3.0 | 4 votes |
function ReportForm({ reportCaseTrigger, positions }) {
const { control, handleSubmit, errors } = useForm();
const onSubmit = data => {
Alert.alert("Data submitted");
reportCaseTrigger(positions);
// Alert.alert("Form Data", JSON.stringify(data), positions.length);
};
return (
<View>
<Form>
<Text style={styles.hintText}>
On this page you can report if you have got an infection. Please enter
your details below
</Text>
<View style={styles.inputWrapper}>
<Item>
<Text>Picker</Text>
<Controller
as={e => {
console.log(e);
return (
<Picker
note
mode="dropdown"
style={{ width: 120 }}
selectedValue={"key3"}
onValueChange={() => {}}
>
<Picker.Item label="Wallet" value="key0" />
<Picker.Item label="ATM Card" value="key1" />
<Picker.Item label="Debit Card" value="key2" />
<Picker.Item label="Credit Card" value="key3" />
<Picker.Item label="Net Banking" value="key4" />
</Picker>
);
}}
control={control}
name="firstName"
onChange={args => args[0].nativeEvent.text}
onChange={e => {
return "key1";
// Place your logic here
return selected;
}}
rules={{ required: true }}
defaultValue=""
placeholder="Username"
/>
</Item>
{errors.firstName && <Text>This is required.</Text>}
<Item>
<Controller
as={Input}
control={control}
name="lastName"
onChange={args => args[0].nativeEvent.text}
defaultValue=""
placeholder="Password"
/>
</Item>
</View>
<Text style={styles.hintText}>
Enter a contact phone number. This can be yours or a doctors phone
number.
</Text>
<View style={styles.inputWrapper}>
<Item>
<Label>Contact phone number</Label>
<Controller
as={Input}
control={control}
name="contact_phone"
onChange={args => args[0].nativeEvent.text}
defaultValue=""
/>
</Item>
</View>
<Text style={styles.hintText}>Enter information for you contact.</Text>
<View style={styles.inputWrapper}>
<Item style={styles.input}>
<Label>Contact information</Label>
<Controller
as={Input}
control={control}
name="contact_information"
onChange={args => args[0].nativeEvent.text}
defaultValue=""
placeholder="Contact information"
/>
</Item>
</View>
</Form>
{/*
<Form>
<Item>
<Input placeholder="Username" />
</Item>
<Item last>
<Input placeholder="Password" />
</Item>
<Button primary onPress={reportButton}>
<Text>Submit data</Text>
</Button>
</Form>*/}
<View style={styles.submitWrapper}>
<Button primary onPress={handleSubmit(onSubmit)}>
<Text>Submit</Text>
</Button>
</View>
</View>
);
}
Example #14
Source File: react_hook_form.js From react-multi-date-picker with MIT License | 4 votes |
export default function Doc({ translate, language, otherProps }) {
const { control, handleSubmit } = useForm();
const [submittedDate, setSubmittedDate] = useState();
const onSubmit = ({ date }) => {
setSubmittedDate(date);
};
const example = {
title: "Example Of Using React Hook Form",
code: `import React, { useState } from "react";
import DatePicker from "react-multi-date-picker";
import { useForm, Controller } from "react-hook-form";
export default function Example() {
const { control, handleSubmit } = useForm();
const [submittedDate, setSubmittedDate] = useState();
const onSubmit = ({ date }) => {
setSubmittedDate(date);
};
return (
<>
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name="date"
rules={{ required: true }} //optional
render={({
field: { onChange, name, value },
fieldState: { invalid, isDirty }, //optional
formState: { errors }, //optional, but necessary if you want to show an error message
}) => (
<>
<DatePicker
value={value || ""}
onChange={(date) => {
onChange(date?.isValid ? date : "");
}}
format={language === "en" ? "MM/DD/YYYY" : "YYYY/MM/DD"}
${
language === "en"
? "/>"
: ` calendar="persian"
locale="fa"
calendarPosition="bottom-right"
/>`
}
{errors && errors[name] && errors[name].type === "required" && (
//if you want to show an error message
<span>your error message !</span>
)}
</>
)}
/>
<input type="submit" />
</form>
<p>${translate("Submitted Date: ")} {submittedDate?.format?.("${
language === "en" ? "MMMM D YYYY" : "D MMMM YYYY"
}")}</p>
</>
)
}`,
jsx: (
<>
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
control={control}
name="date"
rules={{ required: true }} //optional
render={({
field: { onChange, name, value },
fieldState: { invalid, isDirty }, // optional
formState: { errors }, //optional, but necessary if you want to show an error message
}) => (
<>
<DatePicker
//react hook form needs this
value={value || ""}
onChange={(date) => {
onChange(date?.isValid ? date : "");
}}
format={language === "en" ? "MM/DD/YYYY" : "YYYY/MM/DD"}
{...otherProps}
/>
{errors && errors[name] && errors[name].type === "required" && (
//if you want to show an error message
<span>your error message !</span>
)}
</>
)}
/>
<input type="submit" />
</form>
<p>
{translate("Submitted Date: ")}
{submittedDate?.format?.(
language === "en" ? "MMMM D YYYY" : "D MMMM YYYY"
)}
</p>
</>
),
};
return [example];
}
Example #15
Source File: Login.jsx From fluentui-starter with MIT License | 4 votes |
function LoginForm({ theme, styles }) {
const { isAuthenticated, principal, login, logout } = useAuthentication();
const {
handleSubmit,
control,
formState: { errors },
} = useForm();
const [error, setError] = React.useState();
const history = useHistory();
const location = useLocation();
const from = location.state?.from || { pathname: "/" };
function onSubmit(values) {
setError(null);
remoteAuthService(values)
.then((identity) => {
login(identity);
history.replace(from);
})
.catch(setError);
}
function getErrorMessage(name) {
return get(errors, name + ".message");
}
const classNames = getClassNames(styles, { theme });
return (
<Stack className={classNames.root}>
{isAuthenticated && (
<Stack tokens={{ childrenGap: "1em" }}>
<h3 className={classNames.title}>
{principal.username}, you are already signed in.
</h3>
<Stack horizontal tokens={{ childrenGap: "1em" }}>
<PrimaryButton
onClick={() => history.push("/")}
iconProps={{ iconName: "Home" }}
>
Go to Home
</PrimaryButton>
<DefaultButton onClick={logout} iconProps={{ iconName: "SignOut" }}>
Logout
</DefaultButton>
</Stack>
</Stack>
)}
{!isAuthenticated && (
<form onSubmit={handleSubmit(onSubmit)}>
<Stack horizontal horizontalAlign="end" verticalAlign="center">
<ThemeToggle as={DefaultButton} />
</Stack>
<h3 className={classNames.title}>Login</h3>
<Stack
tokens={{
childrenGap: "1em",
}}
>
<Controller
as={TextField}
control={control}
autoComplete="username"
autoFocus
minLength={3}
maxLength={32}
defaultValue=""
name="username"
rules={{
required: "Please enter your username",
minLength: {
value: 3,
message: "Please enter your username",
},
maxLength: { value: 32, message: "Username is too long" },
}}
render={({ field }) => (
<TextField
{...field}
label="Username"
errorMessage={getErrorMessage("username")}
/>
)}
/>
<Controller
name="password"
control={control}
defaultValue=""
minLength={4}
maxLength={64}
rules={{
required: "Please enter your password",
minLength: {
value: 4,
message: "Please enter your password",
},
maxLength: { value: 64, message: "Password is too long" },
}}
render={({ field }) => (
<TextField
{...field}
label="Password"
type="password"
autoComplete="current-password"
errorMessage={getErrorMessage("password")}
/>
)}
/>
<Stack
horizontal
horizontalAlign="end"
tokens={{ childrenGap: "1em" }}
>
<Link>Find my password</Link>
<PrimaryButton type="submit">Login</PrimaryButton>
</Stack>
<Stack>
<h3>Demo users</h3>
<ul>
<li>demo/demo</li>
<li>admin/admin</li>
</ul>
</Stack>
{error && (
<MessageBar
messageBarType={MessageBarType.error}
onDismiss={() => setError(null)}
>
{error}
</MessageBar>
)}
</Stack>
</form>
)}
</Stack>
);
}
Example #16
Source File: SelectField.js From plataforma-sabia with MIT License | 4 votes |
SelectField = ({
name,
form,
label,
help,
options,
defaultOptions,
validation,
creatable,
onCreate,
isMulti,
callback,
wrapperCss,
variant,
isHidden,
isLoading,
instanceId,
isAsync,
onChange,
...selectProps
}) => {
const { t } = useTranslation(['error']);
const [needsUpdate, setNeedsUpdate] = useState(true);
const [internalIsLoading, setInternalIsLoading] = useState(false);
const [selectOptions, setSelectOptions] = useState(options);
const { formState: { errors } = {}, control, watch, setValue, getValues } = form;
const errorObject = get(errors, name);
const hasError = typeof errorObject !== 'undefined';
let selectedValue = watch(name);
if (selectedValue) {
selectedValue = Array.isArray(selectedValue)
? selectedValue.map((value) => `${value}`)
: selectedValue;
selectedValue = Array.isArray(selectedValue) && !isMulti ? selectedValue[0] : selectedValue;
selectedValue =
!Array.isArray(selectedValue) && typeof selectedValue !== 'object'
? `${selectedValue}`
: selectedValue;
}
/**
* Compares each option's label with each other in order to sort them later.
*
* @param {object} firstOption The first option
* @param {object} secondOption The second option
* @returns {number}
*/
function compareOptions(firstOption, secondOption) {
const { label: firstLabel } = firstOption;
const { label: secondLabel } = secondOption;
return firstLabel.localeCompare(secondLabel);
}
// update the select options whenever options prop changes
useEffect(() => {
const useOptionsFrom = isAsync ? defaultOptions : options;
setSelectOptions(useOptionsFrom.sort(compareOptions));
}, [options, defaultOptions, isAsync]);
/**
* React-select expects value to be in { value: '', label: '' } shape so we run a useEffect
* to ensure it's in the right format. This allows this component to be intialized just with the value.
*/
useEffect(() => {
if (!needsUpdate) {
return;
}
if (
(!options || options.length === 0) &&
(!defaultOptions || defaultOptions.length === 0)
) {
return;
}
const useOptionsFrom = isAsync ? defaultOptions : options;
if (!selectedValue) {
setNeedsUpdate(false);
return;
}
if (isMulti) {
setValue(
name,
selectedValue.map((value) =>
useOptionsFrom.find((option) => `${option.value}` === `${value}`),
),
{ shouldDirty: true },
);
} else if (typeof selectedValue === 'object') {
setValue(
name,
useOptionsFrom.find((option) => `${option.value}` === `${selectedValue.value}`),
{ shouldDirty: true },
);
} else {
setValue(
name,
useOptionsFrom.find((option) => `${option.value}` === `${selectedValue}`),
{ shouldDirty: true },
);
}
setNeedsUpdate(false);
}, [selectedValue, options, defaultOptions, name, setValue, isMulti, isAsync, needsUpdate]);
/**
* Handles creating a new element in the select field.
*
* Only called if `creatable` is true.
*
* @param {string} inputValue The inserted input value.
*
*/
const onCreateOption = async (inputValue) => {
setInternalIsLoading(true);
const newOption = await onCreate(inputValue);
setInternalIsLoading(false);
setSelectOptions([...options, newOption]);
const currentValue = getValues(name) || [];
if (isMulti) {
setValue(name, [...currentValue, newOption], { shouldDirty: true });
} else {
setValue(name, newOption, { shouldDirty: true });
}
return newOption;
};
// eslint-disable-next-line no-nested-ternary
const Component = creatable ? StyledCreatable : isAsync ? StyledAsync : StyledSelect;
return (
<InputFieldWrapper hasError={hasError} customCss={wrapperCss} isHidden={isHidden}>
{label && (
<InputLabel htmlFor={name}>
{label}
{validation.required && <RequiredIndicator />}
</InputLabel>
)}
<Row>
<Controller
control={control}
rules={validation}
name={name}
render={({ field }) => (
<Component
id={name}
className="react-select-container"
classNamePrefix="react-select"
aria-label={label}
aria-required={validation.required}
options={selectOptions}
defaultOptions={selectOptions}
isMulti={isMulti}
onCreateOption={creatable ? onCreateOption : null}
isDisabled={internalIsLoading || isLoading || isHidden}
isLoading={internalIsLoading || isLoading}
styles={reactSelectStyles[variant]}
instanceId={instanceId}
{...selectProps}
{...field}
onChange={(selectedValues) => {
if (typeof callback === 'function') callback(selectedValues);
if (typeof onChange === 'function')
return field.onChange(onChange(selectedValues));
return field.onChange(selectedValues);
}}
/>
)}
/>
{help && <Help id={name} label={label} HelpComponent={help} />}
</Row>
{creatable && (
<Hint>
É possÃvel adicionar novas opções neste campo. Basta digitar a opção e
pressionar a tecla Enter.
</Hint>
)}
{hasError && Object.keys(errors).length ? (
<InputError>{validationErrorMessage(errors, name, t)}</InputError>
) : null}
</InputFieldWrapper>
);
}
Example #17
Source File: GrantModal.js From akashlytics-deploy with GNU General Public License v3.0 | 4 votes |
GrantModal = ({ address, onClose }) => {
const formRef = useRef();
const [error, setError] = useState("");
const classes = useStyles();
const { sendTransaction } = useTransactionModal();
const {
handleSubmit,
control,
formState: { errors },
watch,
clearErrors
} = useForm({
defaultValues: {
amount: "",
expiration: format(addYears(new Date(), 1), "yyyy-MM-dd'T'HH:mm"),
useDepositor: false,
granteeAddress: ""
}
});
const { amount, granteeAddress, expiration } = watch();
const onDepositClick = (event) => {
event.preventDefault();
formRef.current.dispatchEvent(new Event("submit", { cancelable: true, bubbles: true }));
};
const onSubmit = async ({ amount }) => {
setError("");
clearErrors();
const spendLimit = aktToUakt(amount);
const expirationDate = new Date(expiration);
const message = TransactionMessageData.getGrantMsg(address, granteeAddress, spendLimit, expirationDate);
const response = await sendTransaction([message]);
if (response) {
await analytics.event("deploy", "authorize spend");
onClose();
}
};
function handleDocClick(ev, url) {
ev.preventDefault();
window.electron.openUrl(url);
}
return (
<Dialog maxWidth="xs" aria-labelledby="deposit-dialog-title" open={true} onClose={onClose}>
<DialogTitle id="deposit-dialog-title">Authorize Spending</DialogTitle>
<DialogContent dividers className={classes.dialogContent}>
<form onSubmit={handleSubmit(onSubmit)} ref={formRef}>
<Alert severity="info">
<Typography variant="caption">
<LinkTo onClick={(ev) => handleDocClick(ev, "https://docs.akash.network/testnet-technical-docs/authorized-spend")}>Authorized Spend</LinkTo>{" "}
allows users to authorize spend of a set number of tokens from a source wallet to a destination, funded wallet. The authorized spend is restricted
to Akash deployment activities and the recipient of the tokens would not have access to those tokens for other operations.
</Typography>
</Alert>
<FormControl error={!errors.amount} className={classes.formControl} fullWidth>
<Controller
control={control}
name="amount"
rules={{
required: true
}}
render={({ fieldState, field }) => {
const helperText = fieldState.error?.type === "validate" ? "Invalid amount." : "Amount is required.";
return (
<TextField
{...field}
type="number"
variant="outlined"
label="Spending Limit"
autoFocus
error={!!fieldState.invalid}
helperText={fieldState.invalid && helperText}
className={classes.formValue}
inputProps={{ min: 0, step: 0.000001 }}
InputProps={{
startAdornment: <InputAdornment position="start">AKT</InputAdornment>
}}
/>
);
}}
/>
</FormControl>
<FormControl className={classes.formControl} fullWidth>
<Controller
control={control}
name="granteeAddress"
defaultValue=""
rules={{
required: true
}}
render={({ fieldState, field }) => {
return (
<TextField
{...field}
type="text"
variant="outlined"
label="Grantee Address"
error={!!fieldState.invalid}
helperText={fieldState.invalid && "Grantee address is required."}
className={classes.formValue}
/>
);
}}
/>
</FormControl>
<FormControl className={classes.formControl} fullWidth>
<Controller
control={control}
name="expiration"
rules={{
required: true
}}
render={({ fieldState, field }) => {
return (
<TextField
{...field}
type="datetime-local"
variant="outlined"
label="Expiration"
error={!!fieldState.invalid}
helperText={fieldState.invalid && "Expiration is required."}
className={classes.formValue}
/>
);
}}
/>
</FormControl>
{!!amount && granteeAddress && (
<Box marginTop={1} textAlign={"left"}>
This address will be able to spend up to {amount}AKT on your behalf.
</Box>
)}
{error && (
<Alert severity="warning" className={classes.alert}>
{error}
</Alert>
)}
</form>
</DialogContent>
<DialogActions className={classes.dialogActions}>
<Button autoFocus onClick={onClose}>
Cancel
</Button>
<Button onClick={onDepositClick} disabled={!amount} variant="contained" color="primary">
Grant
</Button>
</DialogActions>
</Dialog>
);
}
Example #18
Source File: BadgeForm.js From carbon-badges with Apache License 2.0 | 4 votes |
BadgeForm = () => {
const [emails, setEmails] = useState([]);
const [steps, setSteps] = useState([]);
const [stepsLoading, setStepsLoading] = useState(false);
const [submitLoading, setSubmitLoading] = useState(false);
const [acceptUrl, setAcceptUrl] = useState("");
const { token } = useAuth();
const {
handleSubmit,
watch,
errors,
control,
formState,
setError,
clearErrors,
register,
reset,
} = useForm({
mode: "onChange",
});
const selectedTutorial = watch("badge", {});
useEffect(() => {
if (!token) return;
fetch(`/api/github/user-emails?access_token=${token}`)
.then((response) => response.json())
.then((data) => {
setEmails(data || []);
});
}, [token]);
useEffect(() => {
if (!selectedTutorial.id) {
return;
}
const preSetSteps = (prs) => {
// filter PRs by "step x" title and sort by step then status (approved
// first, then needs correction, then not reviewed)
const items = cleanPRs(prs)
.filter((item) => item.step)
.sort((a, b) => {
if (a.step < b.step) return -1;
if (a.step > b.step) return 1;
if (a.status < b.status) return -1;
if (a.status > b.status) return 1;
return 0;
});
// grab the first PR for each step and backfill missing steps
const uniqueItems = [];
for (let i = 1; i <= 5; i++) {
const foundItem = items.find((item) => item.step.includes(i));
if (foundItem) {
uniqueItems.push(foundItem);
} else {
uniqueItems.push({
status: "not-found",
step: "Step " + i,
});
}
}
const hasError = uniqueItems.reduce((error, item) => {
return error ? true : item.status !== "approved";
}, false);
if (hasError) {
setError("badge", {
type: "manual",
message: "A pull request for each step 1 - 5 must be approved.",
});
} else {
clearErrors("badge");
}
setSteps(uniqueItems);
};
setSteps([]);
setStepsLoading(true);
fetch(
`/api/github/pull-requests?access_token=${token}&tutorial=${selectedTutorial.id}`
)
.then((response) => response.json())
.then((data) => {
preSetSteps(data.items || []);
setStepsLoading(false);
});
}, [clearErrors, selectedTutorial, setError, token]);
const onSubmit = (values) => {
setSubmitLoading(true);
setAcceptUrl("");
fetch(`/api/github/badge-issue?access_token=${token}`, {
method: "POST",
headers: {
"Content-type": "application/json",
},
body: JSON.stringify(values),
})
.then((response) => response.json())
.then((data) => {
console.log(data);
setSubmitLoading(false);
const acclaimError = getAcclaimError(data.data);
if (data.error) {
setError("email", {
type: "submit",
message: data.error,
});
} else if (acclaimError) {
setError("email", {
type: "submit",
message: acclaimError,
});
} else if (data.data && data.data["accept_badge_url"]) {
reset({
badge: "",
email: "",
});
setSteps([]);
setAcceptUrl(data.data["accept_badge_url"]);
}
});
};
if (!token) return null;
return (
<>
<Row>
<Column colLg={8}>
<H2>Badge application</H2>
</Column>
</Row>
<Row>
<Column colLg={8}>
{emails.length === 0 ? (
<SkeletonText paragraph={true} width="320px" />
) : (
<form method="post" onSubmit={handleSubmit(onSubmit)}>
<div>
<Controller
control={control}
name="badge"
rules={{ required: true }}
render={({ onChange, value }) => (
<Dropdown
id="badge"
invalid={!!errors.badge && !stepsLoading}
selectedItem={value}
onChange={(item) => onChange(item.selectedItem)}
invalidText={
(errors.badge && errors.badge.message) ||
"A value is required."
}
ariaLabel="Badge dropdown"
titleText="Carbon tutorial"
label="Choose a badge"
items={Object.keys(badgeConfig.badges).map((name) => {
return {
id: name,
text: badgeConfig.badges[name].label,
};
})}
itemToString={(item) => (item ? item.text : "")}
light={true}
/>
)}
/>
</div>
<div className={style.field}>
{stepsLoading && (
<InlineLoading
description="Searching GitHub..."
iconDescription="Searching GitHub"
status="active"
/>
)}
{steps.map((step, i) => (
<InlineNotification
key={i}
hideCloseButton={true}
kind={
step.status === "approved"
? "success"
: step.status === "correction"
? "error"
: "warning"
}
lowContrast={true}
title={
step.step.charAt(0).toUpperCase() + step.step.slice(1)
}
subtitle={
<span>
{step.number && (
<>
<a href={step.url} rel="noreferrer" target="_blank">
PR #{step.number}
</a>{" "}
</>
)}
{step.status === "approved"
? "approved."
: step.status === "correction"
? "needs correction."
: step.status === "not-reviewed"
? "not reviewed."
: "not found."}
</span>
}
></InlineNotification>
))}
</div>
<div className={style.field}>
<Controller
control={control}
name="email"
rules={{ required: true }}
render={({ onChange, value }) => (
<Dropdown
id="email"
invalid={!!errors.email}
selectedItem={value}
onChange={(item) => onChange(item.selectedItem)}
invalidText={
(errors.email && errors.email.message) ||
"A value is required."
}
ariaLabel="Email dropdown"
titleText="Email address"
label="Choose an email address"
helperText="Don't see your work email address? Verify it in GitHub email settings to use here."
items={emails
.filter((email) => email.verified)
.map((email) => email.email)}
light={true}
/>
)}
/>
</div>
{Object.keys(badgeConfig.questions).map((question) => (
<div className={style.field}>
<TextArea
id={question}
name={question}
invalid={!!errors[question]}
invalidText="A value is required."
labelText={`${badgeConfig.questions[question]} (Optional)`}
rows={3}
light={true}
ref={register}
/>
</div>
))}
{formState.isSubmitted && errors.email && (
<div className={style.field}>
<InlineNotification
hideCloseButton={true}
kind="error"
lowContrast={true}
title="Error"
subtitle={errors.email.message}
/>
</div>
)}
{acceptUrl && (
<div className={style.field}>
<InlineNotification
actions={
<NotificationActionButton
onClick={() => (window.location.href = acceptUrl)}
>
Accept badge
</NotificationActionButton>
}
kind="success"
lowContrast={true}
title="Success"
subtitle="Your badge has been issued. You'll receive an email to accept the badge."
/>
</div>
)}
<div className={style.actions}>
<Button
disabled={!formState.isValid || submitLoading}
size="field"
type="submit"
>
Apply for badge
</Button>
{submitLoading && (
<InlineLoading
description="Applying..."
iconDescription="Applying"
status="active"
/>
)}
</div>
</form>
)}
</Column>
</Row>
</>
);
}
Example #19
Source File: ProfileForm.js From AdaptivApps-fe with MIT License | 4 votes |
ProfileForm = ({ loading, profile, user, updateProfile }) => {
const [updated, setUpdated] = useState(false);
const [userProfile, setUserProfile] = useState(null);
const classes = useStyles();
const { refetch: refetchProfile } = useQuery(GET_USER_PROFILE, { variables: { email: user.email } });
const { handleSubmit, register, setValue, control } = useForm({
mode: "onSubmit",
validationSchema: ProfileSchema,
defaultValues: {
email: user && user.email,
firstName: userProfile && userProfile.firstName,
lastName: userProfile && userProfile.lastName,
displayName: userProfile && userProfile.displayName,
birthday: userProfile && userProfile.birthday,
bio: userProfile && userProfile.bio,
disability: userProfile && userProfile.disability,
},
});
// updates profile in the backend and frontend
const onSubmit = (formValues, e) => {
e.preventDefault();
// backend update
updateProfile({
variables: {
email: user.email,
firstName:
formValues.firstName === ""
? userProfile.firstName
: formValues.firstName,
lastName:
formValues.lastName === ""
? userProfile.lastName
: formValues.lastName,
displayName:
formValues.displayName === ""
? userProfile.displayName
: formValues.displayName,
birthday:
formValues.birthday === ""
? userProfile.birthday
: formValues.birthday,
bio: formValues.bio === "" ? userProfile.bio : formValues.bio,
disability:
formValues.disability === ""
? userProfile.disability
: formValues.disability,
legal: formValues.legal === "" ? userProfile.legal : formValues.legal,
},
});
// frontend update
setUserProfile({
email: user.email,
firstName:
formValues.firstName === ""
? userProfile.firstName
: formValues.firstName,
lastName:
formValues.lastName === "" ? userProfile.lastName : formValues.lastName,
displayName:
formValues.displayName === ""
? userProfile.displayName
: formValues.displayName,
birthday:
formValues.birthday === "" ? userProfile.birthday : formValues.birthday,
bio: formValues.bio === "" ? userProfile.bio : formValues.bio,
disability:
formValues.disability === ""
? userProfile.disability
: formValues.disability,
legal: formValues.legal === "" ? userProfile.legal : formValues.legal,
});
refetchProfile();
};
// updates form fields with new values
useEffect(() => {
if (!loading && !userProfile) setUserProfile(profile);
if (!loading && userProfile) {
setValue([
{ firstName: userProfile && userProfile.firstName },
{ lastName: userProfile && userProfile.lastName },
{ displayName: userProfile && userProfile.displayName },
{ birthday: userProfile && userProfile.birthday },
{ bio: userProfile && userProfile.bio },
{ disability: userProfile && userProfile.disability },
{ legal: userProfile && userProfile.legal },
]);
}
}, [loading, userProfile, setValue, profile]);
// alerts user to successful update, handy for screen readers
const handleUpdated = () => {
refetchProfile();
alert("Profile updated successfully!");
setUpdated(false);
};
const userPicture = user && user.picture;
return (
<main className={classes.root}>
<Box className={classes.headingBox} borderBottom={2}>
<Typography variant="h1" gutterBottom>
Account Information
</Typography>
</Box>
<Container className={classes.profileContainer}>
<Box className={classes.profileInfo}>
<img className={classes.profileImg} src={userPicture} alt="Profile" />
<Box className={classes.profileText}>
<Typography>
{userProfile && userProfile.firstName !== null
? `${userProfile && userProfile.firstName} ${userProfile &&
userProfile.lastName}`
: user && user.name}{" "}
</Typography>
<Typography>{user && user.email}</Typography>
</Box>
</Box>
<Typography className={classes.personalInfo} variant="h2" gutterBottom>
Personal Information
</Typography>
<form className={classes.form} onSubmit={handleSubmit(onSubmit)}>
<Box component="div" className={classes.formBox}>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="firstName">
First Name
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="firstName"
variant="outlined"
type="text"
placeholder={userProfile ? userProfile.firstName : ""}
name="firstName"
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="lastName">
Last Name
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="lastName"
type="text"
variant="outlined"
placeholder={userProfile ? userProfile.lastName : ""}
name="lastName"
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
</Box>
<Box className={classes.formBox}>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="displayName">
Display Name
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="displayName"
type="text"
variant="outlined"
placeholder={userProfile ? userProfile.displayName : ""}
name="displayName"
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="birthday">
Date of Birth
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="birthday"
type="text"
variant="outlined"
name="birthday"
placeholder={userProfile ? userProfile.birthday : "mm/dd/yyyy"}
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
</Box>
<Box className={classes.formBox}>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="bio">
Bio
</InputLabel>
<Controller
as={<TextField />}
className={classes.bio}
id="bio"
name="bio"
variant="outlined"
multiline={true}
rows="8"
placeholder={userProfile ? userProfile.bio : null}
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
</Box>
<Box className={classes.formBox}>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="disability">
Disability Status
</InputLabel>
<Controller
as={<TextField />}
className={classes.input}
id="disability"
type="select"
variant="outlined"
name="disability"
ref={register}
placeholder={userProfile ? userProfile.disability : null}
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
<Box className={classes.box}>
<InputLabel className={classes.inputLabel} htmlFor="legal">
Are you over 18 years old?
</InputLabel>
<Controller
as={
<Select value={userProfile?.legal}>
<MenuItem value="">
{userProfile ? userProfile.legal : ""}
</MenuItem>
<MenuItem value={`Adult`}>Yes</MenuItem>
<MenuItem value={`Minor`}>No</MenuItem>
</Select>
}
className={classes.input}
id="legal"
name="legal"
variant="outlined"
control={control}
inputProps={{
classes: {
input: classes.resize,
},
}}
/>
</Box>
</Box>
<Box className={classes.formBox}>
<Button
className={classes.button}
variant="outlined"
color="primary"
type="submit"
aria-label="save changes to user profile"
onClick={() => {
setUpdated(true);
}}
>
Save
</Button>
{updated === true ? handleUpdated() : null}
</Box>
</form>
</Container>
</main>
);
}
Example #20
Source File: NewRequestPage.js From app with MIT License | 4 votes |
function NewRequestPage() {
const classes = useStyles();
const location = useLocation();
const qs = queryString.parse(location.search);
const defaultValues = {
needs: {},
immediacy: '1',
needFinancialAssistance: 'false',
};
// Append needs from query string type
if (qs && qs.type) {
defaultValues.needs = { [qs.type]: true };
}
const {
register,
handleSubmit,
errors,
watch,
control,
formState: { isValid, isSubmitting, dirty },
} = useForm({
validationSchema: requestValidationSchema,
defaultValues,
});
const {
submitRequest,
handleLocationChange,
requestLocation,
requestLocationLoading,
} = useNewRequestPage();
const currentNeeds = watch('needs');
const groceryPickup = currentNeeds && currentNeeds['grocery-pickup'];
return (
<Container maxWidth="md">
<Helmet>
<title>Request Assistance</title>
</Helmet>
<Typography variant="h5" color="textPrimary" gutterBottom>
Request Help
</Typography>
<Paper className={classes.paper} data-test="request-form">
<div className={classes.heroContent}>
<Container maxWidth="md">
<form onSubmit={handleSubmit(submitRequest)}>
<Container>
<FormGroup>
<Typography
variant="h5"
gutterBottom
className={classes.otherComments}>
What do you need help with?
</Typography>
{Object.keys(activeCategoryMap).map((optionKey) => (
<FormControlLabel
key={optionKey}
control={
<Checkbox
inputRef={register}
name={`needs.${optionKey}`}
data-test={`need-${optionKey}`}
defaultChecked={defaultValues.needs[optionKey]}
/>
}
label={
activeCategoryMap[optionKey].inputCaption
? activeCategoryMap[optionKey].inputCaption
: activeCategoryMap[optionKey].description
}
/>
))}
</FormGroup>
{!!errors.needs && (
<FormHelperText error>{errors.needs.message}</FormHelperText>
)}
<Typography
variant="h5"
className={classes.otherComments}
gutterBottom={!groceryPickup}>
Details
</Typography>
<Zoom in={groceryPickup} unmountOnExit>
<Typography variant="subtitle1" gutterBottom>
For grocery pickup, please provide the list of groceries
that you would like the volunteer to get. Please be as
specific as possible.
</Typography>
</Zoom>
<Grid container spacing={3}>
<Grid item xs={12}>
<TextField
name="otherDetails"
data-test="otherDetails"
multiline
placeholder="Please be as specific as possible."
fullWidth
rows="4"
variant="outlined"
inputRef={register}
/>
</Grid>
</Grid>
{/* <Zoom in={hasFinancialComponent} unmountOnExit> */}
<div>
<Divider className={classes.optionalDivider} />
<Typography variant="h5" gutterBottom>
Will you be able to pay for your items?
</Typography>
<Typography variant="body1" gutterBottom>
This service is free, but the items still cost money. Are
you able to pay for your items? If not, we will do our best
to match you with organizations and volunteers who can also
provide financial assistance.
</Typography>
<Controller
as={
<RadioGroup
aria-label="Need Financial Assistance"
component="fieldset">
<FormControlLabel
value="false"
control={<Radio />}
label="Yes, I can pay and only need help with the delivery."
/>
<FormControlLabel
value="true"
control={<Radio />}
label="No, I need help paying for the items."
/>
</RadioGroup>
}
control={control}
onChange={([event]) => event.target.value}
name="needFinancialAssistance"
/>
{!!errors.needFinancialAssistance && (
<FormHelperText error>
{errors.needFinancialAssistance}
</FormHelperText>
)}
</div>
{/* </Zoom> */}
<Divider className={classes.optionalDivider} />
<Typography variant="h5" gutterBottom>
Immediacy of Need
</Typography>
<Typography variant="body1" gutterBottom>
Please let us know how urgently you need us to fulfill the
request. We will do our best to connect you with a volunteer
as soon as possible, however, we cannot guarantee anything
because we are dependent on volunteer availability.
</Typography>
<Controller
as={
<RadioGroup>
<FormControlLabel
value="1"
control={<Radio />}
label="Low"
/>
<FormControlLabel
value="5"
control={<Radio />}
label="Medium - Not very urgent"
/>
<FormControlLabel
value="10"
control={<Radio />}
label="High - Urgent"
/>
</RadioGroup>
}
control={control}
name="immediacy"
/>
{!!errors.immediacy && (
<FormHelperText error>
{errors.immediacy.message}
</FormHelperText>
)}
<Divider className={classes.optionalDivider} />
<Typography variant="h5" gutterBottom>
Your Location
</Typography>
<Typography className={classes.intro}>
A rough location is needed to allow us to efficiently and
quickly find a match for your need. You can do this in three
ways: by entering your address in the address field, by
clicking the "Detect Location" button, or by
clicking on the map. If you decide to enter the address, we
will not save the actual address and instead use it to get the
location.
</Typography>
<Grid container spacing={3}>
<Grid item xs={12}>
<Card>
{requestLocationLoading ? (
<LoadingSpinner />
) : (
<ClickableMap
locationInfo={requestLocation}
onLocationChange={handleLocationChange}
/>
)}
</Card>
</Grid>
</Grid>
<Divider className={classes.optionalDivider} />
<Typography variant="h5" gutterBottom>
Contact Information
</Typography>
<Typography gutterBottom>
To minimize exposing your contact information, we do not
display it unless a volunteer specifically requests to see it.
To further discourage any abuse, we do not display your last
name and also keep track of all the volunteers who have looked
up your contact information.
</Typography>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
name="firstName"
data-test="firstName"
type="text"
label="First Name"
variant="outlined"
inputRef={register}
error={!!errors.firstName}
fullWidth
helperText={errors?.firstName?.message}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
name="lastName"
data-test="lastName"
type="text"
label="Last Name"
variant="outlined"
fullWidth
inputRef={register}
error={!!errors.lastName}
helperText={errors?.firstName?.message}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
name="phone"
data-test="phone"
type="text"
label="Phone Number"
variant="outlined"
fullWidth
inputRef={register}
error={!!errors.phone}
helperText={errors?.phone?.message}
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
name="email"
type="text"
data-test="email"
label="Email"
variant="outlined"
fullWidth
inputRef={register}
error={!!errors.email}
helperText={errors?.email?.message}
/>
</Grid>
</Grid>
<Typography className={classes.warrantyInfo}>
Note: This website and all related work products are provided
"AS IS". The provider of this service makes no other
warranties, express or implied, and hereby disclaims all
implied warranties, including any warranty of merchantability
and warranty of fitness for a particular purpose.
</Typography>
{dirty && !!Object.keys(errors).length && !isValid && (
<Typography variant="body2" className={classes.errorText}>
Please fix the errors above.
</Typography>
)}
<div className={classes.buttons}>
<Button
type="submit"
variant="contained"
color="primary"
data-test="submit-request"
disabled={isSubmitting}>
Submit Request
</Button>
</div>
</Container>
</form>
</Container>
</div>
</Paper>
</Container>
);
}
Example #21
Source File: NewNeedDialog.js From e-Pola with MIT License | 4 votes |
function NewNeedDialog({ onSubmit, open, onRequestClose }) {
const classes = useStyles()
const [category, setCategory] = React.useState('')
const [product, setProduct] = React.useState('')
const {
control,
register,
handleSubmit,
formState: { isSubmitting, isValid }
} = useForm({ mode: 'onChange' })
useFirestoreConnect({
collection: 'products',
where: ['category', '==', category]
})
const products = useSelector(({ firestore: { ordered } }) => ordered.products)
const handleChange = (event) => {
setCategory(event.target.value)
setProduct('')
}
const handleChangeProduct = ([event]) => {
const selectedProduct = products.find(
(product) => product.id === event.target.value
)
setProduct(selectedProduct)
return event.target.value
}
const handleChangeUnit = ([event]) => {
return event.target.value
}
return (
<Dialog open={open} onClose={onRequestClose}>
<DialogTitle id="new-need-dialog-title" color="secondary">
<Trans>What do you want?</Trans>
</DialogTitle>
<form className={classes.root} onSubmit={handleSubmit(onSubmit)}>
<DialogContent>
<FormControl className={classes.selection}>
<InputLabel id="catagories">
<Trans>Category</Trans>
</InputLabel>
<Select
labelId="catagories"
id="catagories-list"
value={category}
onChange={handleChange}
inputRef={register({
required: true
})}
name="category"
defaultValue="">
<MenuItem value="dairy">
<Trans>Dairy</Trans>{' '}
<span
className={classes.emojis}
role="img"
alt="Dairy"
aria-label="emoji">
??
</span>
</MenuItem>
<MenuItem value="meat">
<Trans>Meat, Seafood & Poultry</Trans>{' '}
<span
className={classes.emojis}
role="img"
aria-label="emoji"
alt="Meat, Seafood & Poultry">
???
</span>
</MenuItem>
<MenuItem value="vegetables">
<Trans>Vegetables</Trans>{' '}
<span
className={classes.emojis}
role="img"
alt="Vegetables"
aria-label="emoji">
???
</span>
</MenuItem>
<MenuItem value="grains">
<Trans>Grains</Trans>{' '}
<span
className={classes.emojis}
role="img"
alt="Grains"
aria-label="emoji">
??
</span>
</MenuItem>
<MenuItem value="grocery">
<Trans>Grocery Items</Trans>{' '}
<span
className={classes.emojis}
role="img"
alt="Grocery Items"
aria-label="emoji">
?
</span>
</MenuItem>
<MenuItem value="pharmaceuticals">
<Trans>Pharmacy Items</Trans>{' '}
<span
className={classes.emojis}
role="img"
alt="Grocery Items"
aria-label="emoji">
?
</span>
</MenuItem>
</Select>
</FormControl>
<br />
<br />
<FormControl className={classes.selection}>
<InputLabel id="product">
<Trans>Products</Trans>
</InputLabel>
<Controller
as={
<Select
disabled={isEmpty(products)}
labelId="product"
name="products_id">
{!isEmpty(products) &&
products.map((product) => (
<MenuItem value={product.id} key={product.id}>
{product.name}
</MenuItem>
))}
</Select>
}
name="products_id"
onChange={handleChangeProduct}
rules={{ required: 'Product is required' }}
control={control}
defaultValue=""
/>
</FormControl>
<br />
<br />
<FormControl className={classes.selection}>
<InputLabel id="amount">
<Trans>How much?</Trans>
</InputLabel>
<Controller
as={
<Select disabled={!product} labelId="amount" name="amount">
{!!product &&
product.units.map((unit, i) => (
<MenuItem value={unit} key={i}>
{unit}
</MenuItem>
))}
</Select>
}
name="amount"
onChange={handleChangeUnit}
rules={{ required: 'How much is required' }}
control={control}
defaultValue=""
/>
</FormControl>
<TextField
type="hidden"
name="name"
value={product && product.name}
inputRef={register()}
/>
</DialogContent>
<DialogActions>
<Button onClick={onRequestClose} color="secondary">
<Trans>Cancel</Trans>
</Button>
<Button
type="submit"
color="primary"
disabled={isSubmitting || !isValid}>
{isSubmitting ? (
<Trans>Requesting...</Trans>
) : (
<Trans>Request</Trans>
)}
</Button>
</DialogActions>
</form>
</Dialog>
)
}
Example #22
Source File: index.jsx From react-firebase-admin with MIT License | 4 votes |
UserForm = ({ isEditing, isProfile, user, onSubmitHandler, schema }) => {
const { loading, success } = useSelector(
(state) => ({
loading: state.users.loading,
success: state.users.success,
}),
shallowEqual
);
const dispatch = useDispatch();
const { register, handleSubmit, errors, control, watch, setValue } = useForm({
defaultValues: { ...user },
resolver: yupResolver(schema),
});
useEffect(() => {
if (success) {
setValue('file', null);
}
return () => dispatch(usersCleanUp());
}, [dispatch, success, setValue]);
const invalidEmailMessage = useFormatMessage('UserForm.invalidEmail');
const imagePreviewUrl =
watch('file') && watch('file')[0]
? URL.createObjectURL(watch('file')[0])
: user.logoUrl;
const goBackMessage = useFormatMessage('UserForm.goBack');
const pickAnotherFileMessage = useFormatMessage('UserForm.pickAnotherFile');
const pickFileMessage = useFormatMessage('UserForm.pickFile');
const emailMessage = useFormatMessage('UserForm.email');
const adminMessage = useFormatMessage('UserForm.admin');
return (
<>
<div className="tile is-ancestor">
<div className="tile is-parent">
<div className="card tile is-child">
<header className="card-header">
<p className="card-header-title">
<span className="icon">
<i className="mdi mdi-account-edit default" />
</span>
{useFormatMessage('UserForm.userInfo')}
</p>
</header>
<div className="card-content">
<form onSubmit={handleSubmit(onSubmitHandler)}>
{isEditing ? (
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">{emailMessage}</label>
</div>
<div className="field-body">
<div className="field">
<div className="control">
<input
type="text"
readOnly="readOnly"
className="input is-static"
name="email"
ref={register}
/>
</div>
</div>
</div>
</div>
) : (
<>
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">{emailMessage}</label>
</div>
<div className="field-body">
<div className="field">
<div className="control">
<input
className={classNames(`input`, {
'is-danger': errors.email,
})}
ref={register}
name="email"
/>
</div>
</div>
</div>
</div>
{errors.email && (
<div className="field is-horizontal">
<div className="field-label is-normal" />
<div className="field-body">
<ErrorMessage text={invalidEmailMessage} />
</div>
</div>
)}
</>
)}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">
{useFormatMessage('UserForm.name')}
</label>
</div>
<div className="field-body">
<div className="field">
<div className="control">
<input
name="name"
id="name"
className={classNames('input', {
'is-danger': errors.name,
})}
ref={register}
type="text"
/>
</div>
</div>
</div>
</div>
{errors.name && (
<div className="field is-horizontal">
<div className="field-label is-normal" />
<div className="field-body">
<ErrorMessage />
</div>
</div>
)}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">
{useFormatMessage('UserForm.location')}
</label>
</div>
<div className="field-body">
<div className="field">
<div className="control">
<input
className="input"
type="text"
ref={register}
name="location"
/>
</div>
</div>
</div>
</div>
{!isProfile && (
<div className="field has-check is-horizontal">
<div className="field-label">
<label className="label">{adminMessage}</label>
</div>
<div className="field-body">
<div className="field">
<div className="field">
<div className="control">
<label className="b-checkbox checkbox">
<input
type="checkbox"
name="isAdmin"
ref={register}
/>
<span className="check is-primary" />
</label>
</div>
</div>
</div>
</div>
</div>
)}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">
{useFormatMessage('UserForm.created')}
</label>
</div>
<div className="field-body">
<div className="field">
<Controller
control={control}
name="createdAt"
render={({ onChange, name, value }) => (
<DatePicker
name={name}
onChange={onChange}
date={new Date(value)}
/>
)}
/>
</div>
</div>
</div>
<hr />
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">
{useFormatMessage('UserForm.logo')}
</label>
</div>
<div className="field-body">
<div className="field">
<div className="file has-name">
<label className="file-label">
<input
className="file-input"
type="file"
name="file"
ref={register}
accept="image/*"
/>
<span className="file-cta">
<span className="file-icon">
<i className="mdi mdi-upload" />
</span>
<span className="file-label">
{watch('file') && watch('file').file
? pickAnotherFileMessage
: pickFileMessage}
</span>
</span>
<span className="file-name">
{watch('file') && watch('file')[0]?.name}
</span>
</label>
</div>
</div>
</div>
</div>
<hr />
<div className="field is-horizontal">
<div className="field-label" />
<div className="field-body">
<div className="field">
<div className="field is-grouped">
<div className="control">
<button
type="submit"
className={`button is-primary ${
loading && 'is-loading'
}`}
>
<span>{useFormatMessage('UserForm.submit')}</span>
</button>
</div>
{!isProfile && (
<Link to={paths.USERS} className="button">
{goBackMessage}
</Link>
)}
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<div className="tile is-parent preview">
<div className="card tile is-child">
<header className="card-header">
<p className="card-header-title">
<span className="icon">
<i className="mdi mdi-account default" />
</span>
{useFormatMessage('UserForm.userPreview')}
</p>
</header>
<div className="card-content">
{imagePreviewUrl && (
<>
<div className="is-user-avatar image has-max-width is-aligned-center">
<img
className="user-avatar"
src={imagePreviewUrl}
alt="User profile logo preview"
/>
</div>
<hr />
</>
)}
{!isEditing && (
<div className="field">
<label className="label">{emailMessage}</label>
<div className="control is-clearfix">
<input
data-testid="email"
type="text"
readOnly="readOnly"
className="input is-static"
value={watch('email')}
/>
</div>
</div>
)}
<div className="field">
<label className="label">
{useFormatMessage('UserForm.name')}
</label>
<div className="control is-clearfix">
<input
data-testid="name"
type="text"
readOnly="readOnly"
className="input is-static"
value={watch('name')}
/>
</div>
</div>
<div className="field">
<label className="label">
{useFormatMessage('UserForm.location')}
</label>
<div className="control is-clearfix">
<input
data-testid="location"
type="text"
readOnly="readOnly"
className="input is-static"
value={watch('location')}
/>
</div>
</div>
{!isProfile && (
<div className="field">
<label className="label">{adminMessage}</label>
<div className="control is-clearfix" data-testid="admin">
{watch('isAdmin') ? (
<span className="icon">
<i className="mdi mdi-check" />
</span>
) : (
<span className="icon">
<i className="mdi mdi-close" />
</span>
)}
</div>
</div>
)}
<div className="field">
<label className="label">
{useFormatMessage('UserForm.created')}
</label>
<div className="control is-clearfix" data-testid="date">
<p className="date">
{useFormatDate(watch('createdAt'), {
weekday: 'short',
year: 'numeric',
month: 'short',
day: 'numeric',
})}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</>
);
}
Example #23
Source File: ProfileDetails.js From flame-coach-web with MIT License | 4 votes |
ProfileDetails = ({
userDetails,
enablePersonalData,
saveContactInformationHandler,
savePersonalInformationHandler,
updateUserDetailsHandler,
className
}) => {
const classes = useStyles();
logDebug("ProfileDetails", "render", "userDetails", userDetails);
const formContactInformation = useForm();
const formPersonalInformation = useForm();
return (
<Box component="div">
<Card>
<CardContent>
<CardHeader
title="Profile"
subheader="Use this section to update information related with you"
/>
<form
autoComplete="off"
onSubmit={(event) => {
event.preventDefault();
formContactInformation.handleSubmit(
saveContactInformationHandler
)(event);
}}
className={clsx(classes.root, className)}
>
<Accordion defaultExpanded>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="contactInfo-content"
id="contactInfo-header"
>
<Typography component="h2">Contact information</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid
container
spacing={3}
>
<Grid
item
md={6}
xs={12}
>
<TextField
fullWidth
label="First name"
name="firstName"
helperText="First name is required"
error={Boolean(formContactInformation.errors.firstName)}
onChange={updateUserDetailsHandler}
inputRef={formContactInformation.register({ required: true })}
value={userDetails.firstName}
variant="outlined"
/>
</Grid>
<Grid
item
md={6}
xs={12}
>
<TextField
fullWidth
label="Last name"
name="lastName"
onChange={updateUserDetailsHandler}
error={Boolean(formContactInformation.errors.lastName)}
inputRef={formContactInformation.register({ required: true })}
value={userDetails.lastName}
variant="outlined"
/>
</Grid>
<Grid
item
md={6}
xs={12}
>
<TextField
fullWidth
label="Email Address"
name="email"
type="email"
disabled
onChange={updateUserDetailsHandler}
value={userDetails.email}
variant="outlined"
/>
</Grid>
<Grid
item
md={2}
xs={6}
>
<TextField
fullWidth
label="Code"
name="phoneCode"
error={Boolean(formContactInformation.errors.phoneCode)}
inputRef={formContactInformation.register({
required: false,
pattern: "^[+]*[0-9]{1,4}$"
})}
onChange={updateUserDetailsHandler}
value={userDetails.phoneCode}
variant="outlined"
/>
</Grid>
<Grid
item
md={4}
xs={6}
>
<TextField
fullWidth
label="Phone Number"
name="phoneNumber"
inputRef={formContactInformation.register}
onChange={updateUserDetailsHandler}
type="number"
value={userDetails.phoneNumber}
variant="outlined"
/>
</Grid>
<Grid
item
md={6}
xs={12}
>
<FormControl fullWidth variant="outlined">
<InputLabel>Country</InputLabel>
<Controller
render={(renderProps) => (
<Select
key="select_country"
labelId="country"
label="Country"
name="country"
data-testid="country"
value={userDetails.country}
onChange={(event) => {
renderProps.onChange(updateUserDetailsHandler(event));
}}
>
<MenuItem key="default" value="">Country</MenuItem>
{
countries.map((country) => (
<MenuItem key={country.code} value={country.code}>
{country.name}
</MenuItem>
))
}
</Select>
)}
control={formContactInformation.control}
defaultValue={userDetails.country}
name="country"
/>
</FormControl>
</Grid>
</Grid>
</AccordionDetails>
<Divider />
<AccordionActions>
<Box
display="flex"
justifyContent="flex-end"
p={1}
>
<Button
color="primary"
variant="contained"
type="submit"
name="contactInfo-save"
>
Save
</Button>
</Box>
</AccordionActions>
</Accordion>
</form>
{enablePersonalData
? (
<form
autoComplete="off"
onSubmit={(event) => {
event.preventDefault();
formPersonalInformation.handleSubmit(
savePersonalInformationHandler
)(event);
}}
className={clsx(classes.root, className)}
>
<Accordion>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="contactInfo-content"
id="contactInfo-header"
>
<Typography component="h2">Personal information</Typography>
</AccordionSummary>
<AccordionDetails>
<Grid
container
spacing={3}
>
<Grid
item
xs={6}
>
<FormControl fullWidth variant="outlined">
<InputLabel>Measure Type</InputLabel>
<Controller
render={(renderProps) => (
<Select
labelId="measureType"
label="Measure Type"
name="measureType"
value={userDetails.measureType}
onChange={(event) => {
renderProps.onChange(updateUserDetailsHandler(event));
}}
>
<MenuItem value="KG_CM">Kg/cm</MenuItem>
<MenuItem value="LBS_IN">Lbs/in</MenuItem>
</Select>
)}
control={formPersonalInformation.control}
defaultValue={userDetails.measureType}
name="measureType"
/>
</FormControl>
</Grid>
<Grid
item
xs={6}
>
<FormControl fullWidth variant="outlined">
<InputLabel>Gender</InputLabel>
<Controller
render={(renderProps) => (
<Select
labelId="gender"
label="Gender"
name="gender"
value={userDetails.gender}
onChange={(event) => {
renderProps.onChange(updateUserDetailsHandler(event));
}}
>
<MenuItem value="">Gender</MenuItem>
<MenuItem value="M">Male</MenuItem>
<MenuItem value="F">Female</MenuItem>
<MenuItem value="O">Other</MenuItem>
</Select>
)}
control={formPersonalInformation.control}
defaultValue={userDetails.gender}
name="gender"
/>
</FormControl>
</Grid>
<Grid
item
xs={6}
>
<TextField
fullWidth
helperText="Please specify your weight"
label="Weight"
name="weight"
type="number"
inputProps={{
step: 0.05,
min: 0
}}
inputRef={formPersonalInformation.register}
onChange={updateUserDetailsHandler}
value={userDetails.weight}
variant="outlined"
/>
</Grid>
<Grid
item
xs={6}
>
<TextField
fullWidth
helperText="Please specify your height"
label="Height"
name="height"
type="number"
inputProps={{
step: 0.05,
min: 0
}}
inputRef={formPersonalInformation.register}
onChange={updateUserDetailsHandler}
value={userDetails.height}
variant="outlined"
/>
</Grid>
</Grid>
</AccordionDetails>
<Divider />
<AccordionActions>
<Box
display="flex"
justifyContent="flex-end"
p={2}
>
<Button
color="primary"
variant="contained"
type="submit"
name="personalInfo-save"
>
Save
</Button>
</Box>
</AccordionActions>
</Accordion>
</form>
)
: null}
</CardContent>
</Card>
</Box>
);
}
Example #24
Source File: createJob.page.js From hiring-system with GNU General Public License v3.0 | 4 votes |
CreateJob = () => {
const { handleSubmit, watch, errors, control, getValues } = useForm({
mode: "all",
reValidateMode: "onChange",
});
const [selectedPostDate, setSelectedPostDate] = useState();
const watchDate = watch("jobPostDate");
const onSubmit = (data) => {
// code to submit form
console.log(data);
};
useEffect(() => {
if (!getValues("jobPostDate")) {
return;
}
const selectedDate = new Date(getValues("jobPostDate"));
setSelectedPostDate(selectedDate.toDateString());
}, [watchDate]);
return (
<>
<div className="create-job-container" style={styles.pageContainer}>
<div>
<Card style={styles.cardContainer}>
<CardBody>
<CardTitle style={styles.section}>
<h3> Create New Job</h3>
</CardTitle>
<Form
style={styles.formContainer}
onSubmit={handleSubmit(onSubmit)}
>
<FormGroup>
<Controller
as={Input}
type="text"
name="jobTitle"
control={control}
rules={{ required: true }}
placeholder="Enter Job Title"
/>
{errors.jobTitle && (
<span className="error-text">This field is required</span>
)}
</FormGroup>
<FormGroup>
<Controller
as={Input}
type="text"
name="jobDesc"
control={control}
rules={{ required: true }}
placeholder="Enter Job Description"
/>
{errors.jobDesc && (
<span className="error-text">This field is required</span>
)}
</FormGroup>
<FormGroup>
<Controller
name="skills"
as={Select}
options={skills}
control={control}
rules={{ required: true }}
isMulti
placeholder="Select Skills"
/>
{errors.skills && (
<span className="error-text">This field is required</span>
)}
</FormGroup>
<FormGroup>
<Controller
as={Input}
type="text"
name="companyName"
control={control}
rules={{ required: true }}
placeholder="Enter Company Name"
/>
{errors.companyName && (
<span className="error-text">This field is required</span>
)}
</FormGroup>
<FormGroup style={styles.relativeEle}>
<Input
type="text"
name="jobPostDateInput"
placeholder="Select Job Post Date"
value={selectedPostDate}
/>
{errors.jobPostDate && (
<span className="error-text">This field is required</span>
)}
<Controller
name="jobPostDate"
as={DatePicker}
control={control}
rules={{ required: true }}
maxDate={new Date()}
clearIcon={null}
className="app-date-custom-style"
/>
</FormGroup>
<FormGroup>
<Controller
as={Input}
type="text"
name="workLocation"
control={control}
rules={{ required: true }}
placeholder="Enter Work Location"
/>
{errors.workLocation && (
<span className="error-text">This field is required</span>
)}
</FormGroup>
<FormGroup>
<Controller
name="benefits"
as={Select}
options={benefits}
control={control}
rules={{ required: true }}
placeholder="Select Benefits"
isMulti
/>
{errors.benefits && (
<span className="error-text">This field is required</span>
)}
</FormGroup>
<FormGroup>
<Controller
name="workVisa"
as={Select}
options={visaSelection}
control={control}
rules={{ required: true }}
placeholder="Will Sponsor Work Visa"
/>
{errors.workVisa && (
<span className="error-text">This field is required</span>
)}
</FormGroup>
<div style={styles.section}>
<Button type="submit" variant="primary">
Create New Job
</Button>
</div>
</Form>
</CardBody>
</Card>
</div>
</div>
</>
);
}
Example #25
Source File: EventEditor.jsx From club-connect with GNU General Public License v3.0 | 4 votes |
EventEditor = (props) => {
const { formType, submitFunction, submitting } = props;
const router = useRouter();
const { register, handleSubmit, control, watch, reset } = useForm();
const useCustomInternalName = watch('useCustomInternalName');
const [bannerFile, setBannerFile] = useState(null);
const [presenterImageFile, setPresenterImageFile] = useState(null);
const [editorReady, setEditorReady] = useState(formType !== 'edit');
useEffect(async () => {
if (formType === 'edit') {
// Get event ID from query string
const parsedQueryString = queryString.parse(location.search);
if (!parsedQueryString.id) {
toastErrorCenter('No event ID was specified for editing.');
await router.push('/events');
return;
}
const eventId = parsedQueryString.id;
// Get the event data to edit
let res;
try {
res = await axios.get(`${API_ROOT}/events/${eventId}`);
} catch (err) {
toastErrorCenter('An error occurred while getting the event data.');
await router.push(`/events/${eventId}`);
return;
}
// Load event data into the form
reset(res.data);
setEditorReady(true);
}
}, []);
// Prepare form data to be submitted
const prepareFormData = (submittedData) => {
const eventData = cloneDeep(submittedData);
// Set empty string values and undefined to null
for (const [key, value] of Object.entries(eventData)) {
if (value === '' || value === undefined) {
eventData[key] = null;
}
}
// Convert datetimes to ISO strings
if (eventData.startDateTime) {
eventData.startDateTime = new Date(eventData.startDateTime).toISOString();
}
if (eventData.endDateTime) {
eventData.endDateTime = new Date(eventData.endDateTime).toISOString();
}
// Prepare FormData by serializing form data to JSON and appending files if they exist
// Remove files from form data before serializing
delete eventData.banner;
delete eventData.presenterImage;
const formData = new FormData();
formData.append('formDataJson', JSON.stringify(eventData));
if (bannerFile) {
formData.append('bannerFile', bannerFile);
}
if (presenterImageFile) {
formData.append('presenterImageFile', presenterImageFile);
}
// Submit the form
submitFunction(formData);
};
return (
<>
<form onSubmit={handleSubmit(prepareFormData)}>
<div className={formStyles.labeledInput}>
<label htmlFor="title">Title*</label>
<input
type="text"
id="title"
name="title"
disabled={!editorReady || submitting}
placeholder={!editorReady ? 'Loading...' : ''}
ref={register}
required
/>
</div>
{(formType === 'create' || formType === 'edit') && (
<div className={eventEditorStyles.presenterInputs}>
<div className={formStyles.labeledInput}>
<label htmlFor="presenter">Presenter</label>
<input
type="text"
id="presenter"
name="presenter"
disabled={!editorReady || submitting}
ref={register}
/>
</div>
<div className={formStyles.labeledInput}>
<label
className={eventEditorStyles.presenterImageLabel}
htmlFor="presenterImage"
>
{windowSupported() && window.innerWidth <= 700
? 'Presenter Image'
: 'Image'}
</label>
<Controller
name="presenterImage"
control={control}
render={({ onChange }) => (
<PresenterImageUpload
onChange={onChange}
setPresenterImageFile={setPresenterImageFile}
/>
)}
/>
</div>
</div>
)}
<div className={formStyles.labeledInput}>
<label htmlFor="banner">
Banner (Will be resized to a 16:9 aspect ratio)
{formType === 'request' && '*'}
</label>
<Controller
name="banner"
control={control}
render={({ onChange }) => (
<BannerUpload onChange={onChange} setBannerFile={setBannerFile} />
)}
/>
</div>
<MuiPickersUtilsProvider utils={DayJsUtils}>
<div className={formStyles.twoColumn}>
<div className={formStyles.labeledInput}>
<label htmlFor="startDateTime">
Start Date and Time{formType === 'request' && '*'}
</label>
<Controller
control={control}
name="startDateTime"
id="startDateTime"
as={
<DateTimePicker
defaultValue={null}
variant="dialog"
format="MM/DD/YYYY, h:mm A"
TextFieldComponent={(props) => <input {...props} />}
readOnly={!editorReady || submitting}
required={formType === 'request'}
emptyLabel
showTodayButton
/>
}
/>
</div>
<div className={formStyles.labeledInput}>
<label htmlFor="endDateTime">
End Date and Time{formType === 'request' && '*'}
</label>
<Controller
control={control}
name="endDateTime"
id="endDateTime"
as={
<DateTimePicker
variant="dialog"
format="MM/DD/YYYY, h:mm A"
TextFieldComponent={(props) => <input {...props} />}
readOnly={!editorReady || submitting}
required={formType === 'request'}
emptyLabel
showTodayButton
/>
}
/>
</div>
</div>
</MuiPickersUtilsProvider>
<div className={formStyles.labeledInput}>
<label htmlFor="eventLocation">
Location (Either Online or a building's address and room number)
{formType === 'request' && '*'}
</label>
<input
type="text"
id="eventLocation"
name="eventLocation"
disabled={!editorReady || submitting}
required={formType === 'request'}
ref={register}
/>
</div>
<div className={formStyles.labeledInput}>
<label htmlFor="externalLink">
External Link (This can be a direct Zoom/Google Meet link)
{formType === 'request' && '*'}
</label>
<input
type="text"
id="externalLink"
name="externalLink"
disabled={!editorReady || submitting}
required={formType === 'request'}
ref={register}
/>
</div>
<div className={formStyles.labeledInput}>
<label htmlFor="externalLinkButtonText">
External Link Button Text (The green button on the event page)
{formType === 'request' && '*'}
</label>
<input
type="text"
id="externalLinkButtonText"
name="externalLinkButtonText"
disabled={!editorReady || submitting}
required={formType === 'request'}
ref={register}
/>
</div>
<div className={formStyles.labeledInput}>
<label htmlFor="shortDescription">
Short Event Description (Under 250 characters)
{formType === 'request' && '*'}
</label>
<input
type="text"
id="shortDescription"
name="shortDescription"
disabled={!editorReady || submitting}
required={formType === 'request'}
ref={register}
/>
</div>
<div className={formStyles.labeledInput}>
<label htmlFor="longDescription">
Long Description{formType === 'request' && '*'}
</label>
<textarea
rows="10"
id="longDescription"
name="longDescription"
disabled={!editorReady || submitting}
required={formType === 'request'}
ref={register}
/>
</div>
<div
className={`${formStyles.customInternalName} ${formStyles.checkbox} ${formStyles.checkboxCentered}`}
>
<input
type="checkbox"
name="useCustomInternalName"
id="useCustomInternalName"
disabled={!editorReady || submitting}
ref={register}
/>
<label htmlFor="useCustomInternalName">
Use Custom Internal Name
</label>
</div>
{useCustomInternalName && (
<div className={`${formStyles.labeledInput}`}>
<label htmlFor="internalName">
Internal Name (must-be-lowercase-kebab-case-like-this)*
</label>
<input
type="text"
id="internalName"
name="internalName"
pattern="^([a-z][a-z0-9]*)(-[a-z0-9]+)*$"
disabled={!editorReady || submitting}
required={useCustomInternalName}
ref={register}
/>
</div>
)}
{formType === 'create' && (
<Button
classNamePassed={`${formStyles.formButton} ${commonStyles.actionButton}`}
type="submit"
disabled={!editorReady || submitting}
>
{submitting ? 'Creating Event...' : 'Create Event'}
</Button>
)}
{formType === 'request' && (
<Button
classNamePassed={`${formStyles.formButton} ${commonStyles.actionButton}`}
type="submit"
disabled={!editorReady || submitting}
>
{submitting ? 'Submitting Request...' : 'Submit Request'}
</Button>
)}
{formType === 'edit' && (
<Button
classNamePassed={`${formStyles.formButton} ${commonStyles.actionButton}`}
type="submit"
disabled={!editorReady || submitting}
>
{submitting ? 'Saving...' : 'Save Changes'}
</Button>
)}
</form>
</>
);
}
Example #26
Source File: AddEditAuditoria.jsx From core-audit with MIT License | 4 votes |
AddEditAuditoria = ({history})=> {
const refFire = useFirestore();
const [iglesias, setIglesias] = useState([])
const { register, handleSubmit,control, formState:{ errors } } = useForm({
resolver: yupResolver(schema)
})
const crear = async (datos) => {
console.log(datos)
await refFire.collection('auditorias').doc().set(datos)
toast('Auditoria Creada.')
history.push('/auditorias')
}
const onSubmit = (datos)=> {
crear(datos)
}
const onCancelar = ()=> {
history.push('/auditorias')
}
useEffect(() => {
const traerDatos = async () => {
const temporales = []
const snapshot = await refFire.collection('iglesias').get()
snapshot.docs.forEach((doc)=>{
const elem = {
id: doc.id,
...doc.data(),
value: doc.id,
label: doc.data().nombre
}
temporales.push(elem)
})
setIglesias(temporales)
}
traerDatos()
}, [refFire])
return (
<div className="card">
<div className="card-body">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="input-gruop">
<label>Fecha</label>
<input className="form-control" type="date" {...register('fecha')} />
{ errors.nombre?.message}
</div>
<div className="input-gruop">
<label>Activo</label>
<input value="0" type="radio" {...register('activo')} />
<label>Inactivo</label>
<input value="1" type="radio" {...register('activo')} />
</div>
<div className="input-gruop">
<label>Actual</label>
<input value="0" type="radio" {...register('actual')} />
<label>No actual</label>
<input value="1" type="radio" {...register('actual')} />
</div>
<Controller
name="iglesia"
control={control}
render={({field}) => <Select
{...field}
options={iglesias}
/>}
/>
<button className="btn btn-primary" type="submit" >Guardar</button>
<button className="btn btn-warning" type="button" onClick={() => onCancelar()}>Cancelar</button>
</form>
</div>
</div>
)
}