Adornments in EJ2 React NumericTextBox control

28 Dec 202524 minutes to read

Adornments allow you to add custom elements before or after the numeric textbox using the prependTemplate and appendTemplate properties. These elements can include currency symbols, unit labels, or action icons to provide context and quick actions without affecting numeric behavior or float label functionality.

Common Use Cases

  • Currency Symbols: Add indicators like $, €, ¥ for monetary inputs.
  • Unit Labels: Show measurement units (kg, cm, km).
  • Action Icons: Include buttons for clear, reset, or custom actions.
  • Visual Context: Display icons for input type or status.

Adding Adornments to NumericTextBox

Use prependTemplate and appendTemplate to inject HTML content before and after the masked input respectively. These templates do not alter mask behavior and support any inline HTML or icon.

prependTemplate: Renders elements before the numeric textbox.
appendTemplate: Renders elements after the numeric textbox.

The following example demonstrates how to add adornments in the NumericTextBox control.

[Class-component]

import * as React from 'react';
import * as ReactDOM from "react-dom";
import { NumericTextBoxComponent } from '@syncfusion/ej2-react-inputs';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.iconNumericObj = React.createRef();
    this.prepenNumericObj = React.createRef();
    this.appendNumericObj = React.createRef();
  }

  onPriceChange = () => {
    this.appendNumericObj.current.value = this.prepenNumericObj.current.value * 5;
  };

  onKgChange = () => {
    this.prepenNumericObj.current.value = this.appendNumericObj.current.value / 5;
  };

  prependTemplate = () => {
    return (
      <>
        <span className="e-icons e-menu"></span>
        <span className="e-input-separator"></span>
        <span className="e-icons e-search"></span>
        <span className="e-input-separator"></span>
      </>
    );
  };

  appendTemplate = () => {
    return <span>kg</span>;
  };

  prependIconTemplate = () => {
    const handleResetClick = () => {
      this.iconNumericObj.current.value = null;
    };
    return (
      <>
        <span
          className="e-icons e-reset"
          title="Reset"
          onClick={handleResetClick}
        ></span>
        <span className="e-input-separator"></span>
      </>
    );
  };

  appendIconTemplate = () => {
    const handleSubractClick = () => {
      this.iconNumericObj.current.value = this.iconNumericObj.current.value - 1;
    };
    const handlePlusClick = () => {
      this.iconNumericObj.current.value = this.iconNumericObj.current.value + 1;
    };
    return (
      <>
        <span className="e-input-separator"></span>
        <span
          className="e-icons e-horizontal-line"
          onClick={handleSubractClick}
        ></span>
        <span className="e-input-separator"></span>
        <span className="e-icons e-plus" onClick={handlePlusClick}></span>
      </>
    );
  };

  render() {
    return (
      <div className="control-pane">
        <div className="col-lg-12 control-section">
          <div className="content-wrapper sample-numeric-icon">
            <div className="row custom-margin">
              <NumericTextBoxComponent
                ref={this.prepenNumericObj}
                floatLabelType="Auto"
                cssClass="e-prepend-numeric"
                value={1}
                placeholder="Enter the price"
                prependTemplate={this.prependTemplate}
                change={this.onPriceChange}
              />
            </div>
            <div className="row custom-margin">
              <NumericTextBoxComponent
                ref={this.appendNumericObj}
                floatLabelType="Auto"
                step={1}
                value={5}
                placeholder="Enter the kg"
                appendTemplate={this.appendTemplate}
                change={this.onKgChange}
              />
            </div>
            <div className="row custom-margin-row">
              <NumericTextBoxComponent
                ref={this.iconNumericObj}
                floatLabelType="Auto"
                placeholder="Enter the Number"
                value={10}
                showSpinButton={false}
                prependTemplate={this.prependIconTemplate}
                appendTemplate={this.appendIconTemplate}
              />
            </div>
          </div>
        </div>
      </div>
    );
  }
}
ReactDOM.render(<App />,document.getElementById('sample'));
import * as React from "react";
import * as ReactDOM from "react-dom";
import { NumericTextBoxComponent } from '@syncfusion/ej2-react-inputs';
import { ChangeEventArgs } from '@syncfusion/ej2-inputs';

interface AdornmentsState {}

export default class App extends React.Component<{}, AdornmentsState> {
  iconNumericObj: React.RefObject<NumericTextBoxComponent> = React.createRef();
  prepenNumericObj: React.RefObject<NumericTextBoxComponent> = React.createRef();
  appendNumericObj: React.RefObject<NumericTextBoxComponent> = React.createRef();

  constructor(props: {}) {
    super(props);
  }

