How to make an interactive in-chat questionnaire with TalkJS HTML Panels
Tags: javascript, tutorial, webdev
Published: 2021-05-19 11:43:43

Today’s article will be a quick introduction to using HTML panels with the [TalkJS Chat API] (https://talkjs.com/) and how you can create your very own interactive questionnaire.

##Introduction
Below is the end product that we will be building today. The project is available on [GitHub] (https://github.com/aswinrajeevofficial/TalkJS-Questionnaire) and you can use the folder structure there to structure your own project and code along.

![Simple TalkJS Questionnaire](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xtmoxjuh5yd4cy1ra462.gif)

##Setting up a basic chatbox
Setting up a basic popup is very easy with TalkJS. If you’ve already signed up, you will have your APP_ID. Follow the steps mentioned on the [getting started guide] (https://talkjs.com/docs/Getting_Started/index.html) here to set up a basic popup  chatbox. If everything is set up right, you should see a basic inbox on the webpage, but we need to change up the position and the type of it. Inside the script.js file, make the following changes to replace the inbox with a chatbox in the popup mode.

Replace this:
```javascript
const inbox = session.createInbox({selected: conversation});
inbox.mount(document.getElementById("talkjs-container"));
```
With this:
```javascript
const chatboxPopup = session.createPopup(conversation, { keepOpen: false });
chatboxPopup.mount({ show: true });
```
This is because our use case is more intended for one-on-one conversations and we don’t require an inbox. 

**OPTIONAL**
Since the users didn’t have profile pictures, the `photoUrl` property of each user was replaced with an image from [Random User Generator](https://randomuser.me/) to give it a more realistic look and feel. Ideally, this should be retrieved from your system’s database for the user.

With that, you should have a basic chatbox up and running, placed at the bottom right corner of your webpage with two imaginary users Alice and Sebastian. I have added an additional property called questionnaireAnswered inside the custom field for the user Alice, to check whether they’ve answered the questionnaire or not. In a real application, this would be set and retrieved from the database.

##A quick refresher
Before we get into adding an HTML panel, here are the basic steps that happened till now. We wait until the TalkJS script is loaded from the CDN. Once this is complete, we will initiate a [Session] (https://talkjs.com/docs/Reference/JavaScript_Chat_SDK/Session.html) for the current user using the appID (from your dashboard) and the currently logged in user (Alice, in this case). We create another user, to whom Alice will talk to, and then create a conversation between the two using a unique ID. Once the conversation is created, we set the participants and then create the chatbox for that conversation. After the chatbox has been created, we mount it inside the div with the id ‘talkjs-container’.

In this scenario, Sebastian is the person to whom we are talking to. Ideally, he would be a user from the system backend, whom we can refer to as the operator. Sebastian’s welcome message is “Hi, Do you mind answering a short questionnaire?”. If Alice responds “Yes”, the chatbox won’t display anything. But if she responds “No”, it will start the questionnaire.

##HTML Panels and Listening for Events
To listen to what the user types into the chatbox, we need to create an event listener. In our case, it will be the ‘sendMessage’ event that will execute an anonymous function every time the user sends a message. The function takes in an optional object that consists of the entire information about the conversation. We need this to check what the user actually typed into the message box.
```javascript
chatboxPopup.on("sendMessage", function (data) { }
```
We initialize a variable called count to keep track of the questions. We perform the following check first.
```javascript
if(data.message.text === 'No' && count == 1 && questionnaireAnswered == "false"){
}
```

This says if the user replied ‘No’ and if the count is equal to one and the user hasn’t answered the questionnaire before, then execute a piece of code. Inside that block, we will be creating an HTML panel to display the questionnaire. Below is the file structure we will be using. There will be three questions in the questionnaire, followed by a thank you note. These are 4 separate HTML panels, with their own styling. 

![File Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tl2i8ldsy6tvo061odo7.JPG)

The HTML Panels that are loaded just above the message field and it can be used to render almost any type of content giving you all the functionality of an actual webpage. To create an HTML Panel for your chatbox, we use the following code snippet.

```javascript
chatboxPopup.createHtmlPanel({
	url: `questionnaire_panels/question_1.html`,
	height: 100,
	show: true
});
```
It has three fields that are fed as input. One is the URL of the webpage. This is a relative path, but it can be replaced with an absolute path as well. The height of the panel and whether to show it or not. If you see the file structure above, you can see that we have three HTML files for the three questions and we display them one by one.

##Show questions in the HTML Panel
For now, the questions inside the HTML Panel are displayed inside a simple span class. We have a stylesheet for all the questions that are referenced in the file as shown below.
```html
<head>
    <link rel="stylesheet" href="questionnaire_style.css">
</head>
<div class = "question-div">    
    <h4 class = "questionnaire-heading">&#128525; Customer Experience Questionnaire &#128525;</h4>
        <span class = "question">1. Is this site helpful?</span> 
    <div>
    </div>
</div>
```
Since each HTML Panel is rendered inside an iframe, it can be controlled independently. You can mess around with the heading and contents of the question, but this is the skeleton of the HTML panel used for our questionnaire. Do note that the HTML Panel can be used for almost any kind of content. This can be radio buttons, input fields, forms, and much more.
```javascript
if(data.message.text === 'No' && count == 1 && questionnaireAnswered == "false"){
	chatboxPopup.createHtmlPanel({
		url: `questionnaire_panels/question_1.html`,
		height: 100,
		show: true
	});
	//After displaying the panel, we set the flag to true and increment count
	me.custom.questionnaireAnswered = "true"
	count++;
}
else if(count == 2){
	console.log(count);
	chatboxPopup.createHtmlPanel({
		url: `questionnaire_panels/question_2.html`,
		height: 100,
		show: true,
	});
	count++;
}
else if(count == 3){
	console.log(count);
	chatboxPopup.createHtmlPanel({
		url: `questionnaire_panels/question_3.html`,
		height: 100,
		show: true,
	});
	count++;
}
```
You can see in the above code snippet that for a new user who has not answered the questionnaire yet, the HTML panel will be displayed. As soon as they answer the first question, count will increment to 2. This will display the second question and set the questionnaireAnswered flag to true. Once the second question has also been answered, count is incremented to 3, and this will display the third question. The questionnaireAnswered flag will ensure that the questionnaire is not displayed to the user multiple times.

##Completing the questionnaire
We have now set up our HTML Panels for the questionnaire. But what happens when the user completes it.
```javascript
else if(count === 4){
	chatboxPopup.createHtmlPanel({
		url: "questionnaire_panels/thank_you.html",
		height: 100,
		show: true
	})
	//Once loaded, it will hide itself after a span of 1.5 seconds. Once this is done,
	//the user can chat as usual with the operator
	.then(function(htmlPanel) {
		setTimeout(() => {htmlPanel.hide();}, 1500);                
	});
	count++;
}    
```
The above code snippet shows when the count has been incremented to 3 (starting from 0), it means that the user has responded to all questions and now we display a simple thank you note. This is again, another HTML Panel, that will show for 1.5 seconds and hide itself. Once this is done the user can continue chatting to the operator or navigate away. With that, you should have a simple questionnaire set up with TalkJS and vanilla JavaScript. We hope you enjoyed this how-to and can’t wait to see what you come up with.

Happy Coding!