mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
Basic editing for dynamic table rows
Editors: - text (also covers number and amount for now) - boolean - dropdown (manual) - date
This commit is contained in:
parent
4f566a7ba2
commit
51102980df
@ -17,6 +17,7 @@
|
||||
|
||||
export interface DynamicTableRow {
|
||||
|
||||
isNew: boolean;
|
||||
selected: boolean;
|
||||
value: any;
|
||||
|
||||
|
@ -104,4 +104,24 @@ export class DynamicTableModel extends FormWidgetModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getCellValue(row: DynamicTableRow, column: DynamicTableColumn): any {
|
||||
let result = row.value[column.id];
|
||||
|
||||
if (column.type === 'Dropdown') {
|
||||
return result.name;
|
||||
}
|
||||
|
||||
if (column.type === 'Boolean') {
|
||||
return result ? true : false;
|
||||
}
|
||||
|
||||
if (column.type === 'Date') {
|
||||
if (result) {
|
||||
return moment(result.split('T')[0], 'YYYY-M-D').format('DD-MM-YYYY');
|
||||
}
|
||||
}
|
||||
|
||||
return result || '';
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,10 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dynamic-table-widget__table-editor {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dynamic-table-widget__invalid .mdl-textfield__input {
|
||||
border-color: #d50000;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div class="dynamic-table-widget"
|
||||
[class.dynamic-table-widget__invalid]="!content.isValid">
|
||||
<div class="dynamic-table-widget">
|
||||
<div>{{content.name}}</div>
|
||||
|
||||
<div *ngIf="!editMode">
|
||||
<table class="mdl-data-table mdl-js-data-table dynamic-table-widget__table">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -17,7 +17,7 @@
|
||||
<td *ngFor="let column of content.visibleColumns"
|
||||
class="mdl-data-table__cell--non-numeric"
|
||||
(click)="onRowClicked(row)">
|
||||
{{row.value[column.id]}}
|
||||
{{ getCellValue(row, column) }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -49,6 +49,51 @@
|
||||
<i class="material-icons">edit</i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<span *ngIf="content.validationSummary" class="mdl-textfield__error">{{content.validationSummary}}</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="editMode">
|
||||
<div class="mdl-grid" *ngFor="let column of content.columns">
|
||||
<div class="mdl-cell mdl-cell--6-col" [ngSwitch]="column.type">
|
||||
<div *ngSwitchCase="'Dropdown'">
|
||||
<alf-dropdown-editor
|
||||
[table]="content"
|
||||
[row]="editRow"
|
||||
[column]="column">
|
||||
</alf-dropdown-editor>
|
||||
</div>
|
||||
<div *ngSwitchCase="'Date'">
|
||||
<alf-date-editor
|
||||
[table]="content"
|
||||
[row]="editRow"
|
||||
[column]="column">
|
||||
</alf-date-editor>
|
||||
</div>
|
||||
|
||||
<div *ngSwitchCase="'Boolean'">
|
||||
<alf-boolean-editor
|
||||
[table]="content"
|
||||
[row]="editRow"
|
||||
[column]="column">
|
||||
</alf-boolean-editor>
|
||||
</div>
|
||||
<div *ngSwitchDefault>
|
||||
<alf-text-editor
|
||||
[table]="content"
|
||||
[row]="editRow"
|
||||
[column]="column">
|
||||
</alf-text-editor>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="mdl-button mdl-js-button mdl-js-ripple-effect"
|
||||
(click)="onCancelChanges()">Cancel</button>
|
||||
<button
|
||||
class="mdl-button mdl-js-button mdl-js-ripple-effect"
|
||||
(click)="onSaveChanges()">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--<span *ngIf="content.validationSummary" class="mdl-textfield__error">{{content.validationSummary}}</span>-->
|
||||
</div>
|
||||
|
@ -15,9 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit, ElementRef } from '@angular/core';
|
||||
import { WidgetComponent } from './../widget.component';
|
||||
import { DynamicTableModel, DynamicTableRow } from './../core/index';
|
||||
import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './../core/index';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
@ -30,6 +30,13 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit {
|
||||
@Input()
|
||||
content: DynamicTableModel;
|
||||
|
||||
editMode: boolean;
|
||||
editRow: DynamicTableRow;
|
||||
|
||||
constructor(private elementRef: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
@ -55,17 +62,67 @@ export class DynamicTableWidget extends WidgetComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
addNewRow() {
|
||||
console.log('add new row clicked');
|
||||
}
|
||||
|
||||
deleteSelection() {
|
||||
if (this.content) {
|
||||
this.content.deleteRow(this.content.selectedRow);
|
||||
}
|
||||
}
|
||||
|
||||
addNewRow() {
|
||||
if (this.content) {
|
||||
this.editRow = <DynamicTableRow> { selected: false, value: {} };
|
||||
this.editMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
editSelection() {
|
||||
console.log('edit selection clicked');
|
||||
if (this.content) {
|
||||
this.editRow = this.copyRow(this.content.selectedRow);
|
||||
this.editMode = true;
|
||||
}
|
||||
}
|
||||
|
||||
getCellValue(row: DynamicTableRow, column: DynamicTableColumn): any {
|
||||
if (this.content) {
|
||||
return this.content.getCellValue(row, column);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
onSaveChanges() {
|
||||
if (this.content) {
|
||||
if (this.editRow.isNew) {
|
||||
// TODO: create new record
|
||||
} else {
|
||||
this.content.selectedRow.value = this.copyObject(this.editRow.value);
|
||||
}
|
||||
this.content.flushValue();
|
||||
}
|
||||
this.editMode = false;
|
||||
}
|
||||
|
||||
onCancelChanges() {
|
||||
this.editMode = false;
|
||||
this.editRow = null;
|
||||
}
|
||||
|
||||
private copyRow(row: DynamicTableRow): DynamicTableRow {
|
||||
return <DynamicTableRow> {
|
||||
value: this.copyObject(row.value)
|
||||
};
|
||||
}
|
||||
|
||||
private copyObject(obj: any): any {
|
||||
let result = Object.assign({}, obj);
|
||||
|
||||
if (typeof obj === 'object' && obj !== null && obj !== undefined) {
|
||||
Object.keys(obj).forEach(key => {
|
||||
if (typeof obj[key] === 'object') {
|
||||
result[key] = this.copyObject(obj[key]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
<label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" [attr.for]="column.id">
|
||||
<input
|
||||
class="mdl-checkbox__input"
|
||||
type="checkbox"
|
||||
[attr.id]="column.id"
|
||||
[checked]="table.getCellValue(row, column)"
|
||||
(change)="onValueChanged(row, column, $event)">
|
||||
<span class="mdl-checkbox__label">{{column.name}}</span>
|
||||
</label>
|
@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* @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 } from '@angular/core';
|
||||
import { CellEditorComponent } from './../cell.editor';
|
||||
import { DynamicTableRow, DynamicTableColumn } from './../../../core/index';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'alf-boolean-editor',
|
||||
templateUrl: './boolean.editor.html',
|
||||
styleUrls: ['./boolean.editor.css']
|
||||
})
|
||||
export class BooleanEditorComponent extends CellEditorComponent {
|
||||
|
||||
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: Event) {
|
||||
let value: boolean = (<HTMLInputElement>event.srcElement).checked;
|
||||
row.value[column.id] = value;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*!
|
||||
* @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 { Input } from '@angular/core';
|
||||
import { DynamicTableModel, DynamicTableRow, DynamicTableColumn } from './../../core/index';
|
||||
|
||||
export abstract class CellEditorComponent {
|
||||
|
||||
@Input()
|
||||
table: DynamicTableModel;
|
||||
|
||||
@Input()
|
||||
row: DynamicTableRow;
|
||||
|
||||
@Input()
|
||||
column: DynamicTableColumn;
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
.date-editor {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.date-editor--button {
|
||||
margin-top: 15px;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<div class="mdl-grid">
|
||||
<div class="mdl-cell mdl-cell--11-col">
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label date-editor">
|
||||
<input id="dateInput"
|
||||
class="mdl-textfield__input"
|
||||
type="text"
|
||||
[value]="table.getCellValue(row, column)"
|
||||
[attr.id]="column.id"
|
||||
[readonly]="true"
|
||||
(onOk)="onDateSelected($event)">
|
||||
<label class="mdl-textfield__label" [attr.for]="column.id">{{column.name}} (d-M-yyyy)</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mdl-cell mdl-cell--1-col">
|
||||
<button
|
||||
class="mdl-button mdl-js-button mdl-button--icon date-editor--button"
|
||||
(click)="datePicker.toggle()">
|
||||
<i class="material-icons">date_range</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,74 @@
|
||||
/*!
|
||||
* @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, ElementRef } from '@angular/core';
|
||||
import { CellEditorComponent } from './../cell.editor';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'alf-date-editor',
|
||||
templateUrl: './date.editor.html',
|
||||
styleUrls: ['./date.editor.css']
|
||||
})
|
||||
export class DateEditorComponent extends CellEditorComponent implements OnInit {
|
||||
|
||||
DATE_FORMAT: string = 'DD-MM-YYYY';
|
||||
|
||||
datePicker: any;
|
||||
|
||||
constructor(private elementRef: ElementRef) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
let settings: any = {
|
||||
type: 'date',
|
||||
future: moment().add(21, 'years'),
|
||||
init: moment(this.table.getCellValue(this.row, this.column), this.DATE_FORMAT)
|
||||
};
|
||||
|
||||
this.datePicker = new mdDateTimePicker.default(settings);
|
||||
if (this.elementRef) {
|
||||
this.datePicker.trigger = this.elementRef.nativeElement.querySelector('#dateInput');
|
||||
}
|
||||
}
|
||||
|
||||
onDateSelected(event: CustomEvent) {
|
||||
let newValue = this.datePicker.time.format('YYYY-MM-DD');
|
||||
this.row.value[this.column.id] = newValue + 'T00:00:00.000Z';
|
||||
this.table.flushValue();
|
||||
|
||||
if (this.elementRef) {
|
||||
this.setupMaterialTextField(this.elementRef, componentHandler, newValue);
|
||||
}
|
||||
}
|
||||
|
||||
setupMaterialTextField(elementRef: ElementRef, handler: any, value: string): boolean {
|
||||
if (elementRef && handler) {
|
||||
let el = elementRef.nativeElement;
|
||||
if (el) {
|
||||
let container = el.querySelector('.mdl-textfield');
|
||||
if (container) {
|
||||
container.MaterialTextfield.change(value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
.dropdown-editor__select {
|
||||
width: 100%;
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
<div>
|
||||
<label [attr.for]="column.id">{{column.name}}</label>
|
||||
<div>
|
||||
<select
|
||||
[value]="table.getCellValue(row, column)"
|
||||
class="dropdown-editor__select"
|
||||
(change)="onValueChanged(row, column, $event)">
|
||||
<option *ngFor="let opt of column.options" [value]="opt.name">{{opt.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,36 @@
|
||||
/*!
|
||||
* @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 } from '@angular/core';
|
||||
import { CellEditorComponent } from './../cell.editor';
|
||||
import { DynamicTableRow, DynamicTableColumn } from './../../../core/index';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'alf-dropdown-editor',
|
||||
templateUrl: './dropdown.editor.html',
|
||||
styleUrls: ['./dropdown.editor.css']
|
||||
})
|
||||
export class DropdownEditorComponent extends CellEditorComponent {
|
||||
|
||||
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: Event) {
|
||||
let value: any = (<HTMLInputElement>event.srcElement).value;
|
||||
value = column.options.find(opt => opt.name === value);
|
||||
row.value[column.id] = value;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
<div alfresco-mdl-textfield class="dynamic-table-widget__table-editor">
|
||||
<input
|
||||
class="mdl-textfield__input"
|
||||
type="text"
|
||||
[value]="table.getCellValue(row, column)"
|
||||
(keyup)="onValueChanged(row, column, $event)"
|
||||
[attr.id]="column.id">
|
||||
<label class="mdl-textfield__label" [attr.for]="column.id">{{column.name}}</label>
|
||||
</div>
|
@ -0,0 +1,35 @@
|
||||
/*!
|
||||
* @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 } from '@angular/core';
|
||||
import { CellEditorComponent } from './../cell.editor';
|
||||
import { DynamicTableRow, DynamicTableColumn } from './../../../core/index';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
selector: 'alf-text-editor',
|
||||
templateUrl: './text.editor.html',
|
||||
styleUrls: ['./text.editor.css']
|
||||
})
|
||||
export class TextEditorComponent extends CellEditorComponent {
|
||||
|
||||
onValueChanged(row: DynamicTableRow, column: DynamicTableColumn, event: Event) {
|
||||
let value: any = (<HTMLInputElement>event.srcElement).value;
|
||||
row.value[column.id] = value;
|
||||
}
|
||||
|
||||
}
|
@ -35,6 +35,10 @@ import { PeopleWidget } from './people/people.widget';
|
||||
import { DateWidget } from './date/date.widget';
|
||||
import { AmountWidget } from './amount/amount.widget';
|
||||
import { DynamicTableWidget } from './dynamic-table/dynamic-table.widget';
|
||||
import { DateEditorComponent } from './dynamic-table/editors/date/date.editor';
|
||||
import { DropdownEditorComponent } from './dynamic-table/editors/dropdown/dropdown.editor';
|
||||
import { BooleanEditorComponent } from './dynamic-table/editors/boolean/boolean.editor';
|
||||
import { TextEditorComponent } from './dynamic-table/editors/text/text.editor';
|
||||
|
||||
// core
|
||||
export * from './widget.component';
|
||||
@ -63,6 +67,12 @@ export * from './date/date.widget';
|
||||
export * from './amount/amount.widget';
|
||||
export * from './dynamic-table/dynamic-table.widget';
|
||||
|
||||
// editors (dynamic table)
|
||||
export * from './dynamic-table/editors/date/date.editor';
|
||||
export * from './dynamic-table/editors/dropdown/dropdown.editor';
|
||||
export * from './dynamic-table/editors/boolean/boolean.editor';
|
||||
export * from './dynamic-table/editors/text/text.editor';
|
||||
|
||||
export const WIDGET_DIRECTIVES: any[] = [
|
||||
TabsWidget,
|
||||
ContainerWidget,
|
||||
@ -82,5 +92,10 @@ export const WIDGET_DIRECTIVES: any[] = [
|
||||
PeopleWidget,
|
||||
DateWidget,
|
||||
AmountWidget,
|
||||
DynamicTableWidget
|
||||
|
||||
DynamicTableWidget,
|
||||
DateEditorComponent,
|
||||
DropdownEditorComponent,
|
||||
BooleanEditorComponent,
|
||||
TextEditorComponent
|
||||
];
|
||||
|
@ -19,15 +19,18 @@ import { MDL } from './MaterialDesignLiteUpgradeElement';
|
||||
import { AlfrescoMdlButtonDirective } from './mdl-button.directive';
|
||||
import { AlfrescoMdlMenuDirective } from './mdl-menu.directive';
|
||||
import { AlfrescoMdlTabsDirective } from './mdl-tabs.directive';
|
||||
import { AlfrescoMdlTextFieldDirective } from './mdl-textfield.directive';
|
||||
|
||||
export * from './MaterialDesignLiteUpgradeElement';
|
||||
export * from './mdl-button.directive';
|
||||
export * from './mdl-menu.directive';
|
||||
export * from './mdl-tabs.directive';
|
||||
export * from './mdl-textfield.directive';
|
||||
|
||||
export const MATERIAL_DESIGN_DIRECTIVES: [any] = [
|
||||
MDL,
|
||||
AlfrescoMdlButtonDirective,
|
||||
AlfrescoMdlMenuDirective,
|
||||
AlfrescoMdlTabsDirective
|
||||
AlfrescoMdlTabsDirective,
|
||||
AlfrescoMdlTextFieldDirective
|
||||
];
|
||||
|
@ -0,0 +1,38 @@
|
||||
/*!
|
||||
* @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 { Directive, ElementRef, AfterViewInit } from '@angular/core';
|
||||
|
||||
declare var componentHandler;
|
||||
|
||||
@Directive({
|
||||
selector: '[alfresco-mdl-textfield]'
|
||||
})
|
||||
export class AlfrescoMdlTextFieldDirective implements AfterViewInit {
|
||||
|
||||
constructor(private element: ElementRef) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if (componentHandler) {
|
||||
let el = this.element.nativeElement;
|
||||
el.classList.add('mdl-textfield');
|
||||
el.classList.add('mdl-js-textfield');
|
||||
el.classList.add('mdl-textfield--floating-label');
|
||||
componentHandler.upgradeElement(el, 'MaterialTextfield');
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user