Giter VIP home page Giter VIP logo

open-forms-sdk's People

Contributors

annashamray avatar bart-maykin avatar bartvaderkin avatar charstring avatar dariomory avatar jiromaykin avatar joeribekker avatar nikkiysendoorn1 avatar pi-sigma avatar robbert avatar sergei-maertens avatar shea-maykinmedia avatar silviaamam avatar stevenbal avatar svenvandescheur avatar vaszig avatar viicos avatar vjawala avatar xaohs avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

open-forms-sdk's Issues

Prototyping: explore binding webcomponents via React (step 1)

Part of the prototyping for a suitable formio renderer replacement architecture

The goal of this ticket is to explore rendering formio leaf nodes through a light binding with React (this means: exclude containers like repeating groups, columns, fieldsets..., which is part of step 2 if step 1 is viable).

The ideas to explore/validate here are:

  • We can write a thin React wrapper around web components
  • We can pass javascript state/properties/objects to web components
  • We can hook into events fired by web components to update our internal React state

Formik can be left out of scope for this experiment, as bullet 3 fulfills the requirements (since it listens to onChange, onBlur etc. which are standard DOM events).

Subtasks

  • Define a custom webcomponent for a date picker (<proto-date-picker ... />)
    • The component should just render three dropdowns: day, month, year
    • When any dropdown changes, the "value" of the component changes (which is an ISO-8601 date, YYYY-MM-DD)
    • Sample usage
      <proto-date-picker name="myDate" value="2023-01-24" locale="nl" />
  • Implement a React wrapper/higher order component
    • Sample code
      const WebComponentWrapper = ({formioKey, values, component, onChange}) => {
        const currentValue = values?.[formioKey] || '';
        const ref = useRef(null);
        
        useEffect(
          () => {
            let mounted = false;
            if (!ref.current) return;
            mounted = true;
            // pass necessary context - this is our public API
            ref.current.ofValues = values;
            ref.current.formioComponent = component;
            // bind events
            ref.current.addEventListener('change', (event) => onChange(event));
            return () => {
              if (!mounted) return;
              ref.current.removeEventListener(...);
            };
          },
          [ref],
        );
        
        return (
          <proto-date-picker ref={ref} name={formioKey} value={currentValue} />
        );
      }
    • We use React refs & the useEffect hook to bind the relevant events for our own functionality)
    • The goal is to have the webcomponent-level events bubble up to our React components
    • We should be able to pass Javascript objects to the webcomponent itself, which can then use the full formio component options / full view of data to configure itself/re-render itself etc.
  • Check that appropriate re-renders are triggered, e.g. by having a nl/en locale dropdown in the react state, which triggers a state/prop change and should be picked up by the webcomponent (arrange the date part dropdowns from day-month-year to month-day-year, for example,)

Add the Map component to storybook

We currently don't have all formio components hooked up to storybook, which excludes them from visual regression testing.

  1. Add a story for the map component in src/formio/components/Map.stories.mdx
  2. Check the backend form designer for the required JSON for this component
  3. Configure/document the story similarly to the other formio components

Add the Content component to storybook

We currently don't have all formio components hooked up to storybook, which excludes them from visual regression testing.

  1. Add a story for the content component in src/formio/components/Content.stories.mdx
  2. Check the backend form designer for the required JSON for this component ("Vrije tekst")
  3. Configure/document the story similarly to the other formio components

Style multi-value inputs

Multi value inputs are wrapped in a table container, which now looks awful

  • the table styling is sort of okay (browser default)
  • icons/buttons to remove an item should get the appropriate button styling
  • icon/button to add an item should get the appropriate button styling

Styling inconsistencies between own & form.io components

Primarily looking at the e-mail component for this, but it applies to TextField/NumberField too.

  • Font-weight of input box: in the form.io forms these are bolder

    form.io component
    image

    NLDS component
    image

  • invalid styles are missing background color / border on the left

    form.io component
    image

    NLDS component
    image

Check this for all components:

  • Textfield
  • Numberfield
  • Select
  • Async Select
  • Emailfield

Revamp test suite

  • Check which tests can be moved to interaction tests in storybook
  • Rewrite the remaining jest-tests to use testing-library/react rather than the barebones test utilties

There are a lot of act related warnings now since the upgrade to React 18

Standardise code formatting.

On the backend we use black to format. I think standard tries to be the same "no config" approach.

