Form & Form Item

Basic usage

<script lang="ts">
  let name = ''
  let gender = ''
  let industry = ''
  let birthday: Date

  const genderOptions = [
    {
      label: 'Male',
      value: 0,
    },
    {
      label: 'Female',
      value: 1,
    },
  ]

  const industryOptions = [
    { label: 'IT', value: 0 },
    { label: 'Medical', value: 1 },
    { label: 'Transport', value: 2 },
    { label: 'Education', value: 3 },
  ]

</script>

<CForm>
  <CFormItem label="Name">
    <CInput bind:value={name} placeholder="Your name" />
  </CFormItem>
  <CFormItem label="Gender">
    <CRadioGroup options={genderOptions} bind:value={gender} />
  </CFormItem>
  <CFormItem label="Birthday">
    <CDatePicker
      bind:value={birthday}
      format="MM/DD YYYY"
      placeholder="Your birthday"
    />
  </CFormItem>
  <CFormItem label="Industry">
    <CSelect
      bind:value={industry}
      options={industryOptions}
      placeholder="Your industry"
    />
  </CFormItem>
</CForm>
svelte
Click fold/expand code

Control sizes

<script lang="ts">
  let name = ''
  let gender = ''
  let industry = ''
  let birthday: Date

  const genderOptions = [
    {
      label: 'Male',
      value: 0,
    },
    {
      label: 'Female',
      value: 1,
    },
  ]

  const industryOptions = [
    { label: 'IT', value: 0 },
    { label: 'Medical', value: 1 },
    { label: 'Transport', value: 2 },
    { label: 'Education', value: 3 },
  ]

  let size: 'xs' | 'sm' | 'md' | 'xl' | 'lg' = 'md'
  const sizes = [
    {
      label: 'xs',
      value: 'xs',
    },
    {
      label: 'sm',
      value: 'sm',
    },
    {
      label: 'md',
      value: 'md',
    },
    {
      label: 'lg',
      value: 'lg',
    },
    {
      label: 'xl',
      value: 'xl',
    },
  ]
</script>

<CForm {size}>
  <CFormItem label="Sizes" col={12}>
    <CRadioGroup bind:value={size} options={sizes} />
  </CFormItem>
  <CFormItem label="Name">
    <CInput bind:value={name} placeholder="Your name" />
  </CFormItem>
  <CFormItem label="Gender">
    <CRadioGroup options={genderOptions} bind:value={gender} />
  </CFormItem>
  <CFormItem label="Birthday">
    <CDatePicker
      bind:value={birthday}
      format="MM/DD YYYY"
      placeholder="Your birthday"
    />
  </CFormItem>
  <CFormItem label="Industry">
    <CSelect
      bind:value={industry}
      options={industryOptions}
      placeholder="Your industry"
    />
  </CFormItem>
</CForm>
svelte
Click fold/expand code

Gutter sizes

<script lang="ts">
  let name = ''
  let gender = ''
  let industry = ''
  let birthday: Date

  const genderOptions = [
    {
      label: 'Male',
      value: 0,
    },
    {
      label: 'Female',
      value: 1,
    },
  ]

  const industryOptions = [
    { label: 'IT', value: 0 },
    { label: 'Medical', value: 1 },
    { label: 'Transport', value: 2 },
    { label: 'Education', value: 3 },
  ]

  let size: 'xs' | 'sm' | 'md' | 'xl' | 'lg' = 'md'
  const sizes = [
    {
      label: 'xs',
      value: 'xs',
    },
    {
      label: 'sm',
      value: 'sm',
    },
    {
      label: 'md',
      value: 'md',
    },
    {
      label: 'lg',
      value: 'lg',
    },
    {
      label: 'xl',
      value: 'xl',
    },
  ]
</script>

<CForm gutterSize={size}>
  <CFormItem label="Gutter size" col={12}>
    <CRadioGroup bind:value={size} options={sizes} />
  </CFormItem>
  <CFormItem label="Name">
    <CInput bind:value={name} placeholder="Your name" />
  </CFormItem>
  <CFormItem label="Gender">
    <CRadioGroup options={genderOptions} bind:value={gender} />
  </CFormItem>
  <CFormItem label="Birthday">
    <CDatePicker
      bind:value={birthday}
      format="MM/DD YYYY"
      placeholder="Your birthday"
    />
  </CFormItem>
  <CFormItem label="Industry">
    <CSelect
      bind:value={industry}
      options={industryOptions}
      placeholder="Your industry"
    />
  </CFormItem>
</CForm>
svelte
Click fold/expand code

Label width

