alchemy-widget
Version:
The widget plugin for the AlchemyMVC
248 lines (201 loc) • 5 kB
JavaScript
/**
* The Partial Widget class
*
* @constructor
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.1.6
*
* @param {Object} data
*/
const Partial = Function.inherits('Alchemy.Widget', 'Partial');
/**
* Make this an abstract class
*/
Partial.makeAbstractClass();
/**
* Get the type name
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.1.6
*/
Partial.setStatic(function createClassTypeName() {
return 'partial_' + this.name.underscore();
});
/**
* Set the template to use
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.1.6
*/
Partial.setStatic(function setTemplateFile(name) {
this.constitute(function _setTemplateFile() {
this.template_file = name;
});
});
/**
* Prepare the schema
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.1.6
*/
Partial.constitute(function prepareSchema() {
this.schema.addField('view', 'String', {
title : 'Partial View',
description : 'The actual HWK template to use for rendering this widget',
});
let contents = this.createSchema();
contents.addField('name', 'String');
contents.addField('contents', 'Widgets');
this.schema.addField('contents', contents, {array: true});
});
/**
* Populate the widget
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.2.1
*
* @param {HTMLElement} widget
*/
Partial.setMethod(async function populateWidget() {
let view = this.constructor.template_file || this.config.view;
if (view) {
let options = {
print : false,
};
let variables = {};
await this.addVariablesForRender(variables);
if (this.config?.contents?.length) {
for (let entry of this.config.contents) {
let actual_contents;
if (entry.contents) {
if (entry.contents.config) {
actual_contents = entry.contents.config;
} else if (entry.contents.widgets) {
actual_contents = entry.contents.widgets;
let type = actual_contents?.[0]?.type;
if (type == 'container' || type == 'row') {
actual_contents = actual_contents[0].config?.widgets;
} else {
actual_contents = actual_contents[0];
}
}
}
variables[entry.name] = actual_contents;
}
}
variables.config = this.config;
let placeholder = this.hawkejs_renderer.addSubtemplate(view, options, variables);
// If the widget is already part of the DOM,
// it's being edited and we need to manually kickstart the renderer
if (Blast.isBrowser && document.body.contains(this.widget)) {
await placeholder.getContent();
}
Hawkejs.removeChildren(this.widget);
this.widget.append(placeholder);
}
});
/**
* Allow adding variables for rendering the partial
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.
* @version 0.1.
*/
Partial.setMethod(function addVariablesForRender(variables) {
// To be optionally implemented by child widgets
});
/**
* Get all the sub widgets by their name
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.1.6
*
* @return {Object}
*/
Partial.setMethod(function getSubWidgets() {
let elements = this.widget.queryAllNotNested('[data-section-name]'),
result = {};
for (let element of elements) {
result[element.dataset.sectionName] = element;
}
return result;
});
/**
* Start the editor
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.1.6
*/
Partial.setMethod(function _startEditor() {
let sub_widgets = this.getSubWidgets();
for (let name in sub_widgets) {
let sub_widget = sub_widgets[name];
sub_widget.startEditor();
}
});
/**
* Stop the editor
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.2.2
*/
Partial.setMethod(function _stopEditor() {
let sub_widgets = this.getSubWidgets();
for (let name in sub_widgets) {
let sub_widget = sub_widgets[name];
sub_widget.stopEditor();
}
return this.loadWidget();
});
/**
* Update the config values
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @since 0.1.6
* @version 0.2.3
*
* @return {Object}
*/
Partial.setMethod(function syncConfig() {
let sub_widgets = this.getSubWidgets(),
contents = this.config.contents;
if (!contents) {
contents = [];
this.config.contents = contents;
}
for (let name in sub_widgets) {
let sub_widget = sub_widgets[name];
let widget_config = contents.findByPath('name', name);
if (!widget_config) {
widget_config = {
name,
};
contents.push(widget_config);
}
let value = sub_widget.value,
widget_contents;
if (value?.widgets) {
widget_contents = {
widgets : [{
type : 'row',
config : value,
}]
};
} else {
widget_contents = {
widgets: Array.cast(value)
};
}
widget_config.contents = widget_contents;
}
return this.config;
});