  onPriceChange = (): void => {
    if (this.appendNumericObj.current && this.prepenNumericObj.current) {
      this.appendNumericObj.current.value = 
        (this.prepenNumericObj.current.value as number) * 5;
    }
  };

  onKgChange = (): void => {
    if (this.prepenNumericObj.current && this.appendNumericObj.current) {
      this.prepenNumericObj.current.value = 
        (this.appendNumericObj.current.value as number) / 5;
    }
  };

  prependTemplate = (): React.ReactNode => {
    return (
      <>
        <span className="e-icons e-menu"></span>
        <span className="e-input-separator"></span>
        <span className="e-icons e-search"></span>
        <span className="e-input-separator"></span>
      </>
    );
  };

  appendTemplate = (): React.ReactNode => {
    return <span>kg</span>;
  };

  prependIconTemplate = (): React.ReactNode => {
    const handleResetClick = (): void => {
      if (this.iconNumericObj.current) {
        this.iconNumericObj.current.value = null;
      }
    };
    return (
      <>
        <span
          className="e-icons e-reset"
          title="Reset"
          onClick={handleResetClick}
        ></span>
        <span className="e-input-separator"></span>
      </>
    );
  };

  appendIconTemplate = (): React.ReactNode => {
    const handleSubractClick = (): void => {
      if (this.iconNumericObj.current) {
        this.iconNumericObj.current.value = 
          (this.iconNumericObj.current.value as number) - 1;
      }
    };
    const handlePlusClick = (): void => {
      if (this.iconNumericObj.current) {
        this.iconNumericObj.current.value = 
          (this.iconNumericObj.current.value as number) + 1;
      }
    };
    return (
      <>
        <span className="e-input-separator"></span>
        <span
          className="e-icons e-horizontal-line"
          onClick={handleSubractClick}
        ></span>
        <span className="e-input-separator"></span>
        <span className="e-icons e-plus" onClick={handlePlusClick}></span>
      </>
    );
  };

