add checkbox field type

fixes https://github.com/ohmyform/ohmyform/issues/138
This commit is contained in:
Michael Schramm 2022-01-03 09:00:31 +01:00
parent 831e0d7779
commit 5bcaedb556
7 changed files with 172 additions and 0 deletions

View File

@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- field logic
- add enviroment config
- anonymous form submissions (fixes https://github.com/ohmyform/ohmyform/issues/108)
- checkbox field type (fixed https://github.com/ohmyform/ohmyform/issues/138)
### Changed

View File

@ -30,9 +30,20 @@ export const SubmissionValues: React.FC<Props> = (props) => {
{
title: t('submission:value'),
render(_, row) {
console.log('row.value', row.value)
try {
const data = JSON.parse(row.value) as { value: string }
if (Array.isArray(data.value)) {
return (
<ul>
{data.value.map(r => (
<li key={r}>{JSON.stringify(r)}</li>
))}
</ul>
)
}
return data.value
} catch (e) {
return row.value

View File

@ -0,0 +1,77 @@
import { Button, Col, Form, Input, Row } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { AdminFieldTypeProps } from './type.props'
export const CheckboxType: React.FC<AdminFieldTypeProps> = (props) => {
const { t } = useTranslation()
return (
<div>
<Form.Item
label={t('type:checkbox:default')}
name={[props.field.name as string, 'value']}
labelCol={{ span: 6 }}
>
<Input />
</Form.Item>
<Form.List name={[props.field.name as string, 'options']}>
{(fields, { add, remove }) => {
return (
<div>
{fields.map((field, index) => (
<Form.Item
wrapperCol={{
sm: { offset: index === 0 ? 0 : 6 },
}}
labelCol={{ span: 6 }}
label={index === 0 ? t('type:checkbox:options') : ''}
key={field.key}
>
<Row gutter={16}>
<Col span={12}>
<Form.Item
wrapperCol={{ span: 24 }}
name={[field.name, 'title']}
style={{ marginBottom: 0 }}
>
<Input placeholder={t('type:checkbox:titlePlaceholder')} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
wrapperCol={{ span: 24 }}
name={[field.name, 'value']}
style={{ marginBottom: 0 }}
rules={[{ required: true, message: t('validation:valueRequired') }]}
>
<Input placeholder={t('type:checkbox:valuePlaceholder')} />
</Form.Item>
</Col>
<Col span={4}>
<Button danger onClick={() => remove(index)}>
{t('type:checkbox:removeOption')}
</Button>
</Col>
</Row>
</Form.Item>
))}
<Form.Item
wrapperCol={{
sm: { offset: 6 },
}}
labelCol={{ span: 6 }}
>
<Button type={'dashed'} onClick={() => add()}>
{t('type:checkbox:addOption')}
</Button>
</Form.Item>
</div>
)
}}
</Form.List>
</div>
)
}

View File

@ -1,4 +1,5 @@
import React from 'react'
import { CheckboxType } from './checkbox.type'
import { DateType } from './date.type'
import { DropdownType } from './dropdown.type'
import { EmailType } from './email.type'
@ -18,6 +19,7 @@ export const adminTypes: {
} = {
date: DateType,
dropdown: DropdownType,
checkbox: CheckboxType,
email: EmailType,
hidden: HiddenType,
link: LinkType,

View File

@ -0,0 +1,41 @@
import { Checkbox, Form } from 'antd'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { StyledCheckbox } from '../../styled/checkbox'
import { FieldTypeProps } from './type.props'
export const CheckboxType: React.FC<FieldTypeProps> = ({ field, design, urlValue }) => {
const { t } = useTranslation()
let initialValue: string = undefined
if (field.value) {
initialValue = field.value
}
if (urlValue) {
initialValue = urlValue
}
return (
<div>
<Form.Item
name={[field.id, 'value']}
rules={[{ required: field.required, message: t('validation:valueRequired') }]}
initialValue={field.options
.map((option) => option.value)
.find((value) => value === initialValue)}
>
<Checkbox.Group>
{field.options
.filter((option) => option.key === null)
.map((option) => (
<StyledCheckbox design={design} value={option.value} key={option.value}>
{option.title || option.value}
</StyledCheckbox>
))}
</Checkbox.Group>
</Form.Item>
</div>
)
}

View File

@ -1,4 +1,5 @@
import React from 'react'
import { CheckboxType } from './checkbox.type'
import { DateType } from './date.type'
import { DropdownType } from './dropdown.type'
import { EmailType } from './email.type'
@ -17,6 +18,7 @@ export const fieldTypes: {
} = {
date: DateType,
dropdown: DropdownType,
checkbox: CheckboxType,
email: EmailType,
link: LinkType,
number: NumberType,

View File

@ -0,0 +1,38 @@
import { Checkbox } from 'antd'
import { RadioProps } from 'antd/lib/radio/interface'
import React from 'react'
import styled from 'styled-components'
import { FormPublicDesignFragment } from '../../graphql/fragment/form.public.fragment'
interface Props extends RadioProps {
design: FormPublicDesignFragment
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-assignment
const Field = styled(Checkbox)`
color: ${(props: Props) => props.design.colors.answer};
border-color: ${(props: Props) => props.design.colors.answer};
background: none;
.ant-radio {
.ant-radio-inner {
border-color: ${(props: Props) => props.design.colors.answer};
&::after {
background: ${(props: Props) => props.design.colors.answer};
}
}
&::after {
border-color: ${(props: Props) => props.design.colors.answer};
}
}
.anticon {
color: ${(props: Props) => props.design.colors.answer};
}
`
export const StyledCheckbox: React.FC<Props> = ({ children, ...props }) => {
return <Field {...props}>{children}</Field>
}