<script lang="ts">
  let labelWidth = '80px'
  let name = ''
  let gender = ''
  let industry = ''
  let birthday: Date

  const genderOptions = [
    {
      label: 'Male',
      value: 0,
    },
    {
      label: 'Female',
      value: 1,
    },
  ]

  const industryOptions = [
    { label: 'IT', value: 0 },
    { label: 'Medical', value: 1 },
    { label: 'Transport', value: 2 },
    { label: 'Education', value: 3 },
  ]
</script>

<CForm {labelWidth}>
  <CFormItem label="Label width">
    <CInput bind:value={labelWidth} placeholder="Label width" />
  </CFormItem>
  <CFormItem label="Name">
    <CInput bind:value={name} placeholder="Your name" />
  </CFormItem>
  <CFormItem label="Gender">
    <CRadioGroup options={genderOptions} bind:value={gender} />
  </CFormItem>
  <CFormItem label="Birthday">
    <CDatePicker
      bind:value={birthday}
      format="MM/DD YYYY"
      placeholder="Your birthday"
    />
  </CFormItem>
  <CFormItem label="Industry">
    <CSelect
      bind:value={industry}
      options={industryOptions}
      placeholder="Your industry"
    />
  </CFormItem>
</CForm>
svelte
Click fold/expand code

Label align

<script lang="ts">
  let name = ''
  let gender = ''
  let industry = ''
  let birthday: Date

  const genderOptions = [
    {
      label: 'Male',
      value: 0,
    },
    {
      label: 'Female',
      value: 1,
    },
  ]

  const industryOptions = [
    { label: 'IT', value: 0 },
    { label: 'Medical', value: 1 },
    { label: 'Transport', value: 2 },
    { label: 'Education', value: 3 },
  ]

  let labelAlign: 'left' | 'center' | 'right' = 'left'
  const aligns = [
    {
      label: 'left',
      value: 'left',
    },
    {
      label: 'center',
      value: 'center',
    },
    {
      label: 'right',
      value: 'right',
    },
  ]
</script>

<CForm {labelAlign}>
  <CFormItem label="Gutter size" col={12}>
    <CRadioGroup bind:value={labelAlign} options={aligns} />
  </CFormItem>
  <CFormItem label="Name">
    <CInput bind:value={name} placeholder="Your name" />
  </CFormItem>
  <CFormItem label="Gender">
    <CRadioGroup options={genderOptions} bind:value={gender} />
  </CFormItem>
  <CFormItem label="Birthday">
    <CDatePicker
      bind:value={birthday}
      format="MM/DD YYYY"
      placeholder="Your birthday"
    />
  </CFormItem>
  <CFormItem label="Industry">
    <CSelect
      bind:value={industry}
      options={industryOptions}
      placeholder="Your industry"
    />
  </CFormItem>
</CForm>
svelte
Click fold/expand code

Label direction

<script lang="ts">
  let name = ''
  let gender = ''
  let industry = ''
  let birthday: Date

  const genderOptions = [
    {
      label: 'Male',
      value: 0,
    },
    {
      label: 'Female',
      value: 1,
    },
  ]

  const industryOptions = [
    { label: 'IT', value: 0 },
    { label: 'Medical', value: 1 },
    { label: 'Transport', value: 2 },
    { label: 'Education', value: 3 },
  ]

  let labelDirection: 'row' | 'row-reverse' | 'column' | 'column-reverse' =
    'row'
  const directions = [
    {
      label: 'row',
      value: 'row',
    },
    {
      label: 'row-reverse',
      value: 'row-reverse',
    },
    {
      label: 'column',
      value: 'column',
    },
    {
      label: 'column-reverse',
      value: 'column-reverse',
    },
  ]
</script>

<CForm {labelDirection}>
  <CFormItem label="Gutter size" col={12}>
    <CRadioGroup bind:value={labelDirection} options={directions} />
  </CFormItem>
  <CFormItem label="Name">
    <CInput bind:value={name} placeholder="Your name" />
  </CFormItem>
  <CFormItem label="Gender">
    <CRadioGroup options={genderOptions} bind:value={gender} />
  </CFormItem>
  <CFormItem label="Birthday">
    <CDatePicker
      bind:value={birthday}
      format="MM/DD YYYY"
      placeholder="Your birthday"
    />
  </CFormItem>
  <CFormItem label="Industry">
    <CSelect
      bind:value={industry}
      options={industryOptions}
      placeholder="Your industry"
    />
  </CFormItem>
</CForm>
svelte
Click fold/expand code

Normal (sync) Validation

To make validation work. The value, rules prop need to be set.

