Generalise abstract Table: rename generic to TRow, add docs
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,13 @@ export abstract class Table<TRow extends Object> {
|
|||||||
this.messageEl = messageElement === undefined ? document.createElement("p") : messageElement;
|
this.messageEl = messageElement === undefined ? document.createElement("p") : messageElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the table headers from the provided example object and the headers orders and names if provided (otherwise inferred)
|
||||||
|
* @param exampleObject An example object of TRow, e.g. User = { id: 0, name: "Name"}. Used to store the types for each column.
|
||||||
|
* @param displayNamesAndOrder The order and names of the columns on the table.
|
||||||
|
* e.g. User = { fullname: "Full Name", id: "User ID" }, the headers would be "Full Name" and "User ID" in column order and headers,
|
||||||
|
* @return A array of {@link Header<TRow>} type shape that holds the header/column info.
|
||||||
|
*/
|
||||||
createHeadersFromType(
|
createHeadersFromType(
|
||||||
exampleObject: TRow, // Needed for runtime, since types don't exist in JS.
|
exampleObject: TRow, // Needed for runtime, since types don't exist in JS.
|
||||||
displayNamesAndOrder?: Record<keyof TRow, string>
|
displayNamesAndOrder?: Record<keyof TRow, string>
|
||||||
@@ -59,6 +66,9 @@ export abstract class Table<TRow extends Object> {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the header values on the header row from the {@link headers} object on this object.
|
||||||
|
*/
|
||||||
setHeaderRow() {
|
setHeaderRow() {
|
||||||
const thead = document.createElement("thead");
|
const thead = document.createElement("thead");
|
||||||
const headerRow = document.createElement("tr");
|
const headerRow = document.createElement("tr");
|
||||||
@@ -73,13 +83,15 @@ export abstract class Table<TRow extends Object> {
|
|||||||
this.table.appendChild(thead);
|
this.table.appendChild(thead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the CSS for tables into the html file for proper styling.
|
* Loads the CSS for tables into the html file for custom styling.
|
||||||
|
* @param relativePathAndName The path to go to for the cess file, including the filename and extension.
|
||||||
*/
|
*/
|
||||||
loadCSS() {
|
loadCSS(relativePathAndName: string) {
|
||||||
const link = document.createElement("link");
|
const link = document.createElement("link");
|
||||||
link.rel = "stylesheet"
|
link.rel = "stylesheet"
|
||||||
link.href = "../css/table.css"; // Relative path from JS folder.
|
link.href = relativePathAndName;
|
||||||
link.type = 'text/css';
|
link.type = 'text/css';
|
||||||
document.head.appendChild(link);
|
document.head.appendChild(link);
|
||||||
}
|
}
|
||||||
@@ -100,6 +112,10 @@ export abstract class Table<TRow extends Object> {
|
|||||||
this.tableBody.appendChild(row)
|
this.tableBody.appendChild(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends multiple rows to the table, at the end off the table.
|
||||||
|
* @param data The rows to append to the table, in shape of {@link TRow}.
|
||||||
|
*/
|
||||||
appendRows(data: TRow[]): void {
|
appendRows(data: TRow[]): void {
|
||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
this.setMessage("No data to append. Empty list provided.")
|
this.setMessage("No data to append. Empty list provided.")
|
||||||
@@ -177,20 +193,35 @@ export abstract class Table<TRow extends Object> {
|
|||||||
this.appendRows(data)
|
this.appendRows(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
getMessageElement() {
|
/**
|
||||||
|
* Get the message element for the table.
|
||||||
|
* @return The HTMLElement thats used for showing messaged. Or null if its not set.
|
||||||
|
*/
|
||||||
|
getMessageElement(): HTMLElement | null {
|
||||||
return this.messageEl;
|
return this.messageEl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the {@link messageEl}.textContent value to "". If the message element is not set it does nothing.
|
||||||
|
*/
|
||||||
clearMessage() {
|
clearMessage() {
|
||||||
if (!this.messageEl) return;
|
if (!this.messageEl) return;
|
||||||
this.messageEl.textContent = ""
|
this.messageEl.textContent = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends a message to the alread existing table message, if the message element is set. Works even if current message is empty ("").
|
||||||
|
* @param message The message to append to the current message.
|
||||||
|
*/
|
||||||
appendMessage(message: string) {
|
appendMessage(message: string) {
|
||||||
if (!this.messageEl) return;
|
if (!this.messageEl) return;
|
||||||
this.messageEl.textContent = `${this.messageEl.textContent} ${message}`
|
this.messageEl.textContent = `${this.messageEl.textContent} ${message}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the message, overwriting what it was before. Id the message element is not set, it does nothing.
|
||||||
|
* @param message The message to set the message element to.
|
||||||
|
*/
|
||||||
setMessage(message: string) {
|
setMessage(message: string) {
|
||||||
if (!this.messageEl) return;
|
if (!this.messageEl) return;
|
||||||
this.clearMessage();
|
this.clearMessage();
|
||||||
@@ -198,8 +229,8 @@ export abstract class Table<TRow extends Object> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Header<R> = {
|
type Header<TRow> = {
|
||||||
key: keyof R; // The name of the field.
|
key: keyof TRow; // The name of the field.
|
||||||
value: string; // The name of the header cell
|
value: string; // The name of the header cell
|
||||||
type: string; // The type of the field, can be string since typesof are returned as strings.
|
type: string; // The type of the field, can be string since typesof are returned as strings.
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user