Adornments in EJ2 React TextBox control

28 Dec 202524 minutes to read

Adornments allow you to add custom elements before or after the TextBox using prependTemplate and appendTemplate. These elements can include icons, text labels, or action buttons to improve usability and provide visual context.

Overview

Adornments are useful for:

  • Visual Context: Adding icons that indicate the expected input type (e.g., user icon for username, envelope icon for email)
  • Functional Enhancement: Including action buttons such as password visibility toggles or clear buttons
  • Input Validation: Displaying validation status icons or error indicators
  • Unit Indicators: Showing currency symbols, temperature units, domain extensions, or measurement units
  • Accessibility: Providing visual and interactive guidance to help users input and improve discoverability

Common Use Cases

  • Visual Indicators: Icons for expected input type (e.g., user icon for username, envelope icon for email).
  • Functional Enhancements: Buttons for password visibility toggle or clear input.
  • Validation Status: Icons for error or success indicators.
  • Unit Indicators: Currency symbols, measurement units, or domain extensions.

Adding Adornments to TextBox

Use prependTemplate and appendTemplate properties to add custom HTML content before and after the TextBox.

  • prependTemplate: Renders elements before the TextBox.
  • appendTemplate: Renders elements after the TextBox.

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

[Class-component]

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

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.appendTextboxObj = React.createRef();
    this.iconTextboxObj = React.createRef();
  }

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

  appendTemplate = () => {
    const handleClick = (e) => {
      let textIcon = e.target;
      if (textIcon) {
        if (this.appendTextboxObj.current.type === 'text') {
          this.appendTextboxObj.current.type = 'Password';
          textIcon.className = 'e-icons e-eye-slash';
        } else {
          this.appendTextboxObj.current.type = 'text';
          textIcon.className = 'e-icons e-eye';
        }
      }
    };
    return (
      <>
        <span className="e-input-separator"></span>
        <span
          id="text-icon"
          className="e-icons e-eye"
          onClick={handleClick}
        ></span>
      </>
    );
  };

  prependIconTemplate = () => {
    return (
      <>
        <span className="e-icons e-people"></span>
        <span className="e-input-separator"></span>
      </>
    );
  };

  appendIconTemplate = () => {
    const handleDeleteClick = () => {
      this.iconTextboxObj.current.value = '';
    };
    return (
      <>
        <span>.com</span>
        <span className="e-input-separator"></span>
        <span
          className="e-icons e-trash"
          onClick={handleDeleteClick}
        ></span>
      </>
    );
  };

  render() {
    return (
      <div className='control-pane'>
        <div className='col-lg-12 control-section adornment-textbox'>
          <div className="content-wrapper sample-icon">
            <div className="row">
              <TextBoxComponent
                placeholder="Enter your Name"
                cssClass="e-prepend-textbox"
                floatLabelType="Auto"
                prependTemplate={this.prependTemplate}
              />
            </div>
            <div className="row">
              <TextBoxComponent
                ref={this.appendTextboxObj}
                placeholder="Password"
                floatLabelType="Auto"
                cssClass="e-eye-icon"
                appendTemplate={this.appendTemplate}
              />
            </div>
            <div className="row custom-margin-row">
              <TextBoxComponent
                ref={this.iconTextboxObj}
                placeholder="Enter the Mail Address"
                cssClass="e-icon-textbox"
                floatLabelType="Auto"
                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 { TextBoxComponent } from '@syncfusion/ej2-react-inputs';

interface AdornmentsState {}

export default class App extends React.Component<{}, AdornmentsState> {
  private appendTextboxObj = React.createRef<TextBoxComponent>();
  private iconTextboxObj = React.createRef<TextBoxComponent>();

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

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

  appendTemplate = (): React.ReactNode => {
    const handleClick = (e: React.MouseEvent<HTMLSpanElement>): void => {
      const textIcon = e.target as HTMLSpanElement;
      if (textIcon && this.appendTextboxObj.current) {
        if (this.appendTextboxObj.current.type === 'text') {
          this.appendTextboxObj.current.type = 'Password';
          textIcon.className = 'e-icons e-eye-slash';
        } else {
          this.appendTextboxObj.current.type = 'text';
          textIcon.className = 'e-icons e-eye';
        }
      }
    };
    return (
      <>
        <span className="e-input-separator"></span>
        <span
          id="text-icon"
          className="e-icons e-eye"
          onClick={handleClick}
        ></span>
      </>
    );
  };

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

  appendIconTemplate = (): React.ReactNode => {
    const handleDeleteClick = (): void => {
      if (this.iconTextboxObj.current) {
        this.iconTextboxObj.current.value = '';
      }
    };
    return (
      <>
        <span>.com</span>
        <span className="e-input-separator"></span>
        <span
          className="e-icons e-trash"
          onClick={handleDeleteClick}
        ></span>
      </>
    );
  };

  render(): React.ReactNode {
    return (
      <div className='control-pane'>
        <div className='col-lg-12 control-section adornment-textbox'>
          <div className="content-wrapper sample-icon">
            <div className="row">
              <TextBoxComponent
                placeholder="Enter your Name"
                cssClass="e-prepend-textbox"
                floatLabelType="Auto"
                prependTemplate={this.prependTemplate}
              />
            </div>
            <div className="row">
              <TextBoxComponent
                ref={this.appendTextboxObj}
                placeholder="Password"
                floatLabelType="Auto"
                cssClass="e-eye-icon"
                appendTemplate={this.appendTemplate}
              />
            </div>
            <div className="row custom-margin-row">
              <TextBoxComponent
                ref={this.iconTextboxObj}
                placeholder="Enter the Mail Address"
                cssClass="e-icon-textbox"
                floatLabelType="Auto"
                prependTemplate={this.prependIconTemplate}
                appendTemplate={this.appendIconTemplate}
              />
            </div>
          </div>
        </div>
      </div>
    );
  }
}
ReactDOM.render(<App />,document.getElementById('sample'));

You can view the demo here: TextBox Adornments demo.

[Functional-component]

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

function App() {
  const appendTextboxRef = React.useRef(null);
  const iconTextboxRef = React.useRef(null);

  const prependTemplate = () => (
    <>
      <span className="e-icons e-user"></span>
      <span className="e-input-separator"></span>
    </>
  );

  const appendTemplate = () => {
    const handleClick = (e) => {
      const textIcon = e.target;
      const inst = appendTextboxRef.current;
      if (!inst) return;

      if (inst.type === 'text') {
        inst.type = 'password';
        inst.dataBind();
        textIcon.className = 'e-icons e-eye-slash';
      } else {
        inst.type = 'text';
        inst.dataBind();
        textIcon.className = 'e-icons e-eye';
      }
    };

    return (
      <>
        <span className="e-input-separator"></span>
        <span id="text-icon" className="e-icons e-eye" onClick={handleClick}></span>
      </>
    );
  };

  const prependIconTemplate = () => (
    <>
      <span className="e-icons e-people"></span>
      <span className="e-input-separator"></span>
    </>
  );

  const appendIconTemplate = () => {
    const handleDeleteClick = () => {
      const inst = iconTextboxRef.current;
      if (!inst) return;
      inst.value = '';
      inst.dataBind();
    };
    return (
      <>
        <span>.com</span>
        <span className="e-input-separator"></span>
        <span className="e-icons e-trash" onClick={handleDeleteClick}></span>
      </>
    );
  };

  return (
    <div className='control-pane'>
      <div className='col-lg-12 control-section adornment-textbox'>
        <div className="content-wrapper sample-icon">
          <div className="row">
            <TextBoxComponent
              placeholder="Enter your Name"
              cssClass="e-prepend-textbox"
              floatLabelType="Auto"
              prependTemplate={prependTemplate}
            />
          </div>

          <div className="row">
            <TextBoxComponent
              ref={appendTextboxRef}
              placeholder="Password"
              type="password"
              floatLabelType="Auto"
              cssClass="e-eye-icon"
              appendTemplate={appendTemplate}
            />
          </div>

          <div className="row custom-margin-row">
            <TextBoxComponent
              ref={iconTextboxRef}
              placeholder="Enter the Mail Address"
              cssClass="e-icon-textbox"
              floatLabelType="Auto"
              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 { TextBoxComponent } from '@syncfusion/ej2-react-inputs';

function App() {
  const appendTextboxObj = React.useRef<TextBoxComponent>(null);
  const iconTextboxObj = React.useRef<TextBoxComponent>(null);

  const prependTemplate = () => (
    <>
      <span className="e-icons e-user"></span>
      <span className="e-input-separator"></span>
    </>
  );

  const appendTemplate = () => {
    const handleClick = (e: React.MouseEvent<HTMLSpanElement>) => {
      const textIcon = e.currentTarget;
      if (appendTextboxObj.current) {
        if (appendTextboxObj.current.type === 'text') {
          appendTextboxObj.current.type = 'Password';
          textIcon.className = 'e-icons e-eye-slash';
        } else {
          appendTextboxObj.current.type = 'text';
          textIcon.className = 'e-icons e-eye';
        }
      }
    };
    return (
      <>
        <span className="e-input-separator"></span>
        <span id="text-icon" className="e-icons e-eye" onClick={handleClick}></span>
      </>
    );
  };

  const prependIconTemplate = () => (
    <>
      <span className="e-icons e-people"></span>
      <span className="e-input-separator"></span>
    </>
  );

  const appendIconTemplate = () => {
    const handleDeleteClick = () => {
      if (iconTextboxObj.current) {
        iconTextboxObj.current.value = '';
      }
    };
    return (
      <>
        <span>.com</span>
        <span className="e-input-separator"></span>
        <span className="e-icons e-trash" onClick={handleDeleteClick}></span>
      </>
    );
  };
  return (
    <div className="control-pane">
      <div className="col-lg-12 control-section adornment-textbox">
        <div className="content-wrapper sample-icon">
          <div className="row">
            <TextBoxComponent
              placeholder="Enter your Name"
              cssClass="e-prepend-textbox"
              floatLabelType="Auto"
              prependTemplate={prependTemplate}
            />
          </div>
          <div className="row">
            <TextBoxComponent
              ref={appendTextboxObj}
              placeholder="Password"
              floatLabelType="Auto"
              cssClass="e-eye-icon"
              appendTemplate={appendTemplate}
            />
          </div>
          <div className="row custom-margin-row">
            <TextBoxComponent
              ref={iconTextboxObj}
              placeholder="Enter the Mail Address"
              cssClass="e-icon-textbox"
              floatLabelType="Auto"
              prependTemplate={prependIconTemplate}
              appendTemplate={appendIconTemplate}
            />
          </div>
        </div>
      </div>
    </div>
  );
}

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

You can view the demo here: TextBox Adornments demo.