From 1acf242600e4476a32cb56477db324a02f3c968b Mon Sep 17 00:00:00 2001 From: ashit-rath Date: Fri, 22 Apr 2022 17:20:51 +0530 Subject: [PATCH] feat: JSONFrom add isValid form level property to represent overall form validity (#13083) --- .../JSONForm_FormProperties_spec.js | 20 +++++++++++++++++++ .../utils/autocomplete/EntityDefinitions.ts | 1 + .../widgets/JSONFormWidget/component/Form.tsx | 6 ++++++ .../JSONFormWidget/component/index.tsx | 5 ++++- .../widgets/JSONFormWidget/widget/index.tsx | 5 +++++ 5 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormProperties_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormProperties_spec.js index 4dbddc35d9..6c51c201d7 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormProperties_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/FormWidgets/JSONFormWidget/JSONForm_FormProperties_spec.js @@ -1,5 +1,6 @@ const commonlocators = require("../../../../../locators/commonlocators.json"); const dslWithSchema = require("../../../../../fixtures/jsonFormDslWithSchema.json"); +const widgetsPage = require("../../../../../locators/Widgets.json"); const backBtn = ".t--property-pane-back-btn"; const fieldPrefix = ".t--jsonformfield"; @@ -67,4 +68,23 @@ describe("JSON Form Widget Form Bindings", () => { .parent("button") .should("not.have.attr", "disabled"); }); + + it("Should set isValid to false when form is invalid", () => { + cy.openPropertyPane("textwidget"); + cy.testJsontext("text", "{{JSONForm1.isValid}}"); + + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).contains("true"); + + cy.get(`${fieldPrefix}-name input`) + .clear() + .wait(300); + + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).contains("false"); + + cy.get(`${fieldPrefix}-name input`) + .type("JOHN") + .wait(300); + + cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).contains("true"); + }); }); diff --git a/app/client/src/utils/autocomplete/EntityDefinitions.ts b/app/client/src/utils/autocomplete/EntityDefinitions.ts index 1000ab273b..a7dc81e2f2 100644 --- a/app/client/src/utils/autocomplete/EntityDefinitions.ts +++ b/app/client/src/utils/autocomplete/EntityDefinitions.ts @@ -571,6 +571,7 @@ export const entityDefinitions: Record = { formData: generateTypeDef(widget.formData), sourceData: generateTypeDef(widget.sourceData), fieldState: generateTypeDef(widget.fieldState), + isValid: "bool", }), PROGRESS_WIDGET: { "!doc": diff --git a/app/client/src/widgets/JSONFormWidget/component/Form.tsx b/app/client/src/widgets/JSONFormWidget/component/Form.tsx index 5f664a75bd..956e37a677 100644 --- a/app/client/src/widgets/JSONFormWidget/component/Form.tsx +++ b/app/client/src/widgets/JSONFormWidget/component/Form.tsx @@ -24,6 +24,7 @@ export type FormProps = PropsWithChildren<{ getFormData: () => TValues; hideFooter: boolean; isSubmitting: boolean; + onFormValidityUpdate: (isValid: boolean) => void; onSubmit: (event: React.MouseEvent) => void; registerResetObserver: (callback: () => void) => void; resetButtonLabel: string; @@ -124,6 +125,7 @@ function Form({ getFormData, hideFooter, isSubmitting, + onFormValidityUpdate, onSubmit, registerResetObserver, resetButtonLabel, @@ -231,6 +233,10 @@ function Form({ } }, [scrollContents]); + useEffect(() => { + onFormValidityUpdate(!isFormInValid); + }, [onFormValidityUpdate, isFormInValid]); + return ( diff --git a/app/client/src/widgets/JSONFormWidget/component/index.tsx b/app/client/src/widgets/JSONFormWidget/component/index.tsx index 4186069448..22b9d5f092 100644 --- a/app/client/src/widgets/JSONFormWidget/component/index.tsx +++ b/app/client/src/widgets/JSONFormWidget/component/index.tsx @@ -35,14 +35,15 @@ export type JSONFormComponentProps = { executeAction: (actionPayload: ExecuteTriggerPayload) => void; fieldLimitExceeded: boolean; fixedFooter: boolean; + getFormData: () => TValues; isSubmitting: boolean; + onFormValidityUpdate: (isValid: boolean) => void; onSubmit: (event: React.MouseEvent) => void; registerResetObserver: (callback: () => void) => void; renderMode: RenderMode; resetButtonLabel: string; resetButtonStyles: ButtonStyleProps; schema: Schema; - getFormData: () => TValues; scrollContents: boolean; submitButtonLabel: string; unregisterResetObserver: () => void; @@ -94,6 +95,7 @@ function JSONFormComponent({ fieldLimitExceeded, getFormData, isSubmitting, + onFormValidityUpdate, registerResetObserver, renderMode, resetButtonLabel, @@ -173,6 +175,7 @@ function JSONFormComponent({ getFormData={getFormData} hideFooter={hideFooter} isSubmitting={isSubmitting} + onFormValidityUpdate={onFormValidityUpdate} onSubmit={rest.onSubmit} registerResetObserver={registerResetObserver} resetButtonLabel={resetButtonLabel} diff --git a/app/client/src/widgets/JSONFormWidget/widget/index.tsx b/app/client/src/widgets/JSONFormWidget/widget/index.tsx index b1b4ee44ed..55d560b715 100644 --- a/app/client/src/widgets/JSONFormWidget/widget/index.tsx +++ b/app/client/src/widgets/JSONFormWidget/widget/index.tsx @@ -285,6 +285,10 @@ class JSONFormWidget extends BaseWidget< getFormData = () => this.props.formData; + onFormValidityUpdate = (isValid: boolean) => { + this.props.updateWidgetMetaProperty("isValid", isValid); + }; + getPageView() { return ( // Warning!!! Do not ever introduce formData as a prop directly, @@ -303,6 +307,7 @@ class JSONFormWidget extends BaseWidget< fixedFooter={this.props.fixedFooter} getFormData={this.getFormData} isSubmitting={this.state.isSubmitting} + onFormValidityUpdate={this.onFormValidityUpdate} onSubmit={this.onSubmit} registerResetObserver={this.registerResetObserver} renderMode={this.props.renderMode}