Plugin Class
The Plugin class serves as the foundation for all plugins in RoundtableJS. It provides a structure for creating plugins that can interact with the survey at various lifecycle stages, allowing you to extend the functionality of your surveys.
Constructor
constructor({ targetId = 'survey-container', position = 'top', styles = {} })
The ID of the container element where the plugin will be injected.
The position where the plugin should be injected. Can be ‘top’ or ‘bottom’.
Custom styles to apply to the plugin’s root element.
Properties
targetId
: The ID of the target container.position
: The position of the plugin (‘top’ or ‘bottom’).styles
: The styles for the plugin.pluginId
: A unique ID generated for the plugin.survey
: Reference to the survey instance (set during initialization).
Methods
initialize(survey)
Initialize the plugin with a survey instance and inject it into the DOM.
- Parameters:
survey
(Survey): The survey instance
initialize(survey) {
this.survey = survey;
this.injectPlugin();
}
injectPlugin()
Inject the plugin element into the DOM.
injectPlugin() {
const targetContainer = document.getElementById(this.targetId);
if (!targetContainer) {
console.warn(`Target container with id "${this.targetId}" not found`);
return;
}
let pluginContainer = this.getOrCreatePluginContainer(targetContainer);
const pluginElement = this.createPluginElement();
pluginContainer.appendChild(pluginElement);
}
getOrCreatePluginContainer(targetContainer)
Get or create the container for plugins.
- Parameters:
targetContainer
(HTMLElement): The target container element
- Returns:
HTMLElement
: The plugin container
getOrCreatePluginContainer(targetContainer) {
const containerId = `${this.targetId}-${this.position}-plugins`;
let pluginContainer = document.getElementById(containerId);
if (!pluginContainer) {
pluginContainer = document.createElement('div');
pluginContainer.id = containerId;
if (this.position === 'top') {
targetContainer.insertBefore(pluginContainer, targetContainer.firstChild);
} else {
targetContainer.appendChild(pluginContainer);
}
}
return pluginContainer;
}
createPluginElement()
Create the plugin’s DOM element.
- Returns:
HTMLElement
: The created plugin element
createPluginElement() {
const element = document.createElement('div');
element.id = this.pluginId;
element.innerHTML = this.generateContent();
this.applyStyles(element);
return element;
}
generateContent()
Generate the content for the plugin. This method should be implemented by subclasses.
- Returns:
string
: The HTML content for the plugin
generateContent() {
// To be implemented by subclasses
throw new Error('generateContent method must be implemented by subclasses');
}
applyStyles(element)
Apply styles to the plugin element.
- Parameters:
element
(HTMLElement): The element to style
applyStyles(element) {
Object.assign(element.style, this.styles.root || {});
}
beforePageRender()
Hook called before a page is rendered. To be implemented by subclasses if needed.
beforePageRender() {
// This method is intentionally left empty
}
afterPageRender()
Hook called after a page is rendered. To be implemented by subclasses if needed.
afterPageRender() {
// This method is intentionally left empty
}
beforeSurveyFinish()
Hook called before the survey finishes. To be implemented by subclasses if needed.
beforeSurveyFinish() {
// This method is intentionally left empty
}
destroy()
Remove the plugin from the DOM.
destroy() {
const element = document.getElementById(this.pluginId);
if (element) {
element.remove();
}
}
Creating a Custom Plugin
To create a custom plugin, you’ll extend the Plugin class and implement specific methods. Here’s a step-by-step guide:
-
Extend the Plugin Class
Start by creating a new class that extends Plugin:
class CustomPlugin extends Plugin { // Your custom code here }
-
Implement the Constructor
In the constructor, call the parent constructor and initialize any custom properties:
constructor(props) { super(props); // Initialize custom properties this.customProperty = props.customProperty; }
-
Implement generateContent Method
Override the generateContent method to provide the HTML content for your plugin:
generateContent() { return `<div class="custom-plugin"> <h3>Custom Plugin</h3> <p>${this.customProperty}</p> </div>`; }
-
Implement Lifecycle Methods (Optional)
Override the lifecycle methods to add your custom logic:
beforePageRender() { // Logic to run before each page is rendered } afterPageRender() { // Logic to run after each page is rendered } beforeSurveyFinish() { // Logic to run before the survey finishes }
-
Add Custom Methods (Optional)
Include any additional methods specific to your plugin:
customMethod() { // Your custom functionality }
Example: Custom Header Plugin
This plugin adds a custom header to the survey:
class CustomHeaderPlugin extends Plugin {
constructor(props) {
super({ ...props, position: 'top' });
this.title = props.title || 'Survey';
}
generateContent() {
return `
<header class="custom-header">
<h1>${this.title}</h1>
<p>Welcome to our survey!</p>
</header>
`;
}
applyStyles(element) {
super.applyStyles(element);
const header = element.querySelector('.custom-header');
Object.assign(header.style, {
backgroundColor: '#f0f0f0',
padding: '20px',
textAlign: 'center',
borderBottom: '1px solid #ddd'
});
}
}
// Usage
const headerPlugin = new CustomHeaderPlugin({
title: 'Customer Satisfaction Survey',
styles: {
root: {
marginBottom: '20px'
}
}
});
survey.addPlugin(headerPlugin);