-<input
- id='marc-editable-content-{{randId}}'
- class="p-0 pl-1 rounded-0 form-control {{moreClasses}}"
- [size]="inputSize()"
- [maxlength]="maxLength || ''"
- [disabled]="readOnly"
- [attr.tabindex]="readOnly ? -1 : ''"
- (focus)="$event.target.select()"
- (blur)="propagateTouch()"
- [(ngModel)]="content"
-/>
+<ng-container *ngIf="bigText">
+ <div contenteditable
+ id='{{randId}}'
+ class="d-inline-block p-1 text-break {{moreClasses}}"
+ [attr.tabindex]="readOnly ? -1 : ''"
+ (focus)="focusDiv($event)"
+ (blur)="propagateTouch(); valueChange()">
+ </div>
+</ng-container>
+
+<ng-container *ngIf="!bigText">
+ <input
+ id='{{randId}}'
+ class="p-0 pl-1 text-break rounded-0 form-control {{moreClasses}}"
+ [size]="inputSize()"
+ [maxlength]="maxLength || ''"
+ [disabled]="readOnly"
+ [attr.tabindex]="readOnly ? -1 : ''"
+ (focus)="$event.target.select()"
+ (blur)="propagateTouch()"
+ [(ngModel)]="content"
+ />
+</ng-container>
-import {Component, Input, Output, OnInit, EventEmitter, forwardRef} from '@angular/core';
+import {ElementRef, Component, Input, Output, OnInit, EventEmitter,
+ AfterViewInit, Renderer2, forwardRef} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {MarcRecord} from './marcrecord';
import {MarcEditContext} from './editor-context';
@Component({
selector: 'eg-marc-editable-content',
templateUrl: './editable-content.component.html',
+ styleUrls: ['./editable-content.component.css'],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => EditableContentComponent),
}]
})
-export class EditableContentComponent implements OnInit, ControlValueAccessor {
+export class EditableContentComponent implements OnInit, AfterViewInit, ControlValueAccessor {
@Input() context: MarcEditContext;
@Input() readOnly: boolean;
@Input() content: string;
@Input() maxLength: number;
+ @Input() bigText: boolean;
// space-separated list of additional CSS classes to append
@Input() moreClasses: string;
get record(): MarcRecord { return this.context.record; }
- randId: string;
+ randId: number;
+ editDiv: any; // used for bigText
// Stub functions required by ControlValueAccessor
propagateChange = (_: any) => {};
propagateTouch = () => {};
- constructor() {
- this.randId = Math.random().toFixed(5);
+ constructor(private renderer: Renderer2) {
+ this.randId = Math.floor(Math.random() * 100000);
}
ngOnInit() {}
+ ngAfterViewInit() {
+ if (this.bigText) {
+ this.editDiv = // numeric id requires [id=...] query selector
+ this.renderer.selectRootElement(`[id='${this.randId}']`);
+ }
+ }
+
inputSize(): number {
- return (this.content || ' ').length * 1.1;
+ // give at least 2 chars space and grow with the content
+ return Math.max(2, (this.content || '').length) * 1.1;
+ }
+
+ focusDiv($event) {
+ const targetNode = $event.srcElement.firstChild;
+
+ const range = document.createRange();
+ range.setStart(targetNode, 0);
+ range.setEnd(targetNode, targetNode.length);
+
+ const selection = window.getSelection();
+ selection.removeAllRanges();
+ selection.addRange(range);
}
valueChange() {
+ if (this.editDiv) {
+ this.content = this.editDiv.innerText;
+ }
this.propagateChange(this.content);
}
writeValue(content: string) {
+ if (content === null || content === undefined) {
+ content = '';
+ }
this.content = content;
+ if (this.editDiv) {
+ this.editDiv.innerText = content;
+ }
}
registerOnChange(fn) {
<ng-container *ngFor="let subfield of field.subfields">
- <!-- subfield character -->
+ <!-- subfield decorator -->
<eg-marc-editable-content [readOnly]="true"
moreClasses="text-primary border-right-0 bg-transparent"
i18n-ngModel [ngModel]="'‡'"></eg-marc-editable-content>
+
+ <!-- subfield character -->
<eg-marc-editable-content [context]="context" [(ngModel)]="subfield[0]"
moreClasses="text-info border-left-0"
[maxLength]="1"></eg-marc-editable-content>
<!-- subfield value -->
- <eg-marc-editable-content [context]="context" [(ngModel)]="subfield[1]">
+ <eg-marc-editable-content [context]="context"
+ [bigText]="true" [(ngModel)]="subfield[1]">
</eg-marc-editable-content>
</ng-container>
</div>