  render(): React.ReactNode {
    return (
      <div className="control-pane">
        <div className="col-lg-12 control-section">
          <div className="content-wrapper sample-numeric-icon">
            <div className="row custom-margin">
              <NumericTextBoxComponent
                ref={this.prepenNumericObj}
                floatLabelType="Auto"
                cssClass="e-prepend-numeric"
                value={1}
                placeholder="Enter the price"
                prependTemplate={this.prependTemplate}
                change={this.onPriceChange}
              />
            </div>
            <div className="row custom-margin">
              <NumericTextBoxComponent
                ref={this.appendNumericObj}
                floatLabelType="Auto"
                step={1}
                value={5}
                placeholder="Enter the kg"
                appendTemplate={this.appendTemplate}
                change={this.onKgChange}
              />
            </div>
            <div className="row custom-margin-row">
              <NumericTextBoxComponent
                ref={this.iconNumericObj}
                floatLabelType="Auto"
                placeholder="Enter the Number"
                value={10}
                showSpinButton={false}
                prependTemplate={this.prependIconTemplate}
                appendTemplate={this.appendIconTemplate}
              />
            </div>
          </div>
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />,document.getElementById('sample'));

You can view the demo here: NumericTextBox Adornments demo.

[Functional-component]

import * as React from "react";
import * as ReactDOM from "react-dom";
import { useRef } from 'react';

import { NumericTextBoxComponent } from '@syncfusion/ej2-react-inputs';

function App(){
    const iconNumericObj = useRef(null);
    const prepenNumericObj = useRef(null);
    const appendNumericObj = useRef(null);
    const onPriceChange = () => {
        appendNumericObj.current.value = prepenNumericObj.current.value * 5;
    };
    const onKgChange = () => {
        prepenNumericObj.current.value = appendNumericObj.current.value / 5;
    };
    const prependTemplate = () => {
        return (<>
            <span className="e-icons e-menu"></span><span className="e-input-separator"></span><span className="e-icons e-search"></span><span className="e-input-separator"></span>
        </>);
    };
    const appendTemplate = () => {
        return (<>
            <span>kg</span>
        </>);
    };
    const prependIconTemplate = () => {
        const handleResetClick = () => {
            iconNumericObj.current.value = null;
        };
        return (<>
            <span className="e-icons e-reset" title="Reset" onClick={handleResetClick}></span><span className="e-input-separator"></span>
        </>);
    };
    const appendIconTemplate = () => {
        const handleSubractClick = () => {
            iconNumericObj.current.value = iconNumericObj.current.value - 1;
        };
        const handlePlusClick = () => {
            iconNumericObj.current.value = iconNumericObj.current.value + 1;
        };
        return (<>
            <span className="e-input-separator"></span><span className="e-icons e-horizontal-line" onClick={handleSubractClick}></span><span className="e-input-separator"></span><span className="e-icons e-plus" onClick={handlePlusClick}></span>
        </>);
    };
    return (<div className='control-pane'>
            <div className="col-lg-12 control-section">
                <div className="content-wrapper sample-numeric-icon">
                    <div className="row custom-margin">
                        <NumericTextBoxComponent ref={prepenNumericObj} floatLabelType='Auto' cssClass='e-prepend-numeric' value={1} placeholder='Enter the price' prependTemplate={prependTemplate} change={onPriceChange}/>
                    </div>
                    <div className="row custom-margin">
                        <NumericTextBoxComponent ref={appendNumericObj} floatLabelType='Auto' step={1} value={5} placeholder='Enter the kg' appendTemplate={appendTemplate} change={onKgChange}/>
                    </div>
                    <div className="row custom-margin-row">
                        <NumericTextBoxComponent ref={iconNumericObj} floatLabelType='Auto' placeholder='Enter the Number' value={10} showSpinButton={false} prependTemplate={prependIconTemplate} appendTemplate={appendIconTemplate}/>
                    </div>
                </div>
            </div>
        </div>);
};
ReactDOM.render(<App />,document.getElementById('sample'));
import * as React from "react";
import * as ReactDOM from "react-dom";
import { useRef } from 'react';
import { NumericTextBoxComponent } from '@syncfusion/ej2-react-inputs';

function App(){
  const iconNumericObj = useRef<NumericTextBoxComponent>(null);
  const prepenNumericObj = useRef<NumericTextBoxComponent>(null);
  const appendNumericObj = useRef<NumericTextBoxComponent>(null);

  const onPriceChange = (): void => {
    if (appendNumericObj.current && prepenNumericObj.current) {
      appendNumericObj.current.value = 
        (prepenNumericObj.current.value as number) * 5;
    }
  };

  const onKgChange = (): void => {
    if (prepenNumericObj.current && appendNumericObj.current) {
      prepenNumericObj.current.value = 
        (appendNumericObj.current.value as number) / 5;
    }
  };

  const prependTemplate = () => {
    return (
      <>
        <span className="e-icons e-menu"></span>
        <span className="e-input-separator"></span>
        <span className="e-icons e-search"></span>
        <span className="e-input-separator"></span>
      </>
    );
  };

  const appendTemplate = () => {
    return (
      <>
        <span>kg</span>
      </>
    );
  };

  const prependIconTemplate = () => {
    const handleResetClick = (): void => {
      if (iconNumericObj.current) {
        iconNumericObj.current.value = null;
      }
    };
    return (
      <>
        <span
          className="e-icons e-reset"
          title="Reset"
          onClick={handleResetClick}
        ></span>
        <span className="e-input-separator"></span>
      </>
    );
  };

  const appendIconTemplate = () => {
    const handleSubractClick = (): void => {
      if (iconNumericObj.current) {
        iconNumericObj.current.value = 
          (iconNumericObj.current.value as number) - 1;
      }
    };

    const handlePlusClick = (): void => {
      if (iconNumericObj.current) {
        iconNumericObj.current.value = 
          (iconNumericObj.current.value as number) + 1;
      }
    };

    return (
      <>
        <span className="e-input-separator"></span>
        <span
          className="e-icons e-horizontal-line"
          onClick={handleSubractClick}
        ></span>
        <span className="e-input-separator"></span>
        <span className="e-icons e-plus" onClick={handlePlusClick}></span>
      </>
    );
  };

  return (
    <div className="control-pane">
      <div className="col-lg-12 control-section">
        <div className="content-wrapper sample-numeric-icon">
          <div className="row custom-margin">
            <NumericTextBoxComponent
              ref={prepenNumericObj}
              floatLabelType="Auto"
              cssClass="e-prepend-numeric"
              value={1}
              placeholder="Enter the price"
              prependTemplate={prependTemplate}
              change={onPriceChange}
            />
          </div>
          <div className="row custom-margin">
            <NumericTextBoxComponent
              ref={appendNumericObj}
              floatLabelType="Auto"
              step={1}
              value={5}
              placeholder="Enter the kg"
              appendTemplate={appendTemplate}
              change={onKgChange}
            />
          </div>
          <div className="row custom-margin-row">
            <NumericTextBoxComponent
              ref={iconNumericObj}
              floatLabelType="Auto"
              placeholder="Enter the Number"
              value={10}
              showSpinButton={false}
              prependTemplate={prependIconTemplate}
              appendTemplate={appendIconTemplate}
            />
          </div>
        </div>
      </div>
    </div>
  );
};
ReactDOM.render(<App />,document.getElementById('sample'));

You can view the demo here: NumericTextBox Adornments demo.