Quantity Editor With Increment & Decrement Buttons In Lightning Web Components (LWC)

Quantity Editor With Increment & Decrement Buttons In Lightning Web Components (LWC)

2 Styles - Lightning Experience & Field Service Mobile

🔮 Demo

📜 Code

1️⃣ Style #1 - Lightning Experience

quantityEditorLEX.html

<template>
    <lightning-card variant="Narrow" hide-header="true">
        <div class="slds-card__body slds-card__body_inner">

            <!-- Grid layout with alignment to the right -->
            <div class="slds-grid slds-grid_align-end">

                <!-- Column with button icon for decrease action -->
                <div class="slds-col slds-m-right_small">
                    <lightning-button-icon 
                        data-action="decrease"
                        icon-name="utility:dash" 
                        alternative-text="Remove"
                        title="Remove"
                        onclick={changeQuantity}>
                    </lightning-button-icon>
                </div>

                <!-- Column with number input for quantity -->
                <div class="slds-col slds-m-right_small">
                    <div class="slds-form-element">
                        <div class="slds-form-element__control">
                            <input class="slds-input inputStyling" 
                                type="number" 
                                data-action="update" 
                                variant="label-hidden"
                                value={quantity} 
                                onkeyup={changeQuantity}>
                            </input>
                        </div>
                    </div>
                </div>

                <!-- Column with button icon for increase action -->
                <div class="slds-col">
                    <lightning-button-icon
                        data-action="increase" 
                        icon-name="utility:add" 
                        alternative-text="Add"
                        title="Add" 
                        onclick={changeQuantity}>
                    </lightning-button-icon>
                </div>
            </div>

        </div>
    </lightning-card>
</template>

quantityEditorLEX.css

.inputStyling{
    width: 5rem;
    text-align: center;
}

input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button { 
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    margin: 0; 
}

quantityEditorLEX.js

import { LightningElement } from 'lwc';
export default class quantityEditorLEX extends LightningElement {
    // Initializing quantity variable to 0.
    quantity = 0;

    // Method to handle quantity changes based on the event triggered.
    changeQuantity(event) {

        // Getting the action that needs to be performed from the dataset of the current target of the event.
        let action = event.currentTarget.dataset.action;

        // Checking the action type and performing appropriate actions.
        if (action == 'decrease') {
            // Decreasing the quantity if it's greater than 0.
            let currentQty = this.quantity;
            if (currentQty > 0) {
                this.quantity--;
            }
        } else if (action == 'update') {
            // Updating the quantity with the value entered in the input field.
            this.quantity = event.target.value;
        } else if (action == 'increase') {
            // Increasing the quantity.
            this.quantity++;
        }
    }
}

2️⃣ Style #2 - SFS Field Service Mobile

quantityEditorSFS.html

<template>
    <lightning-card variant="Narrow" hide-header="true">
        <div class="slds-card__body slds-card__body_inner">

            <!-- Grid layout with alignment to the right -->
            <div class="slds-grid slds-grid_align-end quantityEditor">

                <!-- Column with button icon for decrease action -->
                <div class="slds-col slds-m-right_small">
                    <lightning-icon 
                        data-action="decrease" 
                        size="small"
                        icon-name="utility:dash" 
                        alternative-text="Remove" 
                        title="Remove" 
                        onclick={changeQuantity}>
                    </lightning-icon>
                </div>

                <!-- Column with number input for quantity -->
                <div class="slds-col slds-m-right_small">
                    <input
                        type="number" 
                        data-action="update" 
                        value={quantity} 
                        onchange={changeQuantity}>
                    </input>
                </div>

                <!-- Column with button icon for increase action -->
                <div class="slds-col">
                    <lightning-icon
                        data-action="increase" 
                        size="small"
                        icon-name="utility:add" 
                        alternative-text="Add" 
                        title="Add"
                        onclick={changeQuantity}>
                    </lightning-icon>
                </div>
            </div>
        </div>
    </lightning-card>
</template>

quantityEditorSFS.css

.quantityEditor lightning-icon{
    --slds-c-icon-radius-border: 50%;
    --slds-c-icon-color-foreground-default: #2A7AAF;
    padding: 0.25rem;
    border: 2px solid #2A7AAF;
}

.quantityEditor input{
    height: 36px !important;
    border-radius: 0 !important;
    border: none;
    background: #EEEEEE;
    width: 75px;
    text-align: center;    
    border-bottom: 2px solid transparent;
}

.quantityEditor input:focus{
    outline: none;
    border-bottom-color: #2A7AAF;
}

input[type=number]::-webkit-inner-spin-button, 
input[type=number]::-webkit-outer-spin-button { 
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    margin: 0; 
}

quantityEditorSFS.js

The JavaScript logic for this SFS variant is the same as mentioned for the Lightning Experience variant above.

🤔
Why did we use HTML Input instead of lightning-input base component? Though there are styling hooks for the base component, the existing ones didn't support the type of styling we needed. For example: sizing, text alignment

🧩 Components Used