mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-19 17:14:57 +00:00
#589 ability to prevent default outcome behaviour
- ability to prevent default outcome behaviour (i.e. custom validation) - new ‘executeOutcome’ event for DocumentList - unit tests - readme updates
This commit is contained in:
parent
a977e52e8d
commit
acfa8ac819
@ -106,8 +106,9 @@ The recommended set of properties can be found in the following table:
|
||||
| formLoaded | Invoked when form is loaded or reloaded. |
|
||||
| formSaved | Invoked when form is submitted with `Save` or custom outcomes. |
|
||||
| formCompleted | Invoked when form is submitted with `Complete` outcome. |
|
||||
| executeOutcome | Invoked when any outcome is executed, default behaviour can be prevented via `event.preventDefault()` |
|
||||
|
||||
All `form*` events recieve an instance of the `FormModel` as event argument for ease of development:
|
||||
All `form*` events receive an instance of the `FormModel` as event argument for ease of development:
|
||||
|
||||
**MyView.component.html**
|
||||
```html
|
||||
@ -124,6 +125,56 @@ onFormSaved(form: FormModel) {
|
||||
}
|
||||
```
|
||||
|
||||
#### Controlling outcome execution behaviour
|
||||
|
||||
If absolutely needed it is possible taking full control over form outcome execution by means of `executeOutcome` event.
|
||||
This event is fired upon each outcome execution, both system and custom ones.
|
||||
|
||||
You can prevent default behaviour by calling `event.preventDefault()`.
|
||||
This allows for example having custom form validation scenarios and/or additional validation summary presentation.
|
||||
|
||||
Alternatively you may want just running additional code on outcome execution without suppressing default one.
|
||||
|
||||
**MyView.component.html**
|
||||
```html
|
||||
<activiti-form
|
||||
[taskId]="selectedTask?.id"
|
||||
executeOutcome="validateForm($event)">
|
||||
</activiti-form>
|
||||
```
|
||||
|
||||
**MyView.component.ts**
|
||||
```ts
|
||||
import { FormOutcomeEvent } from 'ng2-activiti-form';
|
||||
|
||||
export class MyView {
|
||||
|
||||
validateForm(event: FormOutcomeEvent) {
|
||||
let outcome = event.outcome;
|
||||
|
||||
// you can also get additional properties of outcomes
|
||||
// if you defined them within outcome definition
|
||||
|
||||
if (outcome) {
|
||||
let form = outcome.form;
|
||||
if (form) {
|
||||
// check/update the form here
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
There are two additional functions that can be of a great value when controlling outcomes:
|
||||
|
||||
- `saveTaskForm()` - saves current form
|
||||
- `completeTaskForm(outcome?: string)` - save and complete form with a given outcome name
|
||||
|
||||
**Please note that if `event.preventDefault()` is not called then default outcome behaviour
|
||||
will also be executed after your custom code.**
|
||||
|
||||
## Build from sources
|
||||
|
||||
Alternatively you can build component from sources with the following commands:
|
||||
|
@ -19,7 +19,7 @@ import { it, describe, expect } from '@angular/core/testing';
|
||||
import { Observable } from 'rxjs/Rx';
|
||||
import { SimpleChange } from '@angular/core';
|
||||
import { ActivitiForm } from './activiti-form.component';
|
||||
import { FormModel, FormOutcomeModel, FormFieldModel } from './widgets/index';
|
||||
import { FormModel, FormOutcomeModel, FormFieldModel, FormOutcomeEvent } from './widgets/index';
|
||||
import { FormService } from './../services/form.service';
|
||||
import { WidgetVisibilityService } from './../services/widget-visibility.service';
|
||||
import { ContainerWidget } from './widgets/container/container.widget';
|
||||
@ -582,4 +582,56 @@ describe('ActivitiForm', () => {
|
||||
expect(formComponent.checkVisibility).toHaveBeenCalledWith(fakeField);
|
||||
});
|
||||
|
||||
it('should prevent default outcome execution', () => {
|
||||
|
||||
let outcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: ActivitiForm.CUSTOM_OUTCOME_ID,
|
||||
name: 'Custom'
|
||||
});
|
||||
|
||||
formComponent.form = new FormModel();
|
||||
formComponent.executeOutcome.subscribe((event: FormOutcomeEvent) => {
|
||||
expect(event.outcome).toBe(outcome);
|
||||
event.preventDefault();
|
||||
expect(event.defaultPrevented).toBeTruthy();
|
||||
});
|
||||
|
||||
let result = formComponent.onOutcomeClicked(outcome);
|
||||
expect(result).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not prevent default outcome execution', () => {
|
||||
let outcome = new FormOutcomeModel(new FormModel(), {
|
||||
id: ActivitiForm.CUSTOM_OUTCOME_ID,
|
||||
name: 'Custom'
|
||||
});
|
||||
|
||||
formComponent.form = new FormModel();
|
||||
formComponent.executeOutcome.subscribe((event: FormOutcomeEvent) => {
|
||||
expect(event.outcome).toBe(outcome);
|
||||
expect(event.defaultPrevented).toBeFalsy();
|
||||
});
|
||||
|
||||
spyOn(formComponent, 'completeTaskForm').and.callThrough();
|
||||
|
||||
let result = formComponent.onOutcomeClicked(outcome);
|
||||
expect(result).toBeTruthy();
|
||||
|
||||
expect(formComponent.completeTaskForm).toHaveBeenCalledWith(outcome.name);
|
||||
});
|
||||
|
||||
it('should check visibility only if field with form provided', () => {
|
||||
|
||||
formComponent.checkVisibility(null);
|
||||
expect(visibilityService.updateVisibilityForForm).not.toHaveBeenCalled();
|
||||
|
||||
let field = new FormFieldModel(null);
|
||||
formComponent.checkVisibility(field);
|
||||
expect(visibilityService.updateVisibilityForForm).not.toHaveBeenCalled();
|
||||
|
||||
field = new FormFieldModel(new FormModel());
|
||||
formComponent.checkVisibility(field);
|
||||
expect(visibilityService.updateVisibilityForForm).toHaveBeenCalledWith(field.form);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -26,7 +26,7 @@ import {
|
||||
import { MATERIAL_DESIGN_DIRECTIVES } from 'ng2-alfresco-core';
|
||||
|
||||
import { FormService } from './../services/form.service';
|
||||
import { FormModel, FormOutcomeModel, FormValues, FormFieldModel } from './widgets/core/index';
|
||||
import { FormModel, FormOutcomeModel, FormValues, FormFieldModel, FormOutcomeEvent } from './widgets/core/index';
|
||||
|
||||
import { TabsWidget } from './widgets/tabs/tabs.widget';
|
||||
import { ContainerWidget } from './widgets/container/container.widget';
|
||||
@ -116,6 +116,9 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
||||
@Output()
|
||||
formLoaded: EventEmitter<FormModel> = new EventEmitter<FormModel>();
|
||||
|
||||
@Output()
|
||||
executeOutcome: EventEmitter<FormOutcomeEvent> = new EventEmitter<FormOutcomeEvent>();
|
||||
|
||||
form: FormModel;
|
||||
|
||||
debugMode: boolean = false;
|
||||
@ -185,6 +188,13 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
||||
*/
|
||||
onOutcomeClicked(outcome: FormOutcomeModel): boolean {
|
||||
if (!this.readOnly && outcome && this.form) {
|
||||
|
||||
let args = new FormOutcomeEvent(outcome);
|
||||
this.executeOutcome.emit(args);
|
||||
if (args.defaultPrevented) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (outcome.isSystem) {
|
||||
if (outcome.id === ActivitiForm.SAVE_OUTCOME_ID) {
|
||||
this.saveTaskForm();
|
||||
@ -340,6 +350,8 @@ export class ActivitiForm implements OnInit, AfterViewChecked, OnChanges {
|
||||
}
|
||||
|
||||
checkVisibility(field: FormFieldModel) {
|
||||
this.visibilityService.updateVisibilityForForm(field.form);
|
||||
if (field && field.form) {
|
||||
this.visibilityService.updateVisibilityForForm(field.form);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2016 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { FormOutcomeModel } from './form-outcome.model';
|
||||
|
||||
export class FormOutcomeEvent {
|
||||
|
||||
private _outcome: FormOutcomeModel;
|
||||
private _defaultPrevented: boolean = false;
|
||||
|
||||
get outcome(): FormOutcomeModel {
|
||||
return this._outcome;
|
||||
}
|
||||
|
||||
get defaultPrevented() {
|
||||
return this._defaultPrevented;
|
||||
}
|
||||
|
||||
constructor(outcome: FormOutcomeModel) {
|
||||
this._outcome = outcome;
|
||||
}
|
||||
|
||||
preventDefault() {
|
||||
this._defaultPrevented = true;
|
||||
}
|
||||
|
||||
}
|
@ -26,3 +26,4 @@ export * from './container-column.model';
|
||||
export * from './container.model';
|
||||
export * from './tab.model';
|
||||
export * from './form-outcome.model';
|
||||
export * from './form-outcome-event.model';
|
||||
|
Loading…
x
Reference in New Issue
Block a user