cicil-forms

0.2.7 • Public • Published

Welcome to generic form component

This is a form component widget that can be used to create simple and moderately complex forms as per the carbon design standards

[Live codesandbox demo]: https://codesandbox.io/s/cicil-forms-example-sjclkm

[NPM package]: https://www.npmjs.com/package/cicil-forms

Usage

<Form
  id={<String id here>}
  elements={<Array of individual form fields>}
  sectionName={<Name of form section>}
  formData={<Object (key-value) of final form values>}
  updateFormData={<function where we get the form field changes}
  isEditMode={<Boolean that specifies whether form is in edit mode or new mode>}
></Form>

Props reference

The component takes the following props.

Prop Type Description
id String This is unique string id, important for differentiation between multiple FormComponent invoked in a single view
elements Array Form fields array structure
formData Object key-value pairs, note: the key names should match the indivisual form field key: name
updateFormData Function This is a debounced function that is called when ever user changes any data in any of the form field
isEditMode Boolean This is a boolean, if true, it will take the formData and prefill the form fields for all non-empty keys in formData, which will make the form work as editing mode, if false then new empty form will be presented to the user
sectionName String This is a boolean, if true, it will take the formData and prefill the form fields for all non-empty keys in formData, which will make the form work as editing mode, if false then new empty form will be presented to the user

Form fields array structure ( JSON Schema ) [ TODO ]

Common fields
export interface FormField {
widgetLabel: string
/**
 * TextInput | Select | TextArea | RadioButtonGroup | CheckboxGroup | ComboBox | MultiSelect | Checkbox | DatePicker | NumberInput
 */
widgetType: string
/**
 * This key: name will be
 * used to create form payload
 * e.g if named: 'age', the formData becomes { age: 'value' }
 */
name: string
/**
 * This key dictates whether to show
 * the position of the field. eg left colum or right column
 * Left column - 1
 * Right column - 2
 * Top column - 0
 * Common (across both columns) - 3
 * Top right column - 4
 */
columnNum?: number

/**
 * if `true` then loader is added to the field
 */
loading?: boolean

/**
 * if `true` then triggers the
 * error styling and applies the invalidText, requiredValidationMessage keys
 */
invalid?: boolean
/**
 * Max number of characters which can be entered
 */
maxLength?: number
/**
 * if `true` then this field is visible on the form/screen,
 * if `false` then the this particular field is no more
 * visible in the form
 */
visible?: boolean
/**
 * if `true` then this field becomes compulsory field,
 * else is treated as optional fields
 */
required?: boolean
/**
 * if the field is a required: true field
 * and no data is entered then this message is
 * displayed to the user
 */
requiredValidationMessage?: string
/**
 * This message will be displayed to user if entered
 * data does not match/satisfy the validation
 * rules declared for this field
 */
invalidText?: string
 /**
 * if `true` then this field is shown in Preview,
 * else it is not shown
 */
showInPreview?: boolean
/**
 * If `true`, when onBlur event is called where field has
 * some value entered that satisfies the validation rules,
 * then func: `apiValidateFunc` is called to
 * validate the data by executing the function
 */
shouldValidateByApi?: boolean
/**
 * If `true`, when form is rendered on screen
 * the func: `prefecthFunc` if called where
 * we cann put initial data loading logic,
 * e.g. loading states, countries, timezones etc...
 */
shouldPrefetch?: boolean
/**
 * If `true`, when form is rendered in edit mode,
 * where the value for this field is prefilled,
 * then the user is no more allowed to change
 * the value of this field
 */

preFetchPayloadKeys?: Array 
/**
 * Takes an array of keys as input and returns an array of
 * objects by getting the value of these keys from the existing 
 * payload, This is then passed as the payload to the prefetch function.
 */

disableOnEdit?: boolean
/**
 * If `true`, then this field will be disabled,
 * and user can no more change the data in this field
 */
disabled?: boolean,
  /**
 * If set of Label/checkbox to `true`, it allows to load html tags in the labels
 */
setLabelWithFormatting?: boolean
/**
 * If `true`, then onload of the form, it runs the APIVAlidateFunc for this field
 */
runApiValidateFuncByDefault?: true,
/**
 * If `shouldValidateByApi` is `true`, then this function
 * is executed, note: we can use this.keyNameOfThisField
 * to mutate any property of this field like clearing off
 * the loaders etc... and at the end we need to return 
 * 
 * return Promise.resolve(this);
 * 
 * OR 
 * 
 * this.responseError = error
 return Promise.resolve(this);
 */
apiValidateFunc?: async () => {},
/**
 * If `shouldPrefetch` is `true`, then this function
 * is executed, note: we can use this.keyNameOfThisField
 * to mutate any property of this field like clearing off
 * the loaders etc... and at the end we need to return 
 * 
 * return Promise.resolve(this);
 * 
 * OR 
 * 
 * this.responseError = error
return Promise.resolve(this);
 */
prefetchFunc?: async () => {},
/**
 * If `true`, all the fields mentioned in dependentFields would be 
 * updated ( action is updateValue), prefetchFunc func would be called
 * if action is prefetchValue.
 */
 runDependentFields?: boolean,
  /**
 * define all the fields that need to be updated/prefetched.
 * eg - { fieldName: "CompanyName", action: "updateValue" },
 *        { fieldName: "FirstName", action: "prefetchFunc" },
 */
 dependentField?s: JSON Array,
 /**
 * set the response from API in prefetch, so that it can
 * be used to set back to the payload
 */

