Skip to main content
Skip table of contents

Controller class

Controller class assists in loading configurator blueprints, managing the configuration state, and provides helper methods to a variety of Customizer blueprint-related functions.

Controllers also serve as a core data management interface that a number of other classes rely on:

  • Image views automatically synchronize with the respective controller and automatically repaint when necessary

  • Camera views also synchronize with the controller state and handle the loading and unloading of respective 3D models. Additionally, camera views automatically paint personalization views as necessary.

  • Controllers provide reactive state management that frameworks such as Vue or React can use to drive the user interface state.

Loading a blueprint

In order to start using a controller, create a class instance and pass the initialization parameters. Trigger the load to start the initialization sequence.

CODE
const controller = new DriveCustomizer.Controller({
    apiKey: '...',
    products: ['Product1', 'OverlayProduct2', ...],
    currency: 'USD',
    locale: 'en-US',
    site: 'ecommerce'
});

controller.load();

Controller parameters include:

Parameter

Required

Description

apiKey

Yes

Provide an API key (as thus the Customizer environment) to be used by the controller.

products

Yes

Specify a list of products to be loaded.

Note: the products list may contain an assembly configuration.

preview

No

A future preview date.

Customizer products and components may have associated availability dates; using this parameter allows to preview the products configuration as if it would be configured in the future.

site

No

The target site code or codes.

locale

No

The target locale

currency

No

The target currency to be used for price formatting

disableCaching

No

If specified and is set to true, the controller will disable performance optimizations that would otherwise automatically apply. This flag is useful in the development or staging environment as it allows to preview the product changes as they are being made, without explicitly having to reset the cache.

recipe

No

A recipe object to load the initial configuration from

Note: this parameter should represent a complete recipe, not just a recipe ID.

Product name configuration format

In the simplest form, the initialization product vector shall be a list of applicable product style codes: [ 'StyleCode1', 'StyleCode2', ...]

However, the general format for the product code is:

StartingProductStyleCode(component-selections)~SocketCode,AnotherProductStyleCode(component-selections)~…

This is called assembly initialization string. The assembly code consists of a starting product that may define a number of sockets. The rest of the initialization string consists of zero of more connected product specifications, separated by ~ (tilde) characters.

Each connected product specification consists of a socket code, followed by a style code of a product to be connected.

Both the initial product, and the connected products may optionally specify a list of components that will be automatically selected when an assembly is loaded.

For example:

Phone(iPhone16)~Case,ToughCase(iPhone16)~Wallet,CardWallet

  • A Phone product is loaded, and iPhone16 variety is automatically selected

  • Then a ToughCase product is loaded and attached to the Case socket (attachment point). iPhone16 case variety is selected to match the phone type.

  • Then a CardWallet product is loaded and attached to the Wallet socket

Listening to events

Controllers on and off methods allow to start and stop listening to controller events.

  • on(eventName, callback) — listen to the event

  • off(eventName) — remove event subscription

Namespaces

Multiple event handlers can be attached to the same event. By default, calling off(eventName) will remove all event listeners.

However, controllers allow for fine-grade control as well. If the event name can be in the format eventName.namespace. In this case, calling the off method with the namespace name off('.namespace') will remove only specific event handlers.

Waiting until the controller is in ready state

After the controller loading sequence is kicked off using the load method, the controller state may be incomplete until the full initialization is done. Developers can monitor the initialization state by subscribing to the follow events:

  • afterInitializeBlueprint — triggered the this controller is initialized

  • afterAssembliesBuilt — after all controllers in the hierarchy are loaded and initialized

For example:

CODE
controller.on('afterAssembliedBuilt', () => {
    console.log('Ready!');
});

controller.load();

Handling additional configuration

During the initialization sequence, the controller will trigger additional events that the front-end developers can use to tune or alter the default functionality. For example:

  • initializeAvailability — Fired before the initial state calculation. If the event handler returns a promise, the controller loading sequence is paused until the promise is resolved. The implementation code can use this event to load the inventory availability or pricing data from the host system

  • afterInitializeState — Fired after the initial state calculation. The implementation code can use this event to fine-tune the initial state, for example in response to some external factors (for example, if some components are preselected on the product detail page)

  • getPrice — Fired to calculate a component price. The implementation code can override the default Customizer-driven pricing logic and retrieve product prices from external systems.

  • getInventory — Fired to calculate a component availability. The controller uses the initial inventory state and the current state selections to calculate whether a particular component is available or not.

Specifically, lets say placements A and B both allow a component C to be selected. If the component inventory is 1, and it is selected into the placement A, attempting to select the component into the placement B will fail.

Implementing undo stack or revert functionality

Controller instances can be easily cloned using clone method. A cloned instance is a snapshot of the original blueprint and state configuration.

By managing a current controller instance and a previous instance or a stack of instances it is possible to easily implement an undo or revert functionality.

Conceptually:

CODE
let current = new Controller(...);
await current.load();

// User enters some configuration screen
const revertInstance = current.clone();

// User clicks Cancel button
current = revertInstance;

Accessing configuration state

The controller provides direct blueprint and state accessors though blueprint and state properties respectively. The code written a change-aware library such as Vue or React can use these properties to reactively perform necessary actions, such as UI state updates.

Alternatively, the implementation code can subscribe to stateChanged event to monitor the updates as well.

Updating configuration state

A configuration state can be updated using updateComponent method. The method takes in a placement code that needs to be updated and a component code to be selected:

CODE
controller.updateComponent(placementA, componentC);

The method will perform necessary component validations and will return true if the component was selected successfully or false if the selection is not possible.

If the newly selected component triggers rules that invalidate other components, the controller will automatically attempt to find a replacement:

  • If the invalidated placement has a placeholder, a placeholder will be selected

  • Otherwise a first available component will be selected.

Customizing invalidation logic

The implementation code can alter the out-of-the-box logic by monitoring the pickAlternate event and providing a new component to be selected.

Updating personalization state

The implementation code can use updatePersonalization method to update personalization text (such as one used for embroidery or printing) stored on a placement.

For example:

CODE
controller.updatePersonalization(placementA, text);

The method will perform necessary validations and return whether the text was accepted. The validations and transformations include:

  • Length validation

  • Regular expression match validation

  • Uppercase or lowercase transformation

  • Multiline validation

Saving a recipe

A configured controller can save the current state as a recipe by calling saveRecipe method. The controller will:

  • Perform the first level of validations

  • Submit the design to the server

  • Await the acceptance or rejection state

  • Return the recipe ID to the caller.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.