import {ElementRef, Component, Input, Output, OnInit, EventEmitter,
AfterViewInit, Renderer2} from '@angular/core';
-import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
+import {filter} from 'rxjs/operators';
import {MarcRecord, MarcField} from './marcrecord';
-import {MarcEditContext} from './editor-context';
+import {MarcEditContext, FieldFocusRequest} from './editor-context';
/**
* MARC Tag Editor Component
}
ngOnInit() {
- this.setupDataType();
+ this.setupFieldType();
}
- setupDataType() {
+ watchForFocusRequests() {
+
+ if (!this.field) {
+ // LDR tag has no field associated
+ return;
+ }
+
+ this.context.fieldFocusRequest.subscribe((req: FieldFocusRequest) => {
+
+ if (req.fieldId !== this.field.fieldId) { return ; }
+ if (!this.editInput) { return; }
+
+ if (req.sfOffset === undefined) {
+
+ if (this.fieldType === 'tag') {
+ // Focus tag input
+ this.editInput.select();
+ }
+ return;
+
+ }
+
+ // TODO: focus editable content input at subfield offset
+ if (this.fieldType === 'sfv') {
+ } else if (this.fieldType === 'sfc') {
+ }
+ });
+ }
+
+ setupFieldType() {
const content = this.getContent();
switch (this.fieldType) {
case 'tag':
this.maxLength = 3;
-
- // Arrow navigation focuses tags
- if (this.field) { // LDR tag does not have a field
- this.context.fieldFocusRequest.subscribe(fieldId => {
- if (fieldId === this.field.fieldId && this.editInput) {
- this.editInput.select();
- }
- });
- }
+ this.watchForFocusRequests();
break;
case 'ind':
+ this.maxLength = 1;
+ break;
+
case 'sfc':
this.maxLength = 1;
+ this.watchForFocusRequests();
break;
case 'sfv':
this.bigText = true;
+ this.watchForFocusRequests();
break;
}
}
}
inputKeyDown(evt: KeyboardEvent) {
- switch (evt.key) {
+
+ if (this.fieldType === 'ldr') {
+ // This may be overkill, we'll see
+ return;
+ }
+
+ switch (evt.key) {
+
+ case 'Enter':
+ // No part of a marc Record wants bare newlines
+ evt.preventDefault();
+ break;
+
+ case 'Delete':
+ if (evt.ctrlKey) { // Delete field
+
+ const field =
+ this.record.getNextField(this.field.fieldId) ||
+ this.record.getPreviousField(this.field.fieldId);
+ if (field) {
+ this.context.requestFieldFocus({fieldId: field.fieldId});
+ }
+
+ this.record.deleteFields(this.field);
+ }
+
+ evt.preventDefault();
+ break;
- case 'ArrowDown':
+ case 'ArrowDown':
if (evt.ctrlKey) { // Copy field down
const field = this.record.getNextField(this.field.fieldId);
if (field) {
- this.context.requestFieldFocus(field.fieldId);
+ this.context.requestFieldFocus({fieldId: field.fieldId});
}
}
evt.preventDefault();
const field = this.record.getPreviousField(this.field.fieldId);
if (field) {
- this.context.requestFieldFocus(field.fieldId);
+ this.context.requestFieldFocus({fieldId: field.fieldId});
}
}
evt.preventDefault();
/* Per-instance MARC editor context. */
+export interface FieldFocusRequest {
+ fieldId: number;
+ // If specified, the subfield value at the specified
+ // will be focused. Otherwise, the tag is focused.
+ sfOffset?: number;
+}
+
export class MarcEditContext {
recordChange: EventEmitter<MarcRecord>;
- fieldFocusRequest: EventEmitter<number>;
+ fieldFocusRequest: EventEmitter<FieldFocusRequest>;
popOvers: NgbPopover[] = [];
constructor() {
this.recordChange = new EventEmitter<MarcRecord>();
- this.fieldFocusRequest = new EventEmitter<number>();
+ this.fieldFocusRequest = new EventEmitter<FieldFocusRequest>();
}
// NgbPopovers don't always close when we want them to,
this.popOvers.forEach(p => p.close());
}
- requestFieldFocus(id: number) {
- this.fieldFocusRequest.emit(id);
+ requestFieldFocus(req: FieldFocusRequest) {
+ this.fieldFocusRequest.emit(req);
}
}