 response?: JSON,
  /**
 * In case of errors, we can set the responseError option
 */
responseError?: String,
/**
 * If `true`, the response values would be updated on the payload
 */
this.updatePayload?: true,
 /**
 * If this is set, the passed in values are set on paylaod
 * { State: selectedState, StateCode: "" };
 */
 this.multiKeyValueResponse?: JSON,
 /**
 * If `true`, `i` icon will be shown after label,
 * where if hovered `tooltipHelpText` will be
 * displayed
 */
tooltip?: false,
/**
 * Set the tooltip text that needs to be shown 
 */
tooltipHelpText?: string,
/**
 * Set the tooltip text that needs to be shown 
 */

  						
}
TextInput
 {
      widgetLabel: "Address line2",
      widgetType: "TextInput",
      name: "AddressLine2",
      columnNum: 1,
      maxLength: 100,
      required: false,
      visible: true,
      requiredValidationMessage: "form.RequiredValidationMessage"
  },
Select
  {
  widgetLabel: "Country or origin",
  widgetType: "Select",
  name: "Country",
  options: [],
  initialSelectedItem: {
      value: "US",
      text: "US"
  },
  columnNum: 2,
  dependentFields: [
      { fieldName: "State", action: "prefetchValue, updateValue" }
      //	{ fieldName: "StateCode", action: "prefetchValue, updateValue" }
  ],
  async prefetchFunc(ccode = "US") {
      let payload = {};
      if (!ccode || ccode === "") {
          ccode = "US";
      }
      try {
          let response = await axiosWithTokenRefresh("get", {
              url: `${endpoints.GET_COUNTRIES_LIST}/${ccode}`,
              payload
          });
          if (response.data.status === 200) {
              this.options = response.data.Countries;
              this.options.forEach((opt) => {
                  if (opt.value === ccode) {
                      this.selectedItem = opt;
                  }
              });
              this.loading = false;
              this.invalid = false;
              this.response = response;
              this.runDependentFields = true;
              this.shouldPrefetch = false;
          }
          return Promise.resolve(this);
      } catch (error) {
          this.loading = false;
          this.invalid = true;
          this.invalidText = "Failed to load countries, refresh and try again!";
          this.responseError = error?.response.data.message || error.toString();
          return Promise.resolve(this);
      }
  }
TextArea
  {
      widgetLabel: "Decline invitation",
      widgetType: "TextArea",
      name: "declineInvitationMsg",
      columnNum: 3,
      step: 0,
      invalid: false,
      maxLength: 128,
      visible: true,
      required: false,
      requiredValidationMessage: "Enter a valid message to send to the administrator",
      invalidText: "Email a valid message to send to the administrator",
      shouldValidateByApi: false,
      shouldPrefetch: true,
      disableOnEdit: false,
      replacementText: "",
      tabIndex: 1,
      async apiValidateFunc() {},
      async prefetchFunc(value, initialDepSelection, inputpayload) {
          this.replacementText = inputpayload?.EmailAddress;
          this.shouldPrefetch = false;
          return Promise.resolve(this);
      }
  },
  
RadioButtonGroup
  TODO
CheckBoxGroup
  {
  			widgetType: "CheckboxGroup",
  			widgetLabel: "Please select all that apply regarding the prospect’s business:",
  			name: "checkboxOptions",
  			useLabel: true,
  			label: "Please select all that apply regarding the prospect’s business:",
  			columnNum: 1,
  			visible: true,
  			required: true,
  			options: [
  				{
  					text: "Telecommunications",
  					name: "Telecommunications",
  					checked: false
  				},
  				{
  					text: "Internet Service Provider(ISP)",
  					name: "InternetServiceProvider",
  					checked: false
  				},
ComboBox
{
      widgetLabel: "Charge agreement number",
      widgetType: "ComboBo",
      name: "ChargeAgreementNum",
      columnNum: 2,
      required: true,
      visible: true,
      maxLength: 10,
      options: [],
      selectedItem: {
          text:"Please select", value:"select"
      }
}
  		
MultiSelect
  TODO
Checkbox
{
      widgetLabel:
          "I have received confirmation from the client that they have agreed to IBM Security Randori Trial Terms for an ASR",
      widgetType: "Checkbox",
      useLabel: true,
      name: "CustomerAuthorizedASR",
      setLabelWithFormatting: true,
      columnNum: 3,
      invalid: false,
      required: true,
      requiredValidationMessage: "Select the checkbox",
      invalidText: "Select the checkbox",
  },
DatePicker
  {
      widgetLabel: "Beta End Date",
      widgetType: "DatePicker",
      invalid: false,
      name: "betaEndDate",
      columnNum: 2,
      tooltip: true,
      tooltipHelpText: "form.betaEndDateHelp",  
  }
NumberInput
{
          widgetLabel: "Quantity",
          widgetType: "NumberInput",
          name: "Quantity",
          maxLength: 128,
          required: true,
          hideLabel: true,
          invalidText: "",
          shouldValidateByApi: false,
          shouldPrefetch: false,
          min: 0,
          max: 2147483647,
          initialValue: 1,
          async apiValidateFunc() {}
      },
Label
 {
  			widgetLabel: "Label",
  			//useLabel: true,
  			widgetType: "Label",
  			name: "formDetails",
  			setLabelWithFormatting: true,
  			columnNum: 3,
  			step: 0,
  			value:
  				"Per the changes in the <a target='_blank' href=''>ASR process</a>,  this form discloses how Randori collects and maintains data in the cloud for up to 30-days.",
  			async prefetchFunc() {},
  			async apiValidateFunc() {}
  		},

Package Sidebar

Install

npm i cicil-forms

Weekly Downloads

1

Version

0.2.7

License

none

Unpacked Size

314 kB

Total Files

5

Last publish

Collaborators

  • omkar.ajagunde.ibm