From 679cdfe6cfbbd96c3cfd4808249e60b852118e49 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Mon, 5 Sep 2016 21:45:07 +0100 Subject: [PATCH] #633 basic typeahead implementation --- .../components/activiti-form.component.css | 1 + .../components/activiti-form.component.html | 12 +- .../widgets/container/container.widget.html | 3 + .../widgets/core/form-field-types.ts | 1 + .../widgets/core/form-field.model.ts | 14 ++- .../src/components/widgets/index.ts | 5 +- .../widgets/typeahead/typeahead.widget.css | 29 +++++ .../widgets/typeahead/typeahead.widget.html | 22 ++++ .../widgets/typeahead/typeahead.widget.ts | 103 ++++++++++++++++++ .../src/services/form.service.ts | 5 + 10 files changed, 186 insertions(+), 9 deletions(-) create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.css create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.html create mode 100644 ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.ts diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.css b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.css index 6eb9bd0de9..65aca84d10 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.css +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.css @@ -1,6 +1,7 @@ .activiti-form-container { width: 100%; min-height: 100px; + overflow: visible; } .activiti-form-container > .mdl-card__media { diff --git a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html index 82866342a4..44994aa77a 100644 --- a/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html +++ b/ng2-components/ng2-activiti-form/src/components/activiti-form.component.html @@ -41,11 +41,13 @@ will be removed during future revisions -->
- +
+ +

Values

diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html index 6cffc9730c..f89403d7f4 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html +++ b/ng2-components/ng2-activiti-form/src/components/widgets/container/container.widget.html @@ -46,6 +46,9 @@
+
+ +
UNKNOWN WIDGET TYPE: {{field.type}}
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-types.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-types.ts index 627bcfe5d2..bddb2e3dd2 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-types.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field-types.ts @@ -24,6 +24,7 @@ export class FormFieldTypes { static DISPLAY_VALUE: string = 'readonly'; static READONLY_TEXT: string = 'readonly-text'; static UPLOAD: string = 'upload'; + static TYPEAHEAD: string = 'typeahead'; static READONLY_TYPES: string[] = [ FormFieldTypes.HYPERLINK, diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts index 22bd3822ae..365a669dcc 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/core/form-field.model.ts @@ -150,9 +150,9 @@ export class FormFieldModel extends FormWidgetModel { This is needed due to Activiti issue related to reading radio button values as value string but saving back as object: { id: , name: } */ - let entry: FormFieldOption[] = this.options.filter(opt => opt.id === this.value); - if (entry.length > 0) { - this.form.values[this.id] = entry[0]; + let rbEntry: FormFieldOption[] = this.options.filter(opt => opt.id === this.value); + if (rbEntry.length > 0) { + this.form.values[this.id] = rbEntry[0]; } else if (this.options.length > 0) { this.form.values[this.id] = this.options[0]; } @@ -164,6 +164,14 @@ export class FormFieldModel extends FormWidgetModel { this.form.values[this.id] = null; } break; + case FormFieldTypes.TYPEAHEAD: + let taEntry: FormFieldOption[] = this.options.filter(opt => opt.id === this.value); + if (taEntry.length > 0) { + this.form.values[this.id] = taEntry[0]; + } else if (this.options.length > 0) { + this.form.values[this.id] = null; + } + break; default: if (!FormFieldTypes.isReadOnlyType(this.type)) { this.form.values[this.id] = this.value; diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/index.ts b/ng2-components/ng2-activiti-form/src/components/widgets/index.ts index 51ceb74e05..32d1c765ac 100644 --- a/ng2-components/ng2-activiti-form/src/components/widgets/index.ts +++ b/ng2-components/ng2-activiti-form/src/components/widgets/index.ts @@ -28,6 +28,7 @@ import { RadioButtonsWidget } from './radio-buttons/radio-buttons.widget'; import { DisplayValueWidget } from './display-value/display-value.widget'; import { DisplayTextWidget } from './display-text/display-text.widget'; import { UploadWidget } from './upload/upload.widget'; +import { TypeaheadWidget } from './typeahead/typeahead.widget'; // core export * from './widget.component'; @@ -48,6 +49,7 @@ export * from './radio-buttons/radio-buttons.widget'; export * from './display-value/display-value.widget'; export * from './display-text/display-text.widget'; export * from './upload/upload.widget'; +export * from './typeahead/typeahead.widget'; export const CONTAINER_WIDGET_DIRECTIVES: [any] = [ TabsWidget, @@ -64,7 +66,8 @@ export const PRIMITIVE_WIDGET_DIRECTIVES: [any] = [ RadioButtonsWidget, DisplayValueWidget, DisplayTextWidget, - UploadWidget + UploadWidget, + TypeaheadWidget ]; diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.css b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.css new file mode 100644 index 0000000000..5cefa1e623 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.css @@ -0,0 +1,29 @@ +.typeahead-widget { + width: 100%; +} + +.typeahead-autocomplete { + background-color: #fff; + position: absolute; + z-index: 5; + color: #555; + margin: -15px 0 0 0; +} + +.typeahead-autocomplete > ul { + list-style-type: none; + position: static; + + height: auto; + width: auto; + min-width: 124px; + padding: 8px 0; + margin: 0; + + box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12); + border-radius: 2px; +} + +.typeahead-autocomplete > ul > li { + opacity: 1; +} diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.html b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.html new file mode 100644 index 0000000000..d898da5f99 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.html @@ -0,0 +1,22 @@ +
+ + +
+ +
+
    +
  • + {{item.name}} +
  • +
+
diff --git a/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.ts b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.ts new file mode 100644 index 0000000000..ca589af4f2 --- /dev/null +++ b/ng2-components/ng2-activiti-form/src/components/widgets/typeahead/typeahead.widget.ts @@ -0,0 +1,103 @@ +/*! + * @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 { Component, OnInit } from '@angular/core'; +import { FormService } from './../../../services/form.service'; +import { WidgetComponent } from './../widget.component'; +import { FormFieldOption } from './../core/form-field-option'; + +declare let __moduleName: string; +declare var componentHandler; + +@Component({ + moduleId: __moduleName, + selector: 'typeahead-widget', + templateUrl: './typeahead.widget.html', + styleUrls: ['./typeahead.widget.css'] +}) +export class TypeaheadWidget extends WidgetComponent implements OnInit { + + popupVisible: boolean = false; + minTermLength: number = 1; + value: string; + + constructor(private formService: FormService) { + super(); + } + + ngOnInit() { + this.formService + .getRestFieldValues( + this.field.form.taskId, + this.field.id + ) + .then( + (result: FormFieldOption[]) => { + let options = result || []; + this.field.options = options; + this.field.updateForm(); + + let fieldValue = this.field.value; + if (fieldValue) { + let toSelect = options.find(item => item.id === fieldValue); + if (toSelect) { + this.value = toSelect.name; + } + } + }, + error => console.log(error) + ); + } + + getOptions(): FormFieldOption[] { + let val = this.value.toLocaleLowerCase(); + return this.field.options.filter(item => { + let name = item.name.toLocaleLowerCase(); + return name.indexOf(val) > -1; + }); + } + + onKey(event: KeyboardEvent) { + // this.values += (event.target).value + ' | '; + this.popupVisible = !!(this.value && this.value.length >= this.minTermLength); + } + + onBlur() { + setTimeout(() => { + this.popupVisible = false; + + let options = this.field.options || []; + let field = options.find(item => item.name.toLocaleLowerCase() === this.value.toLocaleLowerCase()); + if (field) { + this.field.value = field.id; + this.value = field.name; + } else { + this.field.value = null; + this.value = null; + } + + this.field.updateForm(); + }, 200); + } + + onItemClick(item: FormFieldOption, event: Event) { + event.preventDefault(); + this.field.value = item.id; + this.value = item.name; + } + +} diff --git a/ng2-components/ng2-activiti-form/src/services/form.service.ts b/ng2-components/ng2-activiti-form/src/services/form.service.ts index a5f33bc003..97af62dd9d 100644 --- a/ng2-components/ng2-activiti-form/src/services/form.service.ts +++ b/ng2-components/ng2-activiti-form/src/services/form.service.ts @@ -212,6 +212,11 @@ export class FormService { .catch(this.handleError); } + getRestFieldValues(taskId: string, field: string): Promise { + let alfrescoApi = this.authService.getAlfrescoApi(); + return alfrescoApi.activiti.taskFormsApi.getRestFieldValues(taskId, field); + } + getFormId(res: any) { let result = null;