Contents
- Chat order in template
- Adding messages to chat window
Having trouble getting help?
Contact Support
Contact Support
Customize ListView as chat window in React ListView component
23 Jan 202524 minutes to read
The ListView can be customizable as a chat window. To achieve this, use ListView template
property and Avatar
component.
- The ListView template property is used to showcase the ListView as a chat window.
- The Avatar component is used to design the image of the contact person.
Refer the below template code snippet for Template of chat window.
function listTemplate(data: any): JSX.Element {
let sendertemplate = <div className='settings'><div id="content"><div className="name">{data.text}</div><div id="info">{data.contact}</div></div>{
data.avatar !== "" ?
<div id="image"><span className='e-avatar img1 e-avatar-circle'>{data.avatar}</span></div> : <div id="image"><span className={`${data.pic} img1 e-avatar e-avatar-circle`}></span></div>
}</div>
let receivertemplate = <div className='settings'>{
data.avatar !== "" ?
<div id="image2"><span className='e-avatar img2 e-avatar-circle'>{data.avatar}</span></div> : <div id="image2"><span className={`${data.pic} img2 e-avatar e-avatar-circle`}></span></div>
}<div id="content1"><div className="name1">{data.text}</div><div id="info1">{data.contact}</div></div></div>
return (
<div>
{data.chat !== "receiver" ? (sendertemplate) : (receivertemplate)}
</div>
);
}
function listTemplate(data) {
let sendertemplate = <div className='settings'><div id="content"><div className="name">{data.text}</div><div id="info">{data.contact}</div></div>{data.avatar !== "" ?
<div id="image"><span className='e-avatar img1 e-avatar-circle'>{data.avatar}</span></div> : <div id="image"><span className={`${data.pic} img1 e-avatar e-avatar-circle`}></span></div>}</div>;
let receivertemplate = <div className='settings'>{data.avatar !== "" ?
<div id="image2"><span className='e-avatar img2 e-avatar-circle'>{data.avatar}</span></div> : <div id="image2"><span className={`${data.pic} img2 e-avatar e-avatar-circle`}></span></div>}<div id="content1"><div className="name1">{data.text}</div><div id="info1">{data.contact}</div></div></div>;
return (<div>
{data.chat !== "receiver" ? (sendertemplate) : (receivertemplate)}
</div>);
}
Chat order in template
In the ListView template, we have rendered the list items based on receiver and sender information from dataSource of the ListView.
Adding messages to chat window
* Use textbox to get message from user.
* Add the textbox message to the ListView dataSource using [addItem](https://ej2.syncfusion.com/react/documentation/api/list-view/#additem) method.
function btnClick() {
let value = textboxEle.value;
listObj.addItem([{ text: "Amenda", contact: value, id: "2", avatar: "A", pic: "", chat: "receiver" }]);
textboxEle.value ="";
}
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { ListViewComponent } from '@syncfusion/ej2-react-lists';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
function App() {
let listObj = null;
let textboxEle;
//Define an array of JSON data
let data = [
{
text: "Jenifer",
contact: "Hi",
id: "1",
avatar: "",
pic: "pic01",
chat: "sender"
},
{ text: "Amenda", contact: "Hello", id: "2", avatar: "A", pic: "", chat: "receiver" },
{
text: "Jenifer",
contact: "What Knid of application going to launch",
id: "4",
avatar: "",
pic: "pic01",
chat: "sender"
},
{
text: "Amenda ",
contact: "A knid of Emergency broadcast App",
id: "5",
avatar: "A",
pic: "",
chat: "receiver"
},
{
text: "Jacob",
contact: "Can you please elaborate",
id: "6",
avatar: "",
pic: "pic04",
chat: "sender"
}
];
function listTemplate(data) {
const sendertemplate = (<div className="settings">
<div id="content">
<div className="name">{data.text}</div>
<div id="info">{data.contact}</div>
</div>
{data.avatar !== "" ? (<div id="image">
<span className="e-avatar img1 e-avatar-circle">{data.avatar}</span>
</div>) : (<div id="image">
<span className={`${data.pic} img1 e-avatar e-avatar-circle`} />
</div>)}
</div>);
const receivertemplate = (<div className="settings">
{data.avatar !== "" ? (<div id="image2">
<span className="e-avatar img2 e-avatar-circle">{data.avatar}</span>
</div>) : (<div id="image2">
<span className={`${data.pic} img2 e-avatar e-avatar-circle`} />
</div>)}
<div id="content1">
<div className="name1">{data.text}</div>
<div id="info1">{data.contact}</div>
</div>
</div>);
return <div>{data.chat !== "receiver" ? sendertemplate : receivertemplate}</div>;
}
function btnClick() {
const value = textboxEle.value;
listObj.addItem([
{ text: "Amenda", contact: value, id: "2", avatar: "A", pic: "", chat: "receiver" }
]);
textboxEle.value = "";
}
return (<div>
{/* ListView element */}
<ListViewComponent id="List" dataSource={data} headerTitle="Chat" showHeader={true} template={listTemplate} ref={scope => {
listObj = scope;
}} />
<input id="inputname" className="e-input" ref={textbox => {
textboxEle = textbox;
}} type="text" placeholder="Type your message" />
<ButtonComponent id="btn" onClick={btnClick.bind(this)}>
Send
</ButtonComponent>
</div>);
}
export default App;
ReactDOM.render(<App />, document.getElementById('element'));
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { ListViewComponent } from '@syncfusion/ej2-react-lists';
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
function App() {
let listObj: ListViewComponent = null as any;
let textboxEle: any;
//Define an array of JSON data
let data: { [key: string]: Object }[] = [
{
text: "Jenifer",
contact: "Hi",
id: "1",
avatar: "",
pic: "pic01",
chat: "sender"
},
{ text: "Amenda", contact: "Hello", id: "2", avatar: "A", pic: "", chat: "receiver" },
{
text: "Jenifer",
contact: "What Knid of application going to launch",
id: "4",
avatar: "",
pic: "pic01",
chat: "sender"
},
{
text: "Amenda ",
contact: "A knid of Emergency broadcast App",
id: "5",
avatar: "A",
pic: "",
chat: "receiver"
},
{
text: "Jacob",
contact: "Can you please elaborate",
id: "6",
avatar: "",
pic: "pic04",
chat: "sender"
}
];
function listTemplate(data: any): JSX.Element {
const sendertemplate = (
<div className="settings">
<div id="content">
<div className="name">{data.text}</div>
<div id="info">{data.contact}</div>
</div>
{data.avatar !== "" ? (
<div id="image">
<span className="e-avatar img1 e-avatar-circle">{data.avatar}</span>
</div>
) : (
<div id="image">
<span className={`${data.pic} img1 e-avatar e-avatar-circle`} />
</div>
)}
</div>
);
const receivertemplate = (
<div className="settings">
{data.avatar !== "" ? (
<div id="image2">
<span className="e-avatar img2 e-avatar-circle">{data.avatar}</span>
</div>
) : (
<div id="image2">
<span className={`${data.pic} img2 e-avatar e-avatar-circle`} />
</div>
)}
<div id="content1">
<div className="name1">{data.text}</div>
<div id="info1">{data.contact}</div>
</div>
</div>
);
return <div>{data.chat !== "receiver" ? sendertemplate : receivertemplate}</div>;
}
function btnClick() {
const value = textboxEle.value;
listObj.addItem([
{ text: "Amenda", contact: value, id: "2", avatar: "A", pic: "", chat: "receiver" }
]);
textboxEle.value = "";
}
return (
<div>
{/* ListView element */}
<ListViewComponent
id="List"
dataSource={data}
headerTitle="Chat"
showHeader={true}
template={listTemplate as any}
ref={scope => {
listObj = scope as any;
}}
/>
<input
id="inputname"
className="e-input"
ref={textbox => {
textboxEle = textbox;
}}
type="text"
placeholder="Type your message"
/>
<ButtonComponent id="btn" onClick={btnClick.bind(this)}>
Send
</ButtonComponent>
</div>
);
}
export default App;
ReactDOM.render(<App />, document.getElementById('element'));
#List {
margin: 0 auto;
border: 1px solid #ccc;
}
#List .e-list-item {
height: auto;
cursor: pointer;
}
#List .e-list-header .e-text {
font-family: sans-serif;
font-size: 18px;
line-height: 26px;
}
#List #info,
#List .name {
font-size: 11px;
line-height: 20px;
}
#List .name {
padding-top: 3px;
font-weight: 500;
padding-left: 150px;
margin-left: 55px;
}
#List #info {
float: right;
margin-right: 10px;
}
.pic01 {
background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/1.png");
}
.pic02 {
background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/3.png");
}
.pic03 {
background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/5.png");
}
.pic04 {
background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/2.png");
}
.img2 {
margin-left: 10px;
margin-top: 7px;
font-size: 13px;
}
#List #content1 {
width: 200px;
background-color: aliceblue;
display: inline-block;
margin: 5px;
}
#List #info1,
#List .name1 {
font-size: 11px;
line-height: 20px;
margin-left: 10px;
}
#List .name1 {
padding-top: 3px;
font-weight: 500;
}
#List #content {
margin: 5px;
width: 250px;
margin-left: 62px;
background-color: aliceblue;
display: inline-block
}
#image {
float: right;
}
#image2 {
float: left;
}
.img1 {
margin-right: 10px;
margin: 5px;
font-size: 13px;
}
.e-listview .e-list-header {
color: white;
}
.e-listview .e-list-header {
background: rgb(2, 120, 215);
}
#List.e-listview .e-hover {
background-color: transparent;
}
#inputname {
width: 275px
}
.message {
width: 350px;
margin: 0 auto;
}
#btn {
float: right
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React ListView</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-react-lists/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/29.1.33/ej2-inputs/styles/material.css" rel="stylesheet" />
<link href="index.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='element' style="margin:0 auto; max-width:400px;">
<div id='loader'>Loading....</div>
</div>
<style>
#List {
margin: 0 auto;
border: 1px solid #ccc;
}
#List .e-list-item {
height: auto;
cursor: pointer;
}
#List .e-list-header .e-text {
font-family: sans-serif;
font-size: 18px;
line-height: 26px;
}
#List #info1,
#List .name1 {
margin-left: 10px;
}
#List #info,
#List .name,
#List #info1,
#List .name1 {
font-size: 11px;
line-height: 20px;
}
#List .name {
padding-left: 150px;
margin-left: 55px;
}
#List #info {
float: right;
margin-right: 10px;
}
.pic01 {
background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/1.png");
}
.pic02 {
background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/3.png");
}
.pic03 {
background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/5.png");
}
.pic04 {
background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/2.png");
}
.img2 {
margin-left: 10px;
margin-top: 7px;
font-size: 13px;
}
#List #content1 {
width: 200px;
background-color: aliceblue;
display: inline-block;
margin: 5px;
}
#List .name1,
#List .name {
padding-top: 3px;
font-weight: 500;
}
#List #content {
margin: 5px;
width: 250px;
margin-left: 62px;
background-color: aliceblue;
display: inline-block
}
#image {
float: right;
/* display: inline-block; */
}
#image2 {
float: left;
/* display: inline-block; */
}
.img1 {
margin-right: 10px;
margin: 5px;
font-size: 13px;
}
.e-listview .e-list-header {
color: white;
background: rgb(2, 120, 215);
}
#List.e-listview .e-hover {
background-color: transparent;
}
#inputname {
width: 275px
}
.message {
width: 350px;
margin: 0 auto;
}
#btn {
float: right
}
</style>
</body>
</html>