mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
[ADF-4441] Save button should be disabled when form fields are invalid (#4817)
* [ADF-4441] Save button should be disabled when form inputs are invalid, Refactored disable custom outcome buttons unit tests * [ADF-4441] add missing space * [ADF-4441] Refactor failing unit tests * [ADF-4441] Added documentation for disableSaveButton property
This commit is contained in:
parent
3e1092d7bf
commit
4ea656e537
docs
process-services-cloud/components
process-services/components
lib
core/form/components
process-services-cloud/src/lib/form/components
process-services/form
@ -78,6 +78,7 @@ The template defined inside `empty-form` will be shown when no form definition i
|
||||
| appName | `string` | | App id to fetch corresponding form and values. |
|
||||
| data | [`TaskVariableCloud`](../../../lib/process-services-cloud/src/lib/form/models/task-variable-cloud.model.ts)`[]` | | Custom form values map to be used with the rendered form. |
|
||||
| disableCompleteButton | `boolean` | false | If true then the `Complete` outcome button is shown but it will be disabled. |
|
||||
| disableSaveButton | `boolean` | false | If true then the `Save` outcome button is shown but it will be disabled. |
|
||||
| disableStartProcessButton | `boolean` | false | If true then the `Start Process` outcome button is shown but it will be disabled. |
|
||||
| fieldValidators | [`FormFieldValidator`](../../../lib/core/form/components/widgets/core/form-field-validator.ts)`[]` | \[] | Contains a list of form field validator instances. |
|
||||
| form | [`FormCloud`](../../../lib/process-services-cloud/src/lib/form/models/form-cloud.model.ts) | | Underlying [form model](../../../lib/core/form/components/widgets/core/form.model.ts) instance. |
|
||||
|
@ -56,6 +56,7 @@ Any content in the body of `<adf-form>` will be shown when no form definition is
|
||||
| ---- | ---- | ------------- | ----------- |
|
||||
| data | [`FormValues`](../../../lib/core/form/components/widgets/core/form-values.ts) | | Custom form values map to be used with the rendered form. |
|
||||
| disableCompleteButton | `boolean` | false | If true then the `Complete` outcome button is shown but it will be disabled. |
|
||||
| disableSaveButton | `boolean` | false | If true then the `Save` outcome button is shown but it will be disabled. |
|
||||
| disableStartProcessButton | `boolean` | false | If true then the `Start Process` outcome button is shown but it will be disabled. |
|
||||
| fieldValidators | [`FormFieldValidator`](../../../lib/core/form/components/widgets/core/form-field-validator.ts)`[]` | \[] | Contains a list of form field validator instances. |
|
||||
| form | [`FormModel`](../../../lib/core/form/components/widgets/core/form.model.ts) | | Underlying [form model](../../../lib/core/form/components/widgets/core/form.model.ts) instance. |
|
||||
|
@ -48,6 +48,10 @@ export abstract class FormBaseComponent {
|
||||
@Input()
|
||||
disableCompleteButton: boolean = false;
|
||||
|
||||
/** If true then the `Save` outcome button is shown but it will be disabled. */
|
||||
@Input()
|
||||
disableSaveButton: boolean = false;
|
||||
|
||||
/** If true then the `Start Process` outcome button is shown but it will be disabled. */
|
||||
@Input()
|
||||
disableStartProcessButton: boolean = false;
|
||||
@ -116,9 +120,8 @@ export abstract class FormBaseComponent {
|
||||
}
|
||||
|
||||
if (outcome) {
|
||||
// Make 'Save' button always available
|
||||
if (outcome.name === FormOutcomeModel.SAVE_ACTION) {
|
||||
return true;
|
||||
return this.disableSaveButton ? false : this.form.isValid;
|
||||
}
|
||||
if (outcome.name === FormOutcomeModel.COMPLETE_ACTION) {
|
||||
return this.disableCompleteButton ? false : this.form.isValid;
|
||||
|
@ -689,25 +689,48 @@ describe('FormCloudComponent', () => {
|
||||
});
|
||||
|
||||
it('should disable complete outcome button when disableCompleteButton is true', () => {
|
||||
const formModel = new FormCloud();
|
||||
const formModel = new FormCloud(cloudFormMock);
|
||||
formComponent.form = formModel;
|
||||
formComponent.disableCompleteButton = true;
|
||||
|
||||
expect(formModel.isValid).toBeTruthy();
|
||||
expect(formComponent.form.hasOutcomes()).toBe(true);
|
||||
const completeOutcome = formComponent.form.outcomes.find((outcome) => outcome.name === FormOutcomeModel.COMPLETE_ACTION);
|
||||
|
||||
expect(formComponent.isOutcomeButtonEnabled(completeOutcome)).toBeFalsy();
|
||||
|
||||
formComponent.disableCompleteButton = false;
|
||||
expect(formComponent.isOutcomeButtonEnabled(completeOutcome)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should disable save outcome button when disableSaveButton is true', () => {
|
||||
const formModel = new FormCloud(cloudFormMock);
|
||||
formComponent.form = formModel;
|
||||
formComponent.disableSaveButton = true;
|
||||
|
||||
expect(formModel.isValid).toBeTruthy();
|
||||
expect(formComponent.form.hasOutcomes()).toBe(true);
|
||||
const saveOutcome = formComponent.form.outcomes.find((outcome) => outcome.name === FormOutcomeModel.SAVE_ACTION);
|
||||
|
||||
expect(formComponent.isOutcomeButtonEnabled(saveOutcome)).toBeFalsy();
|
||||
|
||||
formComponent.disableSaveButton = false;
|
||||
expect(formComponent.isOutcomeButtonEnabled(saveOutcome)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should disable start process outcome button when disableStartProcessButton is true', () => {
|
||||
const formModel = new FormCloud();
|
||||
const formModel = new FormCloud(cloudFormMock);
|
||||
formComponent.form = formModel;
|
||||
formComponent.disableStartProcessButton = true;
|
||||
|
||||
expect(formModel.isValid).toBeTruthy();
|
||||
expect(formComponent.form.hasOutcomes()).toBe(true);
|
||||
const startProcessOutcome = formComponent.form.outcomes.find((outcome) => outcome.name === FormOutcomeModel.START_PROCESS_ACTION);
|
||||
|
||||
expect(formComponent.isOutcomeButtonEnabled(startProcessOutcome)).toBeFalsy();
|
||||
|
||||
formComponent.disableStartProcessButton = false;
|
||||
expect(formComponent.isOutcomeButtonEnabled(startProcessOutcome)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should raise [executeOutcome] event for formService', (done) => {
|
||||
|
@ -586,7 +586,7 @@ describe('FormComponent', () => {
|
||||
expect(formService.completeTaskForm).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should complete form form and raise corresponding event', () => {
|
||||
it('should complete form and raise corresponding event', () => {
|
||||
spyOn(formService, 'completeTaskForm').and.callFake(() => {
|
||||
return new Observable((observer) => {
|
||||
observer.next();
|
||||
@ -709,7 +709,7 @@ describe('FormComponent', () => {
|
||||
expect(formComponent.data).toBe(metadata);
|
||||
});
|
||||
|
||||
it('should disable outcome buttons for readonly form', () => {
|
||||
it('should disable custom outcome buttons for readonly form', () => {
|
||||
const formModel = new FormModel();
|
||||
formModel.readOnly = true;
|
||||
formComponent.form = formModel;
|
||||
@ -727,31 +727,6 @@ describe('FormComponent', () => {
|
||||
expect(formComponent.isOutcomeButtonEnabled(null)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should always enable save outcome for writeable form', () => {
|
||||
const formModel = new FormModel();
|
||||
|
||||
const field = new FormFieldModel(formModel, {
|
||||
type: 'text',
|
||||
value: null,
|
||||
required: true
|
||||
});
|
||||
|
||||
const containerModel = new ContainerModel(field);
|
||||
formModel.fields.push(containerModel);
|
||||
formComponent.form = formModel;
|
||||
formModel.onFormFieldChanged(field);
|
||||
|
||||
expect(formModel.isValid).toBeFalsy();
|
||||
|
||||
const outcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: FormComponent.SAVE_OUTCOME_ID,
|
||||
name: FormOutcomeModel.SAVE_ACTION
|
||||
});
|
||||
|
||||
formComponent.readOnly = true;
|
||||
expect(formComponent.isOutcomeButtonEnabled(outcome)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should disable outcome buttons for invalid form', () => {
|
||||
const formModel = new FormModel();
|
||||
const field = new FormFieldModel(formModel, {
|
||||
@ -780,19 +755,139 @@ describe('FormComponent', () => {
|
||||
formComponent.form = formModel;
|
||||
formComponent.disableCompleteButton = true;
|
||||
|
||||
const field = new FormFieldModel(formModel, {
|
||||
type: 'text',
|
||||
value: 'text',
|
||||
required: true
|
||||
});
|
||||
|
||||
const containerModel = new ContainerModel(field);
|
||||
formModel.fields.push(containerModel);
|
||||
formComponent.form = formModel;
|
||||
formModel.onFormFieldChanged(field);
|
||||
|
||||
expect(formModel.isValid).toBeTruthy();
|
||||
|
||||
const completeOutcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: FormComponent.COMPLETE_OUTCOME_ID,
|
||||
name: FormOutcomeModel.COMPLETE_ACTION
|
||||
});
|
||||
|
||||
expect(formModel.isValid).toBeTruthy();
|
||||
const completeOutcome = formComponent.form.outcomes.find((outcome) => outcome.name === FormOutcomeModel.COMPLETE_ACTION);
|
||||
|
||||
expect(formComponent.isOutcomeButtonEnabled(completeOutcome)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should disable save outcome button when form is valid and readOnly', () => {
|
||||
const formModel = new FormModel();
|
||||
|
||||
const field = new FormFieldModel(formModel, {
|
||||
type: 'text',
|
||||
value: 'text',
|
||||
required: true
|
||||
});
|
||||
|
||||
const containerModel = new ContainerModel(field);
|
||||
formModel.fields.push(containerModel);
|
||||
formComponent.form = formModel;
|
||||
formModel.onFormFieldChanged(field);
|
||||
|
||||
expect(formModel.isValid).toBeTruthy();
|
||||
|
||||
const saveOutcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: FormComponent.SAVE_OUTCOME_ID,
|
||||
name: FormOutcomeModel.SAVE_ACTION
|
||||
});
|
||||
|
||||
formComponent.form.readOnly = true;
|
||||
expect(formComponent.isOutcomeButtonEnabled(saveOutcome)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should enable save outcome button when form is valid and not readOnly', () => {
|
||||
const formModel = new FormModel();
|
||||
|
||||
const field = new FormFieldModel(formModel, {
|
||||
type: 'text',
|
||||
value: 'text',
|
||||
required: true
|
||||
});
|
||||
|
||||
const containerModel = new ContainerModel(field);
|
||||
formModel.fields.push(containerModel);
|
||||
formComponent.form = formModel;
|
||||
formModel.onFormFieldChanged(field);
|
||||
|
||||
expect(formModel.isValid).toBeTruthy();
|
||||
|
||||
const saveOutcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: FormComponent.SAVE_OUTCOME_ID,
|
||||
name: FormOutcomeModel.SAVE_ACTION
|
||||
});
|
||||
|
||||
formComponent.form.readOnly = false;
|
||||
expect(formComponent.isOutcomeButtonEnabled(saveOutcome)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should disable save outcome button when disableSaveButton is true', () => {
|
||||
const formModel = new FormModel();
|
||||
formComponent.form = formModel;
|
||||
formComponent.disableSaveButton = true;
|
||||
|
||||
const saveOutcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: FormComponent.SAVE_OUTCOME_ID,
|
||||
name: FormOutcomeModel.SAVE_ACTION
|
||||
});
|
||||
|
||||
expect(formComponent.isOutcomeButtonEnabled(saveOutcome)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should disable save outcome button when the form is invalid', () => {
|
||||
const formModel = new FormModel();
|
||||
formComponent.form = formModel;
|
||||
|
||||
const field = new FormFieldModel(formModel, {
|
||||
type: 'text',
|
||||
value: null,
|
||||
required: true
|
||||
});
|
||||
|
||||
const containerModel = new ContainerModel(field);
|
||||
formModel.fields.push(containerModel);
|
||||
formComponent.form = formModel;
|
||||
formModel.onFormFieldChanged(field);
|
||||
|
||||
expect(formModel.isValid).toBeFalsy();
|
||||
|
||||
const saveOutcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: FormComponent.SAVE_OUTCOME_ID,
|
||||
name: FormOutcomeModel.SAVE_ACTION
|
||||
});
|
||||
|
||||
expect(formComponent.isOutcomeButtonEnabled(saveOutcome)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should disable start process outcome button when disableStartProcessButton is true', () => {
|
||||
const formModel = new FormModel();
|
||||
formComponent.form = formModel;
|
||||
formComponent.disableStartProcessButton = true;
|
||||
|
||||
const field = new FormFieldModel(formModel, {
|
||||
type: 'text',
|
||||
value: 'text',
|
||||
required: true
|
||||
});
|
||||
|
||||
const containerModel = new ContainerModel(field);
|
||||
formModel.fields.push(containerModel);
|
||||
formComponent.form = formModel;
|
||||
formModel.onFormFieldChanged(field);
|
||||
|
||||
expect(formModel.isValid).toBeTruthy();
|
||||
const startProcessOutcome = formComponent.form.outcomes.find((outcome) => outcome.name === FormOutcomeModel.START_PROCESS_ACTION);
|
||||
|
||||
const startProcessOutcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: FormComponent.START_PROCESS_OUTCOME_ID,
|
||||
name: FormOutcomeModel.START_PROCESS_ACTION
|
||||
});
|
||||
|
||||
expect(formComponent.isOutcomeButtonEnabled(startProcessOutcome)).toBeFalsy();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user