I'm using prettier out of laziness; it also formats css, markdown and html.
But there are others:

Try the following fixers appropriate for the filetype:

'dprint' - Pluggable and configurable code formatting platform
'eslint' - Apply eslint --fix to a file.
'fecs' - Apply fecs format to a file.
'importjs' - automatic imports for javascript
'prettier' - Apply prettier to a file.
'prettier_eslint', 'prettier-eslint' - Apply prettier-eslint to a file.
'prettier_standard', 'prettier-standard' - Apply prettier-standard to a file.
'standard' - Fix JavaScript files using standard --fix
'xo' - Fix JavaScript/TypeScript files using xo --fix.

I have no preference other than consistency.

Progress-indicator header width causes horizontal scroll

Product versie / Product version

Git SHA: 835f4a26e82be4f6509432bc4ae6e3118e0bb93b

Omschrijf het probleem / Describe the bug

The page gets extra whitespace on the right, on mobile view,
this adds an extra horizontal scroll:
Solution: The element openforms-progress-indicator__mobile-header should get max. width: 100%

scroll-x-header

Verwacht gedrag / Expected behavior

All elements in the page should have a maximum width that doesn't overflow. There should be no horizontal scroll.

Screen resolution / Device / OS / Browser

All mobile views, starting from screens below width 765px

Add the file upload component to storybook

We currently don't have all formio components hooked up to storybook, which excludes them from visual regression testing.

  1. Add a story file for the file component in src/formio/components/FileField.stories.mdx
  2. Check the backend form designer for the required JSON for this component
  3. Ensure that a URL is set in component.url and a mock is set up for this endpoint

The following variants should be set up/documented:

  • Happy flow - successful upload
  • Error flow - backend error responds with a HTTP 400 with validation errors

The following controls should be available:

Make OF-prefix configurable through envvar

For better NLDS support

Robbert has a POC of integrating Formio in Storybook and overriding styles with design tokens. Currently the hardcoded prefix sits in the way.

Check React warning

Very likely caused by the logic checking/updates. I've fixed this before where the props change while Formio is still (re)rendering and React doesn't like that.

Warning: unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering
  • Investigate cause and ensure this doesn't happen anymore.

Add focus-styles and design tokens for login-button-logo component

Depends on #313

