hermes-web-cli/wwwroot/list-component.js

103 lines
3.3 KiB
JavaScript

// Simplified List component using urlwidget pattern
// This approach follows the bricks-framework best practices by delegating item rendering to separate .ui files
bricks.List = class extends bricks.VBox {
constructor(opts) {
// Ensure opts has options property
if (!opts) opts = {};
if (!opts.options) opts.options = {};
// Set default dimensions if not provided
if (!opts.options.width) opts.options.width = '100%';
if (!opts.options.height) opts.options.height = '100%';
super(opts);
this.data_url = opts.data_url || null;
this.items = opts.items || [];
this.item_template_url = opts.item_template_url || null; // URL to the item template .ui file
this.itemHeight = opts.itemHeight || 50;
this._loading = false;
// Load data if provided
if (this.data_url) {
this.loadData();
} else if (this.items.length > 0 && this.item_template_url) {
this.renderItems();
}
}
async loadData() {
if (this._loading || !this.data_url) return;
this._loading = true;
try {
const response = await fetch(this.data_url);
if (response.ok) {
const data = await response.json();
this.items = Array.isArray(data) ? data : (data.items || []);
this.renderItems();
} else {
console.error('Failed to load list data:', response.status);
}
} catch (error) {
console.error('Error loading list data:', error);
} finally {
this._loading = false;
}
}
renderItems() {
// Clear existing children by resetting subwidgets array
this.subwidgets = [];
// Create new item containers and add to subwidgets
this.subwidgets = this.items.map((item, index) => {
return {
widgettype: "VBox",
options: {
width: "100%",
height: this.itemHeight + "px"
},
_listItemData: item,
_listItemIndex: index,
binds: [{
wid: "self",
event: "on_parent",
actiontype: "urlwidget",
target: "self",
options: {
url: this.item_template_url,
params: {
item: item,
index: index,
id: "item_" + index
}
},
mode: "replace"
}]
};
});
// In bricks framework, updating subwidgets should automatically trigger re-render
// No need for explicit refresh or invalidate calls
}
// Public method to reload data
reload() {
if (this.data_url) {
this.loadData();
}
}
// Public method to set items directly
setItems(items) {
this.items = items || [];
this.renderItems();
}
};
// Register the List component
bricks.Factory.register('List', bricks.List);
console.log('List component registered - uses urlwidget pattern for item rendering');