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 = {} })
targetId
string
default: "survey-container"

The ID of the container element where the plugin will be injected.

position
string
default: "top"

The position where the plugin should be injected. Can be ‘top’ or ‘bottom’.

styles
object

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:

  1. Extend the Plugin Class

    Start by creating a new class that extends Plugin:

    class CustomPlugin extends Plugin {
        // Your custom code here
    }
    
  2. 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;
    }
    
  3. 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>`;
    }
    
  4. 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
    }
    
  5. 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);