kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.3 KiB
102 lines
3.3 KiB
import {InputState} from "reactivestates";
|
|
import {debugLog} from "../../../../helpers/debug_output";
|
|
import {injectorBridge} from "../../../angular/angular-injector-bridge.functions";
|
|
import {States} from "../../../states.service";
|
|
import {TableRowEditContext} from "../../../wp-edit-form/table-row-edit-context";
|
|
import {WorkPackageEditForm} from "../../../wp-edit-form/work-package-edit-form";
|
|
import {cellClassName, editableClassName} from "../../builders/cell-builder";
|
|
import {rowClassName} from "../../builders/rows/single-row-builder";
|
|
import {WorkPackageTable} from "../../wp-fast-table";
|
|
import {ClickOrEnterHandler} from "../click-or-enter-handler";
|
|
import {TableEventHandler} from "../table-handler-registry";
|
|
|
|
export class EditCellHandler extends ClickOrEnterHandler implements TableEventHandler {
|
|
// Injections
|
|
public states:States;
|
|
|
|
public get EVENT() {
|
|
return 'click.table.cell, keydown.table.cell';
|
|
}
|
|
|
|
public get SELECTOR() {
|
|
return `.${cellClassName}.${editableClassName}`;
|
|
}
|
|
|
|
public eventScope(table:WorkPackageTable) {
|
|
return jQuery(table.container);
|
|
}
|
|
|
|
constructor(table: WorkPackageTable) {
|
|
super();
|
|
injectorBridge(this);
|
|
}
|
|
|
|
protected processEvent(table: WorkPackageTable, evt:JQueryEventObject):boolean {
|
|
debugLog('Starting editing on cell: ', evt.target);
|
|
evt.preventDefault();
|
|
|
|
// Locate the cell from event
|
|
let target = jQuery(evt.target).closest(`.${cellClassName}`);
|
|
// Get the target field name
|
|
let fieldName = target.data('fieldName');
|
|
|
|
if (!fieldName) {
|
|
debugLog('Click handled by cell not a field? ', evt.target);
|
|
return true;
|
|
}
|
|
|
|
// Locate the row
|
|
const rowElement = target.closest(`.${rowClassName}`);
|
|
const workPackageId = rowElement.data('workPackageId');
|
|
|
|
// Get any existing edit state for this work package
|
|
let state = this.editState(workPackageId);
|
|
let form = state.value || this.startEditing(state, workPackageId);
|
|
|
|
// Get the position where the user clicked.
|
|
const positionOffset = this.getClickPosition(evt);
|
|
|
|
// Set editing context to table
|
|
form.editContext = new TableRowEditContext(workPackageId);
|
|
|
|
// Activate the field
|
|
form.activate(fieldName).then((fieldElement:ng.IAugmentedJQuery) => {
|
|
this.setClickPosition(fieldElement.find('input'), positionOffset);
|
|
});
|
|
|
|
return false;
|
|
}
|
|
|
|
private setClickPosition(element:ng.IAugmentedJQuery, offset:number) {
|
|
if (element.length) {
|
|
(element[0] as HTMLInputElement).setSelectionRange(offset, offset);
|
|
} else {
|
|
debugLog('Unable to set position on Element.', element);
|
|
}
|
|
}
|
|
|
|
private getClickPosition(evt:JQueryEventObject):number {
|
|
try {
|
|
const range = document.caretRangeFromPoint(evt.clientX, evt.clientY);
|
|
return range.startOffset;
|
|
} catch(e) {
|
|
debugLog('Failed to get click position for edit field.', e);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
private startEditing(state: InputState<WorkPackageEditForm>, workPackageId:string):WorkPackageEditForm {
|
|
let form = new WorkPackageEditForm(workPackageId);
|
|
state.putValue(form);
|
|
return form;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the edit state for this work package
|
|
*/
|
|
private editState(workPackageId: string): InputState<WorkPackageEditForm> {
|
|
return this.states.editing.get(workPackageId);
|
|
}
|
|
}
|
|
|
|
EditCellHandler.$inject = ['states'];
|
|
|