And the CFormItem's field prop also needed.

The rules is an object that contains every field rules. Its' type look like this:

type Validator = (val: any) => string | false | Promise<string | false>
interface Rules {
  [key: string]: Array<Validator>
}
ts

Each rule can be a function that receive current value and return a string message or a false or a Promise<string | false>.

  • The string message will be shown at the bottom of form item.
  • false means no error.
  • Promise<string | false> means a async validation.
<script lang="ts">
  let name = ''
  let gender = ''
  let industry = ''
  let birthday: Date

  const genderOptions = [
    {
      label: 'Male',
      value: 0,
    },
    {
      label: 'Female',
      value: 1,
    },
  ]

  const industryOptions = [
    { label: 'IT', value: 0 },
    { label: 'Medical', value: 1 },
    { label: 'Transport', value: 2 },
    { label: 'Education', value: 3 },
  ]

  let form: CForm

  const rules = {
    name: [(v: string) => (v ? false : 'Please enter name')],
    gender: [(v: any) => (v === '' ? 'Please select gender' : false)],
    birthday: [(v: any) => (v ? false : 'Please select birthday')],
    industry: [(v: any) => (v === '' ? 'Please select industry' : false)],
  }

  function onSubmit() {
    form.validateAll().then(() => {
      openNotification({
        theme: 'secondary',
        title: 'Congratulations!',
        message: 'Form validation passed',
      })
    })
  }
  function onReset() {
    form.clearAll()
  }
</script>

<CForm
  bind:this={form}
  value={{
    name,
    gender,
    birthday,
    industry,
  }}
  {rules}
>
  <CFormItem label="Name" field="name">
    <CInput bind:value={name} placeholder="Your name" />
  </CFormItem>
  <CFormItem label="Gender" field="gender">
    <CRadioGroup options={genderOptions} bind:value={gender} />
  </CFormItem>
  <CFormItem label="Birthday" field="birthday">
    <CDatePicker
      bind:value={birthday}
      format="MM/DD YYYY"
      placeholder="Your birthday"
    />
  </CFormItem>
  <CFormItem label="Industry" field="industry">
    <CSelect
      bind:value={industry}
      options={industryOptions}
      placeholder="Your industry"
    />
  </CFormItem>
</CForm>
<div class="c-flex c-justify-end c-mt-xl c-gutter-x-sm">
  <div>
    <CButton label="Reset" outlined on:click={onReset} />
  </div>
  <div>
    <CButton label="Submit" on:click={onSubmit} />
  </div>
</div>
svelte
Click fold/expand code

Async validation

To use validation the async validation.

The rule item need to be a function that return a Promise<string | false>. For example:

const rule = async function (v) {
  return await someApiValidation(v)
}
js
<script lang="ts">
  import { openNotification } from '@casual-ui/svelte'

  let name = ''

  let gender = ''

  let industry = ''

  let birthday: Date

  let validating = false
  let nameLoading = false

  const genderOptions = [
    {
      label: 'Male',
      value: 0,
    },
    {
      label: 'Female',
      value: 1,
    },
  ]

  const industryOptions = [
    { label: 'IT', value: 0 },
    { label: 'Medical', value: 1 },
    { label: 'Transport', value: 2 },
    { label: 'Education', value: 3 },
  ]

  let form: CForm

  const rules = {
    name: [
      (v: string) =>
        new Promise<string | false>(resolve => {
          nameLoading = true
          setTimeout(() => {
            resolve(v ? false : 'Please enter name')
            nameLoading = false
          }, 2000)
        }),
    ],
    gender: [(v: any) => (v === '' ? 'Please select gender' : false)],
    birthday: [(v: any) => (v ? false : 'Please select birthday')],
    industry: [(v: any) => (v === '' ? 'Please select industry' : false)],
  }

  function onSubmit() {
    form.validateAll().then(() => {
      openNotification({
        title: 'Congratulations!',
        message: 'Form validation passed',
      })
    })
  }
  function onReset() {
    form.clearAll()
  }
</script>

<CForm
  bind:this={form}
  value={{
    name,
    gender,
    birthday,
    industry,
  }}
  {rules}
  bind:validating
>
  <CFormItem label="Name" field="name">
    <CInput bind:value={name} placeholder="Your name" loading={nameLoading} />
  </CFormItem>
  <CFormItem label="Gender" field="gender">
    <CRadioGroup options={genderOptions} bind:value={gender} />
  </CFormItem>
  <CFormItem label="Birthday" field="birthday">
    <CDatePicker
      bind:value={birthday}
      format="MM/DD YYYY"
      placeholder="Your birthday"
    />
  </CFormItem>
  <CFormItem label="Industry" field="industry">
    <CSelect
      bind:value={industry}
      options={industryOptions}
      placeholder="Your industry"
    />
  </CFormItem>
