function showResponse()

in assets/web/js/custom.js [129:260]


function showResponse(lexResponse) {
	// Prepare a container div to hold the reponse message
	var response = document.createElement("div");
	// The following class names have some styles associated with
	// them so update the custom.css file in the styles folder if
	// you want to change this class name.
	response.className = 'bot-conver-con';
	resTable = "";

	// Checks whether response contains table. Table data are passed
	// as string in the card attribute of session attributes.
	if(lexResponse.sessionAttributes && lexResponse.sessionAttributes.card && lexResponse.intentName) {
		// In Lex session attributes only support string as value.
		// So table data is passed as json encoded string. Parse it
		// to get the actual table data json.
		card = JSON.parse(lexResponse.sessionAttributes.card);
		// Variables intialized to default values and will be used
		// down the line.
		table = "";
		resTable = "";
		rightAlign = false;
		rightAlignIndex = 0;

		if(card.table) {
			table = card.table;

			// Adding table markups
			resTable = "<table><tbody><tr>";
			// Loop to add headers to the table
			for(index in table) {
				i = 0;
				for(item in table[index]) {
					// In order to right aling number column in the table we are
					// checking the column names for orders, revenue or sales
					// team size. If matches then remembering the column position
					// to add the necessary markup later.
					// Note : So far the solution uses numbers in these columns only,
					// so I added a simple if statement here. If you extend then change
					// the logic to something else.
					// Also it is assumed only on column will contain number values.
					// If you need support for additional columns please extend this logic
					// accordingly.
					if(item.toLowerCase() == "orders" || item.toLowerCase() == "revenue" || item.toLowerCase() == "sales team size") {
						rightAlign = true;
						rightAlignIndex = i;
					}
					// Markup to add the actual headers. Note, the header is
					// actually the key of the respective data elements.
					// To see what it actually means see the console for the
					// data returned by the backend lambda.
					resTable += '<th class="center-align">' + item + "</th>";
					i++;
				}
				// Once first row of the table is processed break the loop.
				break;
			}

			// Closes the header row markup.
			resTable += "</tr>";
		}
		// If help is sent in the card rather table of data, intialize
		// some special markups to style it.
		else if(card.help) {
			table = card.help;

			resTable = '<div class="help-con">';
		}

		// Loop to fill the data part of the table or the help contents
		for(index in table) {
			// If table data has to be filled
			if(card.table) {
				// Add the table row markup and specially treats the total row
				// at the end of the table to add some class to it, so that
				// it can be styled as needed in our style sheet.
				resTable += "<tr" + (Object.values(table[index])[0].toLowerCase() == "total" ? ' class="total-row"' : "") + ">";
				// Variable to track the current column number.
				i = 0;
				// Loop to process individual cell elements of the current row.
				for(item in table[index]) {
					// Add the table data markup and checks whether the data has
					// to be right aligne, if so adds some class attributes so that
					// it can be right aligned in CSS.
					resTable += "<td" + (rightAlign && (rightAlignIndex == i) ? ' class="right-align"' : "") + ">" + table[index][item] + "</td>";
					// Increment the current coumn number tracker.
					i++;
				}
				// Markup to close the current data row in the table.
				resTable += "</tr>";
			}
			// If help statements has to be filled
			else if(card.help) {
				// The following statement contains some class attributes, please
				// don't change them as they as associated with some style properties and
				// click triggers. The user can click the individual element to
				// send it to the Lex directly without re typing it.
				resTable += '<div class="help-item-con"><div class="help-item">' + table[index] + "</div></div>";
			}
		}

		// Markup to end table, if response is a table.
		if(card.table) {
			resTable += "</tbody></table>";
		}
		// Markup to end help, if response contains list of help statements.
		else if(card.help) {
			resTable += "</div>";
		}
	}

	// Checks is there any text response.
	if(lexResponse.message) {
		// Markup to add bot image to the response.
		botImage = '<div class="bot-img-con"><img src="images/bot.png" alt="" width="40px"></div>';
		// If reponse contains data table or help statements then append the
		// the above processed markups after the user text message.
		if(resTable) {
			botMsg = '<div class="bot-conver-text">' + lexResponse.message + "<br>" + resTable + '</div>';
		}
		// If user response is just text message, then just add the markups to it.
		else {
			botMsg = '<div class="bot-conver-text">' + lexResponse.message + '</div>';
		}
		// Combine the bot image and bot message markups respectively.
		response.innerHTML = botImage + botMsg;
	}

	// Apped the bot response to the chat window and scroll to
	// bottom of the chat window.
	$("#chat-con").append(response);
	$("#conversation").scrollTop($("#chat-con").height());
}