Getting Started in EJ2 TypeScript Smart TextArea Control

25 Sep 202419 minutes to read

The Smart TextArea is an advanced control designed to elevate the text input experience by providing intelligent autocomplete suggestions for entire sentences through text-generative AI functionality. This control enhances user productivity by predicting and offering relevant completions based on the context of what is being typed.

This section explains how to create a simple Smart TextArea Control and configure its available functionalities in TypeScript, using Essential JS 2 quickstart seed repository.

This application is integrated with the webpack.config.js configuration and uses the latest version of the webpack-cli. It requires node v18.20.x or higher. For more information about webpack and its features, refer to the webpack documentation.

Prerequisites

To get started with application, ensure the following software to be installed in the machine.

Dependencies

The following list of dependencies are required to use the Smart TextArea Control in your application.

|-- @syncfusion/ej2-inputs
    |-- @syncfusion/ej2-base

Set up development environment

Open the command prompt from the required directory, and run the following command to clone the Syncfusion JavaScript (Essential JS 2) quickstart project from GitHub.

git clone https://github.com/SyncfusionExamples/ej2-quickstart-webpack- ej2-quickstart

After cloning the application in the ej2-quickstart folder, run the following command line to navigate to the ej2-quickstart folder.

cd ej2-quickstart

Add Syncfusion JavaScript packages

Syncfusion JavaScript (Essential JS 2) packages are available on the npmjs.com public registry. You can install all Syncfusion JavaScript (Essential JS 2) controls in a single @syncfusion/ej2 package or individual packages for each control.

The quickstart application is preconfigured with the dependent @syncfusion/ej2 package in the ~/package.json file. Use the following command to install the dependent npm packages from the command prompt.

npm install

Import the Syncfusion CSS styles

To render Smart TextArea Control, need to import inputs and its dependent controls styles as given below in the ~/src/styles/index.css file, as shown below:

@import '../../node_modules/@syncfusion/ej2-base/styles/material.css';
@import '../../node_modules/@syncfusion/ej2-inputs/styles/material.css';

Adding TextArea to the application

Add the HTML Smart TextArea tag with the id attribute as default to your index.html file.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 Smart TextArea</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 TextArea Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/20.3.56/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/20.3.56/ej2-inputs/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div>
        <!--Element to render the Smart TextArea control-->
        <textarea id="default"></textarea>
    </div>
</body>

</html>

Then, import the Smart TextArea Control in your src/app/app.ts file and initialize it with the #default. In Smart TextArea, the aiSuggestionHandler property, which sends prompts to the AI model and receives context-aware suggestions. These suggestions appear inline for non-touch devices and as an overlay popup for touch devices by default, helping users type faster and more accurately.

import { SmartTextArea, ChatParameters } from '@syncfusion/ej2-inputs';

let textareaObj: SmartTextArea = new SmartTextArea({
    placeholder: 'Enter your queries here',
    floatLabelType: 'Auto',
    resizeMode: 'Both',
    rows: 3,
    cols: 35,
    userRole: 'Employee communicating with internal team',
    UserPhrases: [
        "Please find the attached report.",
        "Let's schedule a meeting to discuss this further.",
        "Can you provide an update on this task?",
        "I appreciate your prompt response.",
        "Let's collaborate on this project to ensure timely delivery."
    ],
    aiSuggestionHandler: serverAIRequest
});
textareaObj.appendTo('#smart-textarea');

const serverAIRequest = async (settings: ChatParameters) => {
    let output = '';
    try {
        const response = await (window as any).AzureAIRequest(settings) as string;
        output = response;
    } catch (error) {
        console.error("Error:", error);
    }
    return output;
};

Run the application

Run the application in the browser using the following command.

npm start

The following example shows the Smart TextArea control.

In our demonstration, Azure AI is used, but you can integrate any text-generative AI of your choice.

import { SmartTextArea } from '@syncfusion/ej2-inputs';
import { DropDownList } from '@syncfusion/ej2-dropdowns';
import { CheckBox } from '@syncfusion/ej2-buttons';
import { NumericTextBox, TextBox, ChangedEventArgs } from '@syncfusion/ej2-inputs';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

/**
 * Smart TextArea sample
 */
const serverAIRequest = async (settings: any) => {
    let output = '';
    try {
        console.log(settings);
        const response = await (window as any).AzureAIRequest(settings) as string;
        console.log("Success:", response);
        output = response;
    } catch (error) {
        console.error("Error:", error);
    }
    return output;
};

let textareaObj: SmartTextArea = new SmartTextArea({
    placeholder: 'Enter your queries here',
    floatLabelType: 'Auto',
    resizeMode: 'Both',
    rows: 3,
    cols: 35,
    userRole: 'Employee communicating with internal team',
    UserPhrases: [
        "Please find the attached report.",
        "Let's schedule a meeting to discuss this further.",
        "Can you provide an update on this task?",
        "I appreciate your prompt response.",
        "Let's collaborate on this project to ensure timely delivery."
    ],
    aiSuggestionHandler: serverAIRequest
});
textareaObj.appendTo('#smart-textarea');