</CForm>
<div class="c-flex c-justify-end c-mt-xl c-gutter-x-sm">
  <div>
    <CButton label="Reset" outlined on:click={onReset} />
  </div>
  <div>
    <CButton label="Submit" on:click={onSubmit} loading={validating} />
  </div>
</div>
svelte
Click fold/expand code

CForm Props

  • value
    Record<string, any>
    default: undefined

    The whole form data

  • rules
    Record<string, Array<(val: any) => string | false | Promise<string | false>>>
    default: undefined

    The validators of each form item.

  • labelWidth
    string=
    default: undefined

    The label width of whole form. Notice that the default value is '80px' instead of undefined.

  • col
    number=
    default: undefined

    The col span of each form item. Total cols are 12. Notice that default value is 6 instead of undefined

  • labelDirection
    'row' | 'row-reverse' | 'column' | 'column-reverse'=
    default: undefined

    Label and form component arrangement direction.

    Notice that the defualt value is 'row' instead of undefined.

    This prop use CSS flex-direction.

  • labelAlign
    'left' | 'center' | 'right'=
    default: undefined

    The label itself arrangement direction.

    Notice that the default value is 'left' instead of undefined

    This prop use CSS text-align

  • size
    'xs' | 'sm' | 'md' | 'lg' | 'xl'=
    default: undefined

    The size of whole form.

    Notice that the default value is 'md' instead of undefined.

    TIP

    This prop will affect all the components that holds the size props.

  • gutterSize
    'xs' | 'sm' | 'md' | 'lg' | 'xl'=
    default: undefined

    The gutte size between label and form component. Notice that the default value is 'md' instead of undefined.

  • validating
    boolean
    default: false

    The falg that determine form is in validating or not.

    It will be set to true when the validateAll or validateSomeField method is called.

    It will be restore to false when all validations are over.

CForm Events

No data

CForm Slots

No data

CForm Exports

  • errorStatusKey
    symbol

    The errorStatus inject key. Example:

    import { getContext } from 'svelte'
    import { errorStatusKey } from 'casual-ui-svelte/components/form/CForm.svelte'
    const errorStaus: ErrorStatus = getContext(errorStatusKey)
    type ErrorStatus = Writable<Record<string, string | false>>
    ts
  • validateSomeFieldKey
    symbol

    The function to validate specify field. Example:

    import { validateSomeFieldKey } from 'casual-ui-svelte/components/form/CForm.svelte'
    import { getContext } from 'svelte'
    const validateSomeField = getContext(validateSomeFieldKey)
    
    // At some proper time
    validateSomeFiled?.('field')
    ts
  • clearSomeFieldKey
    symbol

    The function to clear specify field validate status. Example:

    import { clearSomeFieldKey } from 'casual-ui-svelte/components/form/CForm.svelte'
    import { getContext } from 'svelte'
    const clearSomeField = getContext(clearSomeFieldKey)
    
    // At some proper time
    clearSomeField?.('field')
    ts
  • rulesKey
    symbol

    The rules object. Can be used like this:

  • validateSomeField
    function

    Validate a single field

  • clearSomeField
    function

    Clear a specified field validate status

  • validateAll
    function

    Validate all fields

  • clearAll
    function

    Clear all fields validate status

CFormItem Props

  • field
    string=
    default: undefined

    The field of whole form data

  • label
    string
    default:

    The label of each form item

  • labelWidth
    string=
    default: undefined

    The label width of this form item. Notice that this prop will override the CForm's labelWidth prop

  • col
    number=
    default: undefined

    This form item col span

  • labelDirection
    'row' | 'row-reverse' | 'column' | 'column-reverse'=
    default: undefined

    The label and form component arrangement direction of this form item

  • labelAlign
    'left' | 'center' | 'right'=
    default: undefined

    The label align of this form item

  • size
    'xs' | 'sm' | 'md' | 'lg' | 'xl'=
    default: undefined

    The size of component in this form item. Notice that the default value is 'md' instead of undefined

  • gutterSize
    'xs' | 'sm' | 'md' | 'lg' | 'xl'=
    default: undefined

    The gutter size of this form item.

CFormItem Events

No data

CFormItem Slots

  • default

    The content of this form item. You can use built-in form components like CInput

CFormItem Exports

No data
Last update at: 2024/07/08 10:39:42