This will also require some backend changes to include meta-information about the logo (whether it's dark or light).

Tasks

  • Add design tokens of.login-button-logo.dark.focus.border-color and of.login-button-logo.dark.focus.border-color
  • Implement CSS classname modifiers openforms-login-button-logo--{dark|light} depending on backend information (TODO!)
  • Add prop appearance with possible values dark and light to LoginButtonIcon component, which configures the modifier of the component
  • Add CSS styles that connect the classnames/modifiers to the appropriate design token

Adopt typescript

Check if we can start gradual typescript adoption, normally CRA should support it out of the box?

Datefield: next iteration

Epic: open-formulieren/open-forms#2471

This is required for appointments to submit date-of-birth for which a datepicker is quite user-hostile.

Follow up from open-formulieren/open-forms#3060 to make the datepicker more accessible/easier to use

  • Allow arrow key navigation inside calendar (contribute to upstream https://github.com/nl-design-system/utrecht/)
  • Show the selected date in the text field in locale-aware format (nl, en)
  • Allow the user to type in the date in locale aware format
  • Ensure the form field value is normalized to an ISO-8601 string
  • Implement variant without calendar, but instead an input for day/month/year #457

See also nl-design-system/utrecht#1746, nl-design-system/backlog#189 and nl-design-system/backlog#188

Add the fieldset component to storybook

We currently don't have all formio components hooked up to storybook, which excludes them from visual regression testing.

  1. Add a story for the fieldset component in src/formio/components/Fieldset.stories.mdx
  2. Check the backend form designer for the required JSON for this component
  3. Configure/document the story similarly to the other formio components - ensure there are some nested components and the JSON of nested components can be edited in the storybook canvas

Add the "selectboxes" component to storybook

We currently don't have all formio components hooked up to storybook, which excludes them from visual regression testing.

  1. Add a story for the checkboxes component in src/formio/components/Selectboxes.stories.mdx
  2. Check the backend form designer for the required JSON for this component ("Selectievakjes")
  3. Configure/document the story similarly to the other formio components

Multiple-value input doesn't work

How to reproduce:

  • Make a form with a text field where the 'multiple values' checkbox is checked.
  • Start the SDK and begin the form
  • Enter some text in the text field and then click on 'Nog een toevoegen'

This gives the error in the console:
Uncaught TypeError: can't define array index property past the end of an array with non-writable length

CSRF token expiry results in unresponsive form.

As an anonymous Submitter
When I let my Session expire
And I click here
image
And for some reason (time/server things) my CSRF token has become invalid
I do get the first login step
image
But clicking "Start formulier" does not start the submission, nor gives me feedback.

Analysis:
Backend correctly reponds with a 403 the POST:

{
	"type": "http://127.0.0.1:8000/fouten/PermissionDenied/",
	"code": "permission_denied",
	"title": "You do not have permission to perform this action.",
	"status": 403,
	"detail": "CSRF Failed: CSRF token missing or incorrect.",
	"instance": "urn:uuid:45c5dc8b-8240-4f3f-8553-94de91c5e995"
}

because the POST request contained these headers

Cookie: csrftoken=TrPftlIryvbjBGq63oh3Y7CnT0oVVUeeiPGOOS6hYOfND7lvJzQhfY7L3rMIYBkA; cookie_consent="analytical=2021-07-19T12:11:35.633000+00:00"; openforms_language=en; openforms_sessionid=lm1kgzn4k0sck8u8lof0osahlma4tcb1
X-CSRFToken: ksJHbv1k39EhazO9jROF6ZTbyMlPcTE2ss6yMNI6VsVbD7UuXAJJ2flUTMmFO7zu

and these tokens are not the same.

A refresh of the page resolves the issue.

Probably not related to open-formulieren/open-forms#2291

Add Signature component to storybook

We currently don't have all formio components hooked up to storybook, which excludes them from visual regression testing.

  1. Add a story for the signature component in src/formio/components/Signature.stories.mdx
  2. Check the backend form designer for the required JSON for this component
  3. Configure/document the story similarly to the other formio components

Add the co-sign component to storybook

We currently don't have all formio components hooked up to storybook, which excludes them from visual regression testing.

  1. Add a story for the co-sign component in src/formio/components/Cosign.stories.js
  2. Check the backend form designer for the required JSON for this component
  3. Configure/document the story similarly to the other formio components
  4. Set up the/a mock endpoint to be called by the co sign component

This is about the "new" Co sign, we will not be documenting the CoSignOld component.

Explore ViteJS/ESBuild instead of CRA webpack setup?

Together with typescript migration it might be beneficial to overhaul the toolchain

Requirements:

  • yarn start must spin up dev server
  • support sass toolchain
  • support emitting to CSS
  • support bundling to UMD bundle
  • support assets like fonts/images/svgs etc.
  • ... ?

react-select Styling

See #418 (comment)

  • incorporate (relevant) Utrecht component design tokens
  • add values for design tokens in our OF theme
  • refer to our own utility tokens where possible (borders etc.)

Radio group met NL DS geeft onwerkbaar formulieren

Screenshot:
image

De HTML dan de radio button in niet zoals de Utrecht component het verwacht.

Wij verwachten deze output:
https://nl-design-system.github.io/utrecht/storybook/?path=/docs/css-form-field-radio-group--label

Maar wij krijgen onderstaande als HTML output, dit gaat niet goed met CSS van het Utrecht component.
openforms-checkbox en openforms-checkbox__checkmark zijn wat onverwacht.

<div class="openforms-form-choices">
    <div class="openforms-form-choices__choice utrecht-form-field utrecht-form-field--radio">
        <div class="openforms-checkbox">
              <input id="eyxrpxn-persoon" value="persoon" lang="nl" class="openforms-checkbox__input utrecht-radio-button utrecht-radio-button--html-input" type="radio" name="data[bentUEenPersoonOfEenBedrijf][eq8767r-eyxrpxn]" ref="input">
            <div class="openforms-checkbox__checkmark"></div>
                <label for="eyxrpxn-persoon" class="openforms-checkbox__label utrecht-form-label utrecht-form-label--radio">Persoon</label>
        </div>
    </div>
    <div class="openforms-form-choices__choice utrecht-form-field utrecht-form-field--radio">
        <div class="openforms-checkbox">
              <input id="eyxrpxn-bedrijf" value="bedrijf" lang="nl" class="openforms-checkbox__input utrecht-radio-button utrecht-radio-button--html-input" type="radio" name="data[bentUEenPersoonOfEenBedrijf][eq8767r-eyxrpxn]" ref="input">
            <div class="openforms-checkbox__checkmark"></div>
                <label for="eyxrpxn-bedrijf" class="openforms-checkbox__label utrecht-form-label utrecht-form-label--radio">Bedrijf</label>
        </div>
    </div>
</div>

Appointments: implement client-side validation

Epic: open-formulieren/open-forms#2471

Now that we're using Formik, we can/should also implement client-side validation (using zod) for the appointment information. Certain aspects (like at least one product required, minimum amount of product is 1) cannot be properly validated using the form inputs and we should catch those errors before even attempting to submit data to the backend.

  • Add Zod
  • Set up (partial) validation schema's depending on the current form step
    • Set up product step schema
    • Set up location step schema
    • Set up customer fields schema
    • Configure correct schema on <Formik> when navigating back
  • #492
  • Fix Storybook play function tests
  • #493

Prerequisite `style-dictionary` is not mentioned in the SDK (Storybook) documentation...

...but is a requirement.

The only mention of style-dictionary in the documentation is in the configuration section of the backend briefly mentioning it as "advanced usage", I suggest adding to the list next to "NodeJS environment" in the Storybook documentation of the Open Forms SDK.

We use style-dictionary for design tokens, make sure it's installed.

To the storybook documentation of the SDK. Also I think "Prerequisites" is more meaningful than "NodeJS environment" when added to this particular list.

Style/theme form field description properly

Currently, descriptions/help texts are lacking the lightish blue background and the vertical spacing is a bit off.

Tasks

  • Fix color appearances to be consistent with form.io components
  • Check spacing of datefield for consistent padding/margins

Re-enable dynamic loading of i18n modules

The webpack config causes these to be loaded from a relative path to the page where the SDK is embedded, rather than relative to the sdk.js module.

A quick fix right now is to always bundle these files instead of loading them dynamically, but this will make the bundle fatter as we add more translations.

Handle error responses from server properly

Related to a pull request here #44 if a 403 response is returned from the server we only alert the user but do no other error handling.

Ideally we would show at least a better error response and possibly send the user to a proper page.

Fix DOMException related to caret restore function (Formio bug)

DOMException: Failed to execute 'setSelectionRange' on 'HTMLInputElement': The input element's type ('email') does not support selection.

This happens in the Component.restoreCaretPosition method on Formio 4.12. It appears to be fixed in 4.13: https://github.com/formio/formio.js/blob/4.13.x/src/components/_classes/component/Component.js#L1564

This is currently causing the subsequent logic checks to fail (when the element is focused).

Preferred mitigation: upgrade to Formio 4.13, however we have run into other issues while trying that with the file upload mimetypes. Alternative solution is monkey-patching the method, as the Component is base class for a lot of components and simply replacing it with our own subclass will not suffice.

Add the "repeating group" component to storybook

We currently don't have all formio components hooked up to storybook, which excludes them from visual regression testing.

  1. Add a story for the repeating group component in src/formio/components/EditGrid.stories.mdx
  2. Check the backend form designer for the required JSON for this component
  3. Configure/document the story similarly to the other formio components
  4. Ensure that there is a control for the nested configuration
  5. Ensure there are controls for the configurable aspects in the form designer

IBAN validation is triggered even if other fields are edited

Testing with the following configuration:

{
  "display": "form",
  "components": [
    {
      "id": "en1l2p",
      "key": "voornaam",
      "mask": false,
      "type": "textfield",
      "input": true,
      "label": "Voornaam",
      "hidden": false,
      "prefix": "",
      "suffix": "",
      "unique": false,
      "widget": {
        "type": "input"
      },
      "dbIndex": false,
      "overlay": {
        "top": "",
        "left": "",
        "style": "",
        "width": "",
        "height": ""
      },
      "tooltip": "",
      "disabled": false,
      "multiple": false,
      "redrawOn": "",
      "tabindex": "",
      "validate": {
        "custom": "",
        "unique": false,
        "pattern": "",
        "multiple": false,
        "required": true,
        "maxLength": "",
        "minLength": "",
        "customPrivate": false,
        "strictDateValidation": false
      },
      "autofocus": false,
      "encrypted": false,
      "hideLabel": false,
      "inputMask": "",
      "inputType": "text",
      "modalEdit": false,
      "protected": false,
      "refreshOn": "",
      "tableView": true,
      "attributes": {},
      "errorLabel": "",
      "persistent": true,
      "properties": {},
      "spellcheck": true,
      "validateOn": "change",
      "clearOnHide": true,
      "conditional": {
        "eq": "",
        "show": null,
        "when": null
      },
      "customClass": "",
      "description": "Geef je voornaam op",
      "inputFormat": "plain",
      "placeholder": "",
      "defaultValue": null,
      "dataGridLabel": false,
      "labelPosition": "top",
      "showCharCount": false,
      "showWordCount": false,
      "calculateValue": "",
      "calculateServer": false,
      "allowMultipleMasks": false,
      "customDefaultValue": "",
      "allowCalculateOverride": false
    },
    {
      "id": "ezmx8ja",
      "key": "tussenvoegsel",
      "mask": false,
      "type": "textfield",
      "input": true,
      "label": "Tussenvoegsel",
      "hidden": false,
      "prefix": "",
      "suffix": "",
      "unique": false,
      "widget": {
        "type": "input"
      },
      "dbIndex": false,
      "overlay": {
        "top": "",
        "left": "",
        "style": "",
        "width": "",
        "height": ""
      },
      "tooltip": "",
      "disabled": false,
      "multiple": false,
      "redrawOn": "",
      "tabindex": "",
      "validate": {
        "custom": "",
        "unique": false,
        "pattern": "",
        "multiple": false,
        "required": false,
        "maxLength": "",
        "minLength": "",
        "customPrivate": false,
        "strictDateValidation": false
      },
      "autofocus": false,
      "encrypted": false,
      "hideLabel": false,
      "inputMask": "",
      "inputType": "text",
      "modalEdit": false,
      "protected": false,
      "refreshOn": "",
      "tableView": true,
      "attributes": {},
      "errorLabel": "",
      "persistent": true,
      "properties": {},
      "spellcheck": true,
      "validateOn": "change",
      "clearOnHide": true,
      "conditional": {
        "eq": "",
        "show": null,
        "when": null
      },
      "customClass": "",
      "description": "",
      "inputFormat": "plain",
      "placeholder": "",
      "defaultValue": null,
      "dataGridLabel": false,
      "labelPosition": "top",
      "showCharCount": false,
      "showWordCount": false,
      "calculateValue": "",
      "calculateServer": false,
      "allowMultipleMasks": false,
      "customDefaultValue": "",
      "allowCalculateOverride": false
    },
    {
      "id": "eyq2zns",
      "key": "achternaam",
      "mask": false,
      "type": "textfield",
      "input": true,
      "label": "Achternaam",
      "hidden": false,
      "prefix": "",
      "suffix": "",
      "unique": false,
      "widget": {
        "type": "input"
      },
      "dbIndex": false,
      "overlay": {
        "top": "",
        "left": "",
        "style": "",
        "width": "",
        "height": ""
      },
      "tooltip": "",
      "disabled": false,
      "multiple": false,
      "redrawOn": "",
      "tabindex": "",
      "validate": {
        "custom": "",
        "unique": false,
        "pattern": "",
        "multiple": false,
        "required": false,
        "maxLength": "",
        "minLength": "",
        "customPrivate": false,
        "strictDateValidation": false
      },
      "autofocus": false,
      "encrypted": false,
      "hideLabel": false,
      "inputMask": "",
      "inputType": "text",
      "modalEdit": false,
      "protected": false,
      "refreshOn": "",
      "tableView": true,
      "attributes": {},
      "errorLabel": "",
      "persistent": true,
      "properties": {},
      "spellcheck": true,
      "validateOn": "change",
      "clearOnHide": true,
      "conditional": {
        "eq": "",
        "show": null,
        "when": null
      },
      "customClass": "",
      "description": "",
      "inputFormat": "plain",
      "placeholder": "",
      "defaultValue": null,
      "dataGridLabel": false,
      "labelPosition": "top",
      "showCharCount": false,
      "showWordCount": false,
      "calculateValue": "",
      "calculateServer": false,
      "allowMultipleMasks": false,
      "customDefaultValue": "",
      "allowCalculateOverride": false
    },
    {
      "id": "ehm8k1",
      "key": "email",
      "mask": false,
      "type": "email",
      "input": true,
      "label": "Email",
      "hidden": false,
      "prefix": "",
      "suffix": "",
      "unique": false,
      "widget": {
        "type": "input"
      },
      "dbIndex": false,
      "kickbox": {
        "enabled": false
      },
      "overlay": {
        "top": "",
        "left": "",
        "style": "",
        "width": "",
        "height": ""
      },
      "tooltip": "",
      "disabled": false,
      "multiple": false,
      "redrawOn": "",
      "tabindex": "",
      "validate": {
        "custom": "",
        "unique": false,
        "pattern": "",
        "multiple": false,
        "required": false,
        "maxLength": "",
        "minLength": "",
        "customPrivate": false,
        "strictDateValidation": false
      },
      "autofocus": false,
      "encrypted": false,
      "hideLabel": false,
      "inputMask": "",
      "inputType": "email",
      "modalEdit": false,
      "protected": false,
      "refreshOn": "",
      "tableView": true,
      "attributes": {},
      "errorLabel": "",
      "persistent": true,
      "properties": {},
      "spellcheck": true,
      "validateOn": "change",
      "clearOnHide": true,
      "conditional": {
        "eq": "",
        "show": null,
        "when": null
      },
      "customClass": "",
      "description": "",
      "inputFormat": "plain",
      "placeholder": "",
      "showInEmail": false,
      "defaultValue": null,
      "dataGridLabel": false,
      "labelPosition": "top",
      "showCharCount": false,
      "showWordCount": false,
      "calculateValue": "",
      "calculateServer": false,
      "allowMultipleMasks": false,
      "customDefaultValue": "",
      "allowCalculateOverride": false
    },
    {
      "id": "encqyof",
      "key": "iban",
      "mask": false,
      "type": "iban",
      "input": true,
      "label": "Rekeningnummer",
      "hidden": false,
      "prefix": "",
      "suffix": "",
      "unique": false,
      "widget": {
        "type": "input"
      },
      "dbIndex": false,
      "overlay": {
        "top": "",
        "left": "",
        "style": "",
        "width": "",
        "height": ""
      },
      "tooltip": "",
      "disabled": false,
      "multiple": false,
      "redrawOn": "",
      "tabindex": "",
      "validate": {
        "custom": true,
        "unique": false,
        "pattern": "",
        "multiple": false,
        "required": false,
        "maxLength": "",
        "minLength": "",
        "customPrivate": false,
        "strictDateValidation": false
      },
      "autofocus": false,
      "encrypted": false,
      "hideLabel": false,
      "inputMask": "",
      "inputType": "text",
      "modalEdit": false,
      "protected": false,
      "refreshOn": "",
      "tableView": true,
      "attributes": {},
      "errorLabel": "",
      "persistent": true,
      "properties": {},
      "spellcheck": true,
      "validateOn": "change",
      "clearOnHide": true,
      "conditional": {
        "eq": "",
        "show": null,
        "when": null
      },
      "customClass": "",
      "description": "",
      "inputFormat": "plain",
      "placeholder": "",
      "defaultValue": null,
      "dataGridLabel": false,
      "labelPosition": "top",
      "showCharCount": false,
      "showWordCount": false,
      "calculateValue": "",
      "calculateServer": false,
      "allowMultipleMasks": false,
      "customDefaultValue": "",
      "allowCalculateOverride": false
    },
    {
      "id": "euqhli",
      "key": "amount",
      "type": "number",
      "input": true,
      "label": "Amount",
      "hidden": false,
      "prefix": "",
      "suffix": "",
      "unique": false,
      "widget": {
        "type": "input"
      },
      "dbIndex": false,
      "overlay": {
        "top": "",
        "left": "",
        "style": "",
        "width": "",
        "height": ""
      },
      "tooltip": "",
      "disabled": false,
      "multiple": false,
      "redrawOn": "",
      "tabindex": "",
      "validate": {
        "max": "",
        "min": "",
        "step": "any",
        "custom": "",
        "unique": false,
        "integer": "",
        "multiple": false,
        "required": false,
        "customPrivate": false,
        "strictDateValidation": false
      },
      "autofocus": false,
      "encrypted": false,
      "hideLabel": false,
      "modalEdit": false,
      "protected": false,
      "refreshOn": "",
      "tableView": false,
      "attributes": {},
      "errorLabel": "",
      "persistent": true,
      "properties": {},
      "validateOn": "change",
      "clearOnHide": true,
      "conditional": {
        "eq": "",
        "show": null,
        "when": null
      },
      "customClass": "",
      "description": "",
      "placeholder": "",
      "showInEmail": false,
      "defaultValue": null,
      "dataGridLabel": false,
      "labelPosition": "top",
      "showCharCount": false,
      "showWordCount": false,
      "calculateValue": "",
      "calculateServer": false,
      "allowMultipleMasks": false,
      "customDefaultValue": "",
      "allowCalculateOverride": false
    },
    {
      "id": "elt1rlp",
      "key": "extras",
      "type": "selectboxes",
      "input": true,
      "label": "Extra's",
      "hidden": false,
      "inline": false,
      "prefix": "",
      "suffix": "",
      "unique": false,
      "values": [
        {
          "label": "Melk",
          "value": "melk"
        },
        {
          "label": "Suiker",
          "value": "suiker"
        },
        {
          "label": "Nog meer suiker",
          "value": "nogMeerSuiker"
        }
      ],
      "widget": null,
      "dbIndex": false,
      "overlay": {
        "top": "",
        "left": "",
        "style": "",
        "width": "",
        "height": ""
      },
      "tooltip": "",
      "disabled": false,
      "fieldSet": false,
      "multiple": false,
      "redrawOn": "",
      "tabindex": "",
      "validate": {
        "custom": "",
        "unique": false,
        "multiple": false,
        "required": false,
        "customPrivate": false,
        "strictDateValidation": false
      },
      "autofocus": false,
      "encrypted": false,
      "hideLabel": false,
      "inputType": "checkbox",
      "modalEdit": false,
      "protected": false,
      "refreshOn": "",
      "tableView": false,
      "attributes": {},
      "errorLabel": "",
      "persistent": true,
      "properties": {},
      "validateOn": "change",
      "clearOnHide": true,
      "conditional": {
        "eq": "",
        "show": null,
        "when": null
      },
      "customClass": "",
      "description": "",
      "placeholder": "",
      "defaultValue": null,
      "dataGridLabel": false,
      "labelPosition": "top",
      "showCharCount": false,
      "showWordCount": false,
      "calculateValue": "",
      "calculateServer": false,
      "allowMultipleMasks": false,
      "customDefaultValue": "",
      "allowCalculateOverride": false
    },
    {
      "id": "e0qy7er",
      "key": "keuze",
      "data": {
        "url": "",
        "json": "",
        "custom": "",
        "values": [
          {
            "label": "Optie 1",
            "value": "optie1"
          },
          {
            "label": "Optie 2",
            "value": "optie2"
          }
        ],
        "resource": ""
      },
      "type": "select",
      "input": true,
      "label": "Keuze",
      "limit": 100,
      "filter": "",
      "hidden": false,
      "idPath": "id",
      "prefix": "",
      "suffix": "",
      "unique": false,
      "widget": null,
      "dataSrc": "values",
      "dbIndex": false,
      "overlay": {
        "top": "",
        "left": "",
        "style": "",
        "width": "",
        "height": ""
      },
      "tooltip": "",
      "disabled": false,
      "lazyLoad": true,
      "multiple": false,
      "redrawOn": "",
      "tabindex": "",
      "template": "<span>{{ item.label }}</span>",
      "validate": {
        "custom": "",
        "unique": false,
        "multiple": false,
        "required": false,
        "customPrivate": false,
        "strictDateValidation": false
      },
      "autofocus": false,
      "encrypted": false,
      "hideLabel": false,
      "minSearch": 0,
      "modalEdit": false,
      "protected": false,
      "refreshOn": "",
      "tableView": true,
      "attributes": {},
      "errorLabel": "",
      "persistent": true,
      "properties": {},
      "validateOn": "change",
      "clearOnHide": true,
      "conditional": {
        "eq": "",
        "show": null,
        "when": null
      },
      "customClass": "",
      "description": "",
      "fuseOptions": {
        "include": "score",
        "threshold": 0.3
      },
      "ignoreCache": false,
      "placeholder": "",
      "searchField": "",
      "authenticate": false,
      "defaultValue": null,
      "selectFields": "",
      "customOptions": {},
      "dataGridLabel": false,
      "labelPosition": "top",
      "readOnlyValue": false,
      "searchEnabled": true,
      "showCharCount": false,
      "showWordCount": false,
      "uniqueOptions": false,
      "valueProperty": "",
      "calculateValue": "",
      "clearOnRefresh": false,
      "useExactSearch": false,
      "calculateServer": false,
      "searchThreshold": 0.3,
      "allowMultipleMasks": false,
      "customDefaultValue": "",
      "allowCalculateOverride": false
    }
  ]
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.