const rolesData: string[] = [
        "Maintainer of an open-source project replying to GitHub issues",
        "Employee communicating with internal team",
        "Customer support representative responding to customer queries",
        "Sales representative responding to client inquiries"
];

let presets: any = [
    {
        userRole: "Maintainer of an open-source project replying to GitHub issues",
        userPhrases: [
            "Thank you for contacting us.",
            "To investigate, we'll need a repro as a public Git repo.",
            "Could you please post a screenshot of NEED_INFO?",
            "This sounds like a usage question. This issue tracker is intended for bugs and feature proposals. Unfortunately, we don't have the capacity to answer general usage questions and would recommend StackOverflow for a faster response.",
            "We don't accept ZIP files as repros."
        ]
    },
    {
        userRole: "Customer support representative responding to customer queries",
        userPhrases: [
            "Thank you for reaching out to us.",
            "Can you please provide your order number?",
            "We apologize for the inconvenience.",
            "Our team is looking into this issue and will get back to you shortly.",
            "For urgent matters, please call our support line."
        ]
    },
    {
        userRole: "Employee communicating with internal team",
        userPhrases: [
            "Please find the attached report.",
            "Let's schedule a meeting to discuss this further.",
            "Can you provide an update on this task?",
            "I appreciate your prompt response.",
            "Let's collaborate on this project to ensure timely delivery."
        ]
    },
    {
        userRole: "Sales representative responding to client inquiries",
        userPhrases: [
            "Thank you for your interest in our product.",
            "Can I schedule a demo for you?",
            "Please find the pricing details attached.",
            "Our team is excited to work with you.",
            "Let me know if you have any further questions."
        ]
    }
];

let dropDownPresets: DropDownList = new DropDownList({
    dataSource: rolesData,
    placeholder: "Select a role",
    value: "Maintainer of an open-source project replying to GitHub issues",
    popupHeight: "200px",
    change: (e: any) => {
        let selectedRole: string = e.value;
        let selectedPreset: any = presets.find((preset: any) => preset.userRole === selectedRole);
        textareaObj.userRole = selectedRole;
        textareaObj.UserPhrases = selectedPreset.userPhrases;
    }
});
dropDownPresets.appendTo('#user-role');
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Essential JS 2 TextArea</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 TextArea Components" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/27.1.48/ej2-inputs/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <script src="../azure_openai.js" type="module"></script>
    <style>
      .content-wrapper {
        margin: 50px auto;
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 10px;
      }

      .content-wrapper div.row {
        padding: 7px 0px;
      }

      .example-label {
        width: 29%;
        font-weight: 700;
      }

      .content-wrapper div.api-row {
        margin: 30px 150px;
      }

      .api-property .left-side {
        font-size: 14px;
        padding: 8px;
      }

      .api-property.property-panel-table div.api {
        padding-left: 0px;
      }

      .e-input-group.e-multi-line-input {
        max-width: 100%;
        margin-top: 40px;
      }
    </style>
  <script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

  <body>
    <div id="loader">Loading....</div>
    <div id="container">
      <div class="wrap">
        <h2>Syncfusion Smart TextArea</h2>
        <br />
        <br />

        <div class="col-lg-12 control-section" id="default">
          <div class="content-wrapper">
            <div class="example-label">Select a role</div>
            <div id="container" style="width: 430px">
              <input type="text" id="user-role" />
            </div>
            <textarea id="smart-textarea"></textarea>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>
import { AzureOpenAI } from "https://cdn.jsdelivr.net/npm/openai@4.56.0/+esm";
 
//Warning: Do not expose your API key in the client-side code. This is only for demonstration purposes.

// Replace your Azure OpenAI endpoint, apiVersion, deployment and API key here
const endpoint = "AZURE_OPENAI_ENDPOINT";
const apiKey = "AZURE_OPENAI_API_KEY";
const deployment = "DEPLOYMENT_NAME";
const apiVersion = "API_VERSION";
 
const client = new AzureOpenAI({
    endpoint,
    apiKey,
    apiVersion,
    deployment,
    dangerouslyAllowBrowser: true
});
 
window.AzureAIRequest = async function (options) {
    try {
        const result = await client.chat.completions.create({
            messages: options.messages,
            model: "",
            top_p: options.topP,
            temperature: options.temperature,
            max_tokens: options.maxTokens,
            frequency_penalty: options.frequencyPenalty,
            presence_penalty: options.presencePenalty,
            stop: options.stopSequences
        });
        return result.choices[0].message.content;
    } catch (err) {
        console.error("Error occurred:", err);
    }
}
#container {
    visibility: hidden;
}

#loader {
    color: #008cff;
    font-family: 'Helvetica Neue', 'calibiri';
    font-size: 14px;
    height: 40px;
    left: 45%;
    position: absolute;
    top: 45%;
    width: 30%;
}

.wrap {
    box-sizing: border-box;
    margin: 0 auto;
    padding: 30px 10px;
    width: 260px;
}
  • Type ‘To investigate’ to experience instant sentence autocompletion.

Syncfusion Smart TextArea - Output

View Sample in GitHub.