If it’s necessary to change the behavior of the Product Line Editor, the developer can wrap it in a custom “wrapper” component and define certain injections or trigger certain behaviors via the Editor’s controller.
Product Line Editor’s Controller and its methods could be controlled by using a reference.
<template>
<finblick-product-line-editor lwc:ref="lineEditor"
record-id={recordId}
object-api-name={objectApiName}>
</finblick-product-line-editor>
<button onclick={handleCancel}>Cancel</button>
</template>
import { LightningElement, api } from 'lwc';
export default class ProductLineEditorWrapper extends LightningElement {
@api recordId;
@api objectApiName;
handleCancel(event) {
//accessing editor's controller
this.refs.lineEditor.controller.cancel();
}
}
General Information #
Product Line Editor attributes #
| Name | Type | Description |
|---|---|---|
| recordId | Id | Id of a record Line Editor is used for. |
| objectApiName | String | Object API Name of an object Line Editor is used for. |
| controller | Class | Controller gives developer an ability to: – Manipulate Product Line Editor’s data and UI from the outside; – Inject custom logic to fire during certain triggers. |
Product Line Editor Methods #
| Name | Description |
|---|---|
| lifecycleevent | Fires when a Lifecycle Event has happened. |
Lifecycle Events #
Lifecycle Events are events that fire at certain points of component’s lifecycle. All lifecycle events’ details contain the following parameters:
{
eventName: "eventName",
...event-dependant parameters (if any)
}
init #
“init” event fires when the line editor’s engine is initiated.
Record isn’t loaded at this point yet.
Controller methods #
addLineItems #
Arguments
- lineItems – list of line items to add.
Description:
Adds line items with provided payload.
By default, line items are added at the end of last section, in the order provided.
“sectionIndex” key could be added to each of the line items to add them to the end of a specific section instead.
Matching will be executed for all line items containing “productId” key.
Example:
const someItem = {discount: 4};
const blankItem = {};
const targetedSectionItem = {
sectionIndex: 1,
customProductName: "Test"
}
await addLineItems([someItem, blankItem, targetedSectionItem]);
editLineItem #
Arguments
- data – data to update on line item.
Returns an updated line item.
Description: Updates a line item with provided data, while keeping all other fields unchanged.
Die Daten müssen die Schlüssel „sectionIndex“ und „productIndex“ enthalten. Wenn ohne Sektionen gearbeitet wird, ist „sectionIndex“ gleich 0.
If data contains “productId” key with value that’s different from a blank string, matching will be executed for the item.
If data contains “productId” key with a blank string value (“”), “Product” lookup will be cleared. If the targeted line item exists in a DB, it will be deleted upon saving.
Example:
const someItem = {
sectionIndex: 1,
productIndex: 2,
unitPrice: 800
};
await editLineItem(someItem);
dragLineItem #
Arguments
- oldPlacement – placement of line item to be moved.
- newPlacement – placement to move line item to.
Returns a moved line item.
Description: Moves a line item from one place to another.
Example:
const oldPlacement = {
sectionIndex: 2,
productIndex: 3
};
const newPlacement = {
sectionIndex: 1,
productIndex: 0
};
dragLineItem(oldPlacement, newPlacement);
deleteLineItem #
Arguments
- placement – placement of the item to be deleted.
Returns a deleted line item.
Description: Deletes a line item at a specified place.
Example:
const placement = {
sectionIndex: 2,
productIndex: 3
};
deleteLineItem(placement);
addSection #
Description: If working without sections, enables them and groups all existing line items in a single section. Otherwise, adds a section at the end of list.
Example:
addSection();
editSection #
Arguments
- data – data to update on section.
Description: Updates a section with provided data.
Data must contain “sectionIndex“.
If it’s necessary to update section’s line items, use editLineItem instead.
Example:
const data = {
sectionIndex: 1,
name: "Custom Section Name"
};
editSection(data);
dragSection #
Arguments
- oldSectionIndex – index of a section to be moved.
- newSectionIndex – index to move section to.
Description: Moves a section from one place to another.
Example:
const oldSectionIndex = 1;
const newSectionIndex = 2;
dragSection(oldSectionIndex, newSectionIndex);
deleteSection #
Arguments
- sectionIndex – index of a section to be deleted.
Description: Deletes a section at a specified place.
If trying to delete section normally, a confirmation modal will appear.
This method doesn’t open a modal, and will delete the section immediately.
Example:
const sectionIndex = 4;
deleteSection(sectionIndex);
removeAllSections #
Description: If working with sections, disables them.
This action doesn’t delete any items. It groups all existing items in an invisible for user section.
Example:
removeAllSections();
cancel #
Description: Cancels any changes made.
Example:
cancel();
saveLineItems #
Returns an object containing the following keys:
- sections – list of sections;
- uiSettings – reserved for internal use.
Description: Saves any changes made.
Example:
const record = await saveLineItems();
console.log(JSON.stringify(record.sections));
setLoading #
Arguments
- isLoading – loading state (true/false).
Description: Enables/disables component loading.
Example:
setLoading(true);
//wait for some data to load
setLoading(false);
setReadMode #
Arguments
- readMode – mode to set (true/false)
Description: Sets component’s mode to either read mode (true) or edit mode (false).
Example:
setReadMode(true);
//do some changes while user can't edit
setReadMode(false);
expandLineItem #
Arguments
- placement – placement of a line item to be expanded.
Description: Expands a line item at a specific placement, showing additional fields.
Example:
const placement = {
sectionIndex: 2,
productIndex: 3
};
expandLineItem(placement);
expandAllLineItems #
Description: Expands all line items.
shrinkAllLineItems #
Description: Shrinks all line items.
Example:
shrinkAllLineItems();
//do some changes while nobody sees
expandAllLineItems();
injectLifecycleHook #
Arguments
- eventName – name of the event that triggers an injection.
- overwriteFunction – custom function that will be executed when the event is triggered.
Description: Allows a custom functionality to happen during certain injection events.
Examples will be provided in the next section.
Injection event names #
This is the list of all supported injections, when they are triggered, and usage examples.
addlineitems #
Arguments
- lineItems – array of line items that are to be added.
Is triggered when:
- “Add Line Item” is pressed – adds a blank line;
- “Save” is pressed when adding multiple line items;
- “Product” lookup is selected for a line item;
- Controller’s “addLineItems” function is called.
If any of the items contains a non-blank “productId” field, injection is fired after matching. Otherwise, injection is fired immediately.
Injection is fired before totals for items are calculated.
Example:
const injectionFunction = lineItems => {
lineItems.forEach(lineItem => lineItem.customProductName = "test");
};
injectLifecycleHook("addlineitems", injectionFunction);
save #
Arguments
- sections – sections containing line items that are to be saved.
Is triggered when:
- “Save” button is pressed;
- Controller’s “saveLineItems” function is called.
Injection happens before changes are saved to DB.
Example:
const injectionFunction = sections => {
sections.forEach((section, index) => section.name = "test" + index);
};
injectLifecycleHook("save", injectionFunction);
Injection code example
#
<template>
<finblick-product-line-editor lwc:ref="lineEditor"
record-id={recordId}
object-api-name={objectApiName}
onlifecycleevent={handleLifecycleEvent}>
</finblick-product-line-editor>
</template>
import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from "lightning/platformShowToastEvent";
export default class ProductLineEditorWrapper extends LightningElement {
@api recordId;
@api objectApiName;
handleLifecycleEvent(event) {
switch (event.detail.eventName) {
case 'init':
this.handleEngineInit(event);
break;
default:
break;
}
}
handleEngineInit(event) {
const controller = this.refs.lineEditor.controller;
controller.injectLifecycleHook('addlineitems', this.addLineItemsInjection);
controller.injectLifecycleHook('save', this.saveInjection.bind(this));
}
addLineItemsInjection = (lineItems) => {
if (lineItems.some(lineItem => lineItem.productId)) {
const loyaltyDiscount = 15;
lineItems.forEach(lineItem => lineItem.discount = loyaltyDiscount);
const toastEvent = new ShowToastEvent({
title: "Loyalty discount applied.",
message: `We've applied a ${loyaltyDiscount}% discount to item's you've just added as a sign of gratitude.`,
variant: "success"
});
this.dispatchEvent(toastEvent);
}
}
saveInjection(sections) {
const toastEvent = new ShowToastEvent({
title: "Save Injection Triggered.",
message: "Triggered a save injection",
variant: "info"
});
this.dispatchEvent(toastEvent);
}
}
Additional Information #
Section attributes #
Parameters intended for internal use only are omitted
| Name | Type | Description |
|---|---|---|
| name | String | Section name. |
| sectionIndex | Number | Section’s index. |
| total | Number | Section’s total price. |
| lineItems | Array | Section’s items. Item’s structure is described below. |
Line item attributes #
Parameters intended for internal use only are omitted
| Name | Type | Required | Description |
|---|---|---|---|
| id | Id | Line Item’s record Id. | |
| unitPrice | Number | Yes | Line Item’s unit price. |
| unitType | String | Line Item’s unit type. Restricted to the values of “Unit Type” global value set. | |
| quantity | Number | Yes | Line Item’s quantity. |
| discount | Number | Line Item’s discount. | |
| totalPrice | Number | Line Item’s total price. | |
| description | String | Line Item’s description. | |
| customProductName | String | Line Item’s display name. | |
| priceBookEntryId | Id | For Orders and Quotes | Line Item’s Price Book Entry Id. |
| productId | Id | Yes | Line Item’s Product Id. |
| productName | String | Line Item’s Product name. | |
| taxRule | Object | Line Item’s Tax Rule. Contains the following attributes: id – Tax Rule’s Id; name – Tax Rule’s name; percentage – Tax Rule’s rate. | |
| dynamicFields | Object | Line Item’s dynamic fields. These fields are used in dynamic sections. Attributes are fields’ API names. | |
| sectionIndex | Number | Line Item’s section’s index. | |
| productIndex | Number | Line Item’s index within section. |
Placement attributes #
| Name | Type |
|---|---|
| sectionIndex | Number |
| productIndex | Number |