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.
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 |
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
Phoneproduct is loaded, andiPhone16variety is automatically selectedThen a
ToughCaseproduct is loaded and attached to theCasesocket (attachment point).iPhone16case variety is selected to match the phone type.Then a
CardWalletproduct is loaded and attached to theWalletsocket
Listening to events
Controllers on and off methods allow to start and stop listening to controller events.
on(eventName, callback)— listen to the eventoff(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 initializedafterAssembliesBuilt— after all controllers in the hierarchy are loaded and initialized
For example:
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 systemafterInitializeState— 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:
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:
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:
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.