Skip to content

Commit

Permalink
add valueStoreFunction - fixes #115
Browse files Browse the repository at this point in the history
  • Loading branch information
uap-universe committed Aug 8, 2023
1 parent f62f05b commit 1b6c277
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This document lists the changes introduced by this fork.
* Add Angular 16 support
* Add proper typing to all settings
* Improve signatures of `valuePrepareFunction`, and `filterFunction`
* Add `valueStoreFunction` as counter-part of the `valuePrepareFunction`
* Change how filters are configured:
* Add `removeFilter()` method
* Change `setFilter()` to always remove all existing filters, first
Expand Down
1 change: 1 addition & 0 deletions projects/angular2-smart-table/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This document lists the changes introduced by this fork.
* Add Angular 16 support
* Add proper typing to all settings
* Improve signatures of `valuePrepareFunction`, and `filterFunction`
* Add `valueStoreFunction` as counter-part of the `valuePrepareFunction`
* Change how filters are configured:
* Add `removeFilter()` method
* Change `setFilter()` to always remove all existing filters, first
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {CheckboxEditorSettings} from "../../../lib/settings";
[disabled]="!cell.isEditable()"
[checked]="cell.getValue() === trueVal"
(click)="onClick.emit($event)"
(change)="onChange($event)">
(change)="onChange($any($event.target).checked)">
`,
})
export class CheckboxEditorComponent extends DefaultEditor implements OnInit {
Expand All @@ -35,7 +35,7 @@ export class CheckboxEditorComponent extends DefaultEditor implements OnInit {
}
}

onChange(event: any) {
this.cell.newValue = event.target.checked ? this.trueVal : this.falseVal;
onChange(newVal: boolean) {
this.cell.setValue(newVal ? this.trueVal : this.falseVal);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import {DefaultEditor} from './default-editor';
styleUrls: ['./editor.component.scss'],
template: `
<input [ngClass]="inputClass"
class="form-control"
[(ngModel)]="cell.newValue"
[value]="cell.getValue()"
[name]="cell.getId()"
[placeholder]="cell.getTitle()"
[disabled]="!cell.isEditable()"
(click)="onClick.emit($event)"
(keyup)="cell.setValue($any($event.target).value)"
(keydown.enter)="disableEnterKeySave || onEdited.emit()"
(keydown.esc)="onStopEditing.emit()">
`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {Component} from '@angular/core';

import {DefaultEditor} from './default-editor';
import {ListEditorSettings} from "../../../lib/settings";

@Component({
selector: 'select-editor',
template: `
<select [ngClass]="inputClass"
class="form-control"
[value]="cell.newValue"
(change)="onSelectionChanged($any($event.target).value)"
[name]="cell.getId()"
[disabled]="!cell.isEditable()"
Expand All @@ -16,7 +16,7 @@ import {DefaultEditor} from './default-editor';
(keydown.enter)="disableEnterKeySave || onEdited.emit($event)"
(keydown.esc)="onStopEditing.emit()">
<option *ngFor="let option of cell.getColumn().getConfig()?.list" [value]="option.value"
<option *ngFor="let option of editorConfig.list" [value]="option.value"
[selected]="option.value === cell.getRawValue()">{{ option.title }}
</option>
</select>
Expand All @@ -28,7 +28,11 @@ export class SelectEditorComponent extends DefaultEditor {
super();
}

get editorConfig(): ListEditorSettings {
return this.cell.getColumn().getConfig();
}

onSelectionChanged(newValue: string) {
this.cell.newValue = newValue;
this.cell.setValue(newValue);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import {DefaultEditor} from './default-editor';
styleUrls: ['./editor.component.scss'],
template: `
<textarea [ngClass]="inputClass"
class="form-control"
[(ngModel)]="cell.newValue"
[value]="cell.getValue()"
[name]="cell.getId()"
[disabled]="!cell.isEditable()"
[placeholder]="cell.getTitle()"
(click)="onClick.emit($event)"
(keyup)="cell.setValue($any($event.target).value)"
(keydown.enter)="disableEnterKeySave || onEdited.emit()"
(keydown.esc)="onStopEditing.emit()">
</textarea>
Expand Down
14 changes: 11 additions & 3 deletions projects/angular2-smart-table/src/lib/lib/data-set/cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import {Row} from './row';

export class Cell {

newValue: string;

private cachedValue: unknown;
private cachedPreparedValue: string;

private newValue: string;

constructor(protected value: unknown, protected row: Row, protected column: Column) {
this.cachedValue = this.value;
this.cachedPreparedValue = this.getPreparedValue();
Expand Down Expand Up @@ -45,7 +45,15 @@ export class Cell {
}

setValue(value: string) {
this.newValue = value;
const store = this.column.valueStoreFunction ?? ((v) => v);
this.newValue = store.call(null, value, this);
}

/**
* Returns the new raw value after being post-processed by the valueStoreFunction.
*/
getNewRawValue(): any {
return this.newValue;
}

getId(): string {
Expand Down
3 changes: 3 additions & 0 deletions projects/angular2-smart-table/src/lib/lib/data-set/column.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ColumnComponentInitFunction,
ColumnFilterFunction,
ColumnValuePrepareFunction,
ColumnValueStoreFunction,
EditorSettings,
FilterSettings,
IColumn,
Expand Down Expand Up @@ -43,6 +44,7 @@ export class Column {
renderComponent?: any;
compareFunction?: ColumnCompareFunction;
valuePrepareFunction?: ColumnValuePrepareFunction;
valueStoreFunction?: ColumnValueStoreFunction;
filterFunction?: ColumnFilterFunction;
componentInitFunction?: ColumnComponentInitFunction;

Expand All @@ -69,6 +71,7 @@ export class Column {

this.compareFunction = this.settings.compareFunction;
this.valuePrepareFunction = this.settings.valuePrepareFunction;
this.valueStoreFunction = this.settings.valueStoreFunction;
this.filterFunction = this.settings.filterFunction;
this.componentInitFunction = this.settings.componentInitFunction;
}
Expand Down
2 changes: 1 addition & 1 deletion projects/angular2-smart-table/src/lib/lib/data-set/row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class Row {

getNewData(): any {
const values = Object.assign({}, this.data);
this.getCells().forEach((cell) => values[cell.getColumn().id] = cell.newValue);
this.getCells().forEach((cell) => values[cell.getColumn().id] = cell.getNewRawValue());
return values;
}

Expand Down
2 changes: 2 additions & 0 deletions projects/angular2-smart-table/src/lib/lib/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export type RowClassFunction = (row: Row) => string;

export type ColumnCompareFunction = (direction: number, left: any, right: any) => number;
export type ColumnValuePrepareFunction = (rawValue: any, cell: Cell) => string;
export type ColumnValueStoreFunction = (value: string, cell: Cell) => any;
export type ColumnFilterFunction = (value: any, searchString: string) => boolean;
export type ColumnComponentInitFunction = (component: any, cell: Cell) => void;

Expand Down Expand Up @@ -123,6 +124,7 @@ export interface IColumn {
renderComponent?: any;
compareFunction?: ColumnCompareFunction;
valuePrepareFunction?: ColumnValuePrepareFunction;
valueStoreFunction?: ColumnValueStoreFunction;
filterFunction?: ColumnFilterFunction;
componentInitFunction?: ColumnComponentInitFunction;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,24 @@ <h3>Table Configuration</h3>
<td>valuePrepareFunction</td>
<td><span class="highlight">Function</span></td>
<td>
undefined
toString()
</td>
<td>
Function that is used by the cell to compute the displayed value.
<br>
This function will be invoked with two parameters: (rawValue: string, cell: Cell)
This function will be invoked with two parameters (rawValue: any, cell: Cell) and must produce a string.
</td>
</tr>
<tr>
<td>valueStoreFunction</td>
<td><span class="highlight">Function</span></td>
<td>
identity
</td>
<td>
Function that is used by the cell to convert an edited value (string) back to a value of the original type.
<br>
This function will be invoked with two parameters: (newValue: string, cell: Cell)
</td>
</tr>
<tr>
Expand Down Expand Up @@ -423,7 +435,7 @@ <h3>Table Configuration</h3>
<td>
Function run against the cell value when filtering is happening, returning a boolean indicating whether the filter matched.
<br>
This function will be invoked with two parameters: (value: string, searchString: string)
This function will be invoked with two parameters: (value: any, searchString: string)
</td>
</tr>
<tr class="section">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,59 +1,44 @@
import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { DefaultEditor } from 'angular2-smart-table';
import {AfterViewInit, Component} from '@angular/core';
import {DefaultEditor} from 'angular2-smart-table';

@Component({
template: `
Name: <input [ngClass]="inputClass"
#name
class="form-control short-input"
[name]="cell.getId()"
[value]="name"
[disabled]="!cell.isEditable()"
[placeholder]="cell.getTitle()"
(click)="onClick.emit($event)"
(keyup)="updateValue()"
(change)="name=$any($event.target).value; updateValue()"
(keydown.enter)="onEdited.emit()"
(keydown.esc)="onStopEditing.emit()"><br>
Url: <input [ngClass]="inputClass"
#url
class="form-control short-input"
[name]="cell.getId()"
[value]="url"
[disabled]="!cell.isEditable()"
[placeholder]="cell.getTitle()"
(click)="onClick.emit($event)"
(keyup)="updateValue()"
(change)="url=$any($event.target).value; updateValue()"
(keydown.enter)="onEdited.emit()"
(keydown.esc)="onStopEditing.emit()">
<div [hidden]="true" [innerHTML]="cell.getValue()" #htmlValue></div>
`,
})
export class CustomEditorComponent extends DefaultEditor implements AfterViewInit {

@ViewChild('name') name!: ElementRef;
@ViewChild('url') url!: ElementRef;
@ViewChild('htmlValue') htmlValue!: ElementRef;
name: string = '';
url: string = '';

constructor() {
super();
}

ngAfterViewInit() {
if (this.cell.newValue !== '') {
this.name.nativeElement.value = this.getUrlName();
this.url.nativeElement.value = this.getUrlHref();
const re = this.cell.getValue().match(/<a href="([^"]*)">([^<]*)<\/a>/);
if (re !== null) {
this.url = re[1];
this.name = re[2];
}
}

updateValue() {
const href = this.url.nativeElement.value;
const name = this.name.nativeElement.value;
this.cell.newValue = `<a href='${href}'>${name}</a>`;
}

getUrlName(): string {
return this.htmlValue.nativeElement.innerText;
}

getUrlHref(): string {
return this.htmlValue.nativeElement.querySelector('a').getAttribute('href');
this.cell.setValue(`<a href='${this.url}'>${this.name}</a>`);
}
}

0 comments on commit 1b6c277

Please sign in to comment.