A Pen by Brian Poole on CodePen.
Created
May 27, 2022 15:35
-
-
Save ahmedtalaltwd7/2d5ea65c91655e20ae8bbe57605c24fe to your computer and use it in GitHub Desktop.
Chat Interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="chat-icon"> | |
<button id="chat-icon"><i class="fas fa-comment-dots"></i></button> | |
<div class="close-icon" id="close-icon"> | |
<i class="far fa-times-circle"></i> | |
</div> | |
</div> | |
<div class="chat-box" id="chat-container"> | |
<div class="chat-title"> | |
<div class="title-text"><i class="fas fa-robot"></i> Robo-Chat</div> | |
<div class="close-chat" id="close"><i class="fas fa-times"></i></div> | |
<div class="minimize" id="minimize"><i class="fas fa-minus"></i></div> | |
</div> | |
<div class="chat-main"> | |
<div class="chat-log" id="chat-log"> | |
<div class="prompt"> | |
<span></span> | |
<!-- <div class="chat-message"> | |
How can I help? <br /><br />Here are some examples of things you | |
can ask: | |
<ul> | |
<li>- How do I make a payment?</li> | |
<li>- Where do I get an online quote?</li> | |
<li>- How do I make a claim?</li> | |
<li>- How do I contact the agency?</li> | |
</ul> | |
</div> --> | |
<div class="chat-message" style="display: inline-block"> | |
Hello. Who am I speaking with? | |
</div> | |
</div> | |
</div> | |
<div class="chat-input"> | |
<textarea | |
rows="1" | |
class="input-message" | |
name="message" | |
type="text" | |
id="message" | |
placeholder="Message..." | |
aria-label="Message..." | |
spellcheck="true" | |
maxlength="4096" | |
></textarea> | |
<button class="btn-Send"> | |
<i class="fas fa-paper-plane"></i> | |
<!-- SEND --> | |
</button> | |
</div> | |
</div> | |
<div class="chat-footer"> | |
<img | |
src="https://iwb.blob.core.windows.net/assets/ada/images/ITC.svg" | |
width="50px" | |
alt="Company Logo" | |
/> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var clientName; | |
// Sends message when send button is clicked | |
$(".btn-Send").click(function () { | |
send(); | |
}); | |
// Sends message when enter key is pressed | |
$(document).keydown(function (e) { | |
if (e.keyCode == 13) { | |
send(); | |
if (e.preventDefault) e.preventDefault(); | |
return false; | |
} | |
}); | |
localStorage["chat-log"] ? console.log("true") : console.log("false"); | |
// Checks for "chat-log" key in localStorage and if it exists it rerenders all user messages and bot responses | |
if (localStorage["chat-log"]) { | |
$("#chat-icon").toggleClass("hidden"); | |
$(".chat-box").toggleClass("open"); | |
var arr = JSON.parse(localStorage["chat-log"]); | |
for (i = 0; i < arr.length; i++) { | |
if (arr[i].person === 1) { | |
reRenderMessage(arr[i].text, arr[i].time); | |
} else { | |
reRenderResponse(arr[i].text, arr[i].time); | |
} | |
} | |
} | |
// Sends message to server | |
function send() { | |
var message = document.getElementById("message").value; | |
hideTyping(); | |
if (clientName === "") { | |
console.log("clientName is" + clientName) | |
clientName = message; | |
addNameToSession(message); | |
addMessage(message, "true"); | |
setTimeout(() => { | |
addPrompt(); | |
}, 3000); | |
} else { | |
addMessage(message); | |
} | |
} | |
// Adds Prompt with Client Name | |
function addPrompt() { | |
hideTyping(); | |
var div = document.createElement("div"); | |
var msg = "Hello " + clientName + ", how can I help?<br /><br />Here are some examples of things you can ask:<ul><li>- How do I make a payment?</li><li>- Where do I get an online quote?</li><li>- How do I make a claim?</li><li>- How do I contact the agency?</li></ul>"; | |
div.innerHTML = "<span></span><div class='chat-message response'>" + | |
msg + | |
"</div><span class='timestamp response'>" + | |
getTimestamp() + | |
"</span>"; | |
div.className = "chat-message-div"; | |
document.getElementById("chat-log").appendChild(div); | |
addToSession(2, msg, getTimestamp()); | |
updateScroll(); | |
} | |
// Adds message from user | |
function addMessage(msg, getResponse) { | |
$(".common").css({ display: "none" }); | |
var div = document.createElement("div"); | |
div.innerHTML = | |
"<span style='flex-grow:1'></span><span class='timestamp'>" + | |
getTimestamp() + | |
"</span><div class='chat-message message'>" + | |
msg + | |
"</div>"; | |
div.className = "chat-message-div"; | |
document.getElementById("chat-log").appendChild(div); | |
$("#message").val(""); | |
addToSession(1, msg, getTimestamp()); | |
showTyping(); | |
if(getResponse === "") { | |
setTimeout(() => { | |
getResponse(msg); | |
}, 3000); | |
} | |
updateScroll(); | |
} | |
// Rerenders user's message upon reopening chat box and if value in localStorage exists | |
function reRenderMessage(msg, time) { | |
$(".common").css({ display: "none" }); | |
var div = document.createElement("div"); | |
div.innerHTML = | |
"<span style='flex-grow:1'></span><span class='timestamp'>" + | |
time + | |
"</span><div class='chat-message message'>" + | |
msg + | |
"</div>"; | |
div.className = "chat-message-div"; | |
document.getElementById("chat-log").appendChild(div); | |
updateScroll(); | |
} | |
// Adds response from bot | |
function addResponse(msg) { | |
hideTyping(); | |
if (msg === "") { | |
msg = "The bot is offline."; | |
} | |
var div = document.createElement("div"); | |
div.innerHTML = | |
"<span></span><div class='chat-message response'>" + | |
msg + | |
"</div><span class='timestamp response'>" + | |
getTimestamp() + | |
"</span>"; | |
div.className = "chat-message-div"; | |
document.getElementById("chat-log").appendChild(div); | |
addToSession(2, msg, getTimestamp()); | |
updateScroll(); | |
} | |
// Rerenders bot's message upon reopening chat box and if value in localStorage exists | |
function reRenderResponse(msg, time) { | |
var div = document.createElement("div"); | |
div.innerHTML = | |
"<span></span><div class='chat-message response'>" + | |
msg + | |
"</div><span class='timestamp response'>" + | |
time + | |
"</span>"; | |
div.className = "chat-message-div"; | |
document.getElementById("chat-log").appendChild(div); | |
updateScroll(); | |
} | |
// Adds response links from bot | |
function addLinks(msg) { | |
var div = document.createElement("div"); | |
div.innerHTML = | |
"<span></span><div class='response-links'>" + | |
msg + | |
"</div><span class='timestamp'>" + | |
getTimestamp() + | |
"</span>"; | |
div.className = "chat-message-div"; | |
document.getElementById("chat-log").appendChild(div); | |
addToSession(2, msg, getTimestamp()); | |
updateScroll(); | |
} | |
// Sets local variable "log" to either the value of localStorage if it exists or empty array if it doesn't | |
var log; | |
function getLog() { | |
if (localStorage["chat-log"]) { | |
log = JSON.parse(localStorage["chat-log"]); | |
} else { | |
log = []; | |
} | |
} | |
getLog(); | |
// Sets local variable "clientName" to either the value of localStorage if it exists or empty string if it doesn't | |
function getClientName() { | |
if (localStorage["clientName"]) { | |
clientName = JSON.parse(localStorage["clientName"]); | |
} else { | |
clientName = ""; | |
} | |
} | |
getClientName(); | |
// Adds message/response to session | |
function addToSession(num, msg, time) { | |
var message = { | |
person: num, | |
text: msg, | |
time, | |
}; | |
log.push(message); | |
localStorage.setItem("chat-log", JSON.stringify(log)); | |
if (localStorage["chat-log"]) { | |
console.log(JSON.parse(localStorage["chat-log"])); | |
} | |
} | |
// Adds Client's Name to session | |
function addNameToSession(name){ | |
localStorage.setItem("clientName", JSON.stringify(name)); | |
} | |
// Sends user's inquiry to server and retrieves response | |
function getResponse(msg) { | |
function sendXHRRequest(url, data, e) { | |
var xhttp = new XMLHttpRequest(); | |
xhttp.open("POST", url, true); | |
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); | |
xhttp.onload = function () { | |
var response = JSON.parse(this.responseText); | |
console.log("response: ", response); | |
addResponse(response.ChatResponse); | |
var links = ""; | |
if (response.ChatUrl.length > 0) { | |
for (i = 0; i < response.ChatUrl.length; i++) { | |
links += `<br><a class="linkButton" href="${response.ChatUrl[i].Item1}" target="_blank">${response.ChatUrl[i].Item2}</a><br>`; | |
} | |
links += `<br>`; | |
addResponse(links); | |
} else { | |
console.log(false); | |
} | |
}; | |
// xhttp.send(JSON.stringify(data)); | |
xhttp.send(data); | |
} | |
// var apiUrl = "http://jamesbakerins.com/controls/handlers/iwbchatbot.ashx"; | |
var apiUrl = "https://www.jamesbakerins.com/iwbchatbot.json"; | |
sendXHRRequest(apiUrl, msg, null); | |
// addResponse(msg); | |
} | |
$("#close-icon").click(function () { | |
$("#close-icon").css({ display: "none" }); | |
$("#chat-icon").css({ display: "none" }); | |
}); | |
$("#chat-icon").mouseover(function () { | |
$("#close-icon").css({ display: "flex" }); | |
}); | |
$("#close-icon").mouseover(function () { | |
$("#close-icon").css({ display: "flex" }); | |
}); | |
$("#chat-icon").mouseout(function () { | |
$("#close-icon").css({ display: "none" }); | |
}); | |
// Clears localStorage key "chat-log" on close of chat box | |
$("#close").click(function () { | |
$(".chat-box").removeClass("open"); | |
$("#chat-icon").removeClass("hidden"); | |
localStorage.removeItem("chat-log"); | |
localStorage.removeItem("clientName"); | |
$(".prompt").css({ display: "block" }); | |
$(".chat-message-div").remove(); | |
console.log("log before: ", log); | |
getLog(); | |
console.log("log after: ", log); | |
minimizeOff(); | |
clientName = ""; | |
}); | |
$("#chat-icon").click(function (e) { | |
e.preventDefault(); | |
$("#chat-icon").toggleClass("hidden"); | |
$(".chat-box").toggleClass("open"); | |
}); | |
$("#minimize").click(function() { | |
toggleWindow(); | |
}) | |
function toggleWindow() { | |
if($(".chat-title").hasClass("minimized")){ | |
$(".chat-title").removeClass("minimized"); | |
$(".chat-box").removeClass("minimized"); | |
$(".chat-main").removeClass("minimized"); | |
$(".chat-footer").removeClass("minimized"); | |
} else { | |
$(".chat-title").addClass("minimized"); | |
$(".chat-box").addClass("minimized"); | |
$(".chat-main").addClass("minimized"); | |
$(".chat-footer").addClass("minimized"); | |
} | |
} | |
function minimizeOff(){ | |
if($(".chat-title").hasClass("minimized")){ | |
$(".chat-title").removeClass("minimized"); | |
$(".chat-box").removeClass("minimized"); | |
$(".chat-main").removeClass("minimized"); | |
$(".chat-footer").removeClass("minimized"); | |
} | |
} | |
function showTyping() { | |
var div = document.createElement("div"); | |
div.innerHTML = | |
"<span></span><div class='chat-message'><i class='fas fa-ellipsis-h'></i></div>"; | |
div.className = "chat-message-div typing"; | |
document.getElementById("chat-log").appendChild(div); | |
updateScroll(); | |
} | |
function hideTyping() { | |
$(".typing").remove(); | |
} | |
// Scrolls div to the bottom | |
function updateScroll() { | |
var element = document.getElementById("chat-log"); | |
element.scrollTop = element.scrollHeight; | |
} | |
// Shows and hides scrollbar based on hover | |
$(".chat-log").hover( | |
function () { | |
$(".chat-log").addClass("show-scroll"); | |
}, | |
function () { | |
$(".chat-log").removeClass("show-scroll"); | |
} | |
); | |
function getTimestamp() { | |
var months = [ | |
"Jan", | |
"Feb", | |
"Mar", | |
"Apr", | |
"May", | |
"Jun", | |
"Jul", | |
"Aug", | |
"Sep", | |
"Oct", | |
"Nov", | |
"Dec", | |
]; | |
var days = [ | |
"Sunday", | |
"Monday", | |
"Tuesday", | |
"Wednesday", | |
"Thursday", | |
"Friday", | |
"Saturday", | |
]; | |
var d = new Date(); | |
var day = days[d.getDay()]; | |
var hr = d.getHours(); | |
var min = d.getMinutes(); | |
if (min < 10) { | |
min = "0" + min; | |
} | |
var ampm = "am"; | |
if (hr > 12) { | |
hr -= 12; | |
ampm = "pm"; | |
} | |
var date = d.getDate(); | |
var month = months[d.getMonth()]; | |
var year = d.getFullYear(); | |
return hr + ":" + min + ampm; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://kit.fontawesome.com/a65762e6f2.js"></script> | |
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
overflow: hidden; | |
} | |
.chat-icon { | |
position: fixed; | |
bottom: 33px; | |
right: 24px; | |
z-index: 10000; | |
} | |
.chat-icon button { | |
border-radius: 50%; | |
height: 39px; | |
width: 39px; | |
cursor: pointer; | |
background: #003882; | |
color: #fff; | |
font-size: 18px; | |
border: 3px solid #fff; | |
box-shadow: 0 0 0 3px #003882; | |
padding: 5px; | |
} | |
.chat-icon button:focus { | |
outline: none; | |
} | |
#chat-icon.hidden { | |
display: none; | |
} | |
.chat-icon .close-icon { | |
align-items: center; | |
background: white; | |
border-radius: 50%; | |
bottom: 62px; | |
color: black; | |
cursor: pointer; | |
/* display: flex; */ | |
display: none; | |
font-size: 18px; | |
height: 15px; | |
justify-content: center; | |
position: fixed; | |
right: 20px; | |
text-align: center; | |
width: 15px; | |
} | |
.chat-box { | |
animation-duration: 150ms; | |
background: #f1f3f5; | |
border: solid 1px #ddd; | |
border-radius: 8px; | |
bottom: 10px; | |
box-shadow: 0 0 50px rgba(0, 0, 0, 0.15); | |
color: #000; | |
/* display: flex; */ | |
display: none; | |
flex-direction: column; | |
font-family: sans-serif; | |
height: 600px; | |
position: fixed; | |
right: 20px; | |
transition: max-height 250ms ease-out; | |
width: 375px; | |
z-index: 99999; | |
} | |
.chat-box.open { | |
/* max-height: 400px; */ | |
display: flex; | |
-webkit-animation-name: spaceInDown; | |
animation-name: spaceInDown; | |
} | |
.chat-box.minimized { | |
height: auto; | |
} | |
.chat-title { | |
background: #003882; | |
font-weight: bold; | |
font-size: 16px; | |
padding: 10px; | |
border-top-right-radius: 8px; | |
border-top-left-radius: 8px; | |
} | |
.chat-title.minimized { | |
border-radius: 8px; | |
} | |
.fa-robot { | |
font-size: 1.25em; | |
} | |
.title-text { | |
text-align: left; | |
} | |
.close-chat, | |
.minimize { | |
position: absolute; | |
top: 6px; | |
right: 10px; | |
cursor: pointer; | |
color: #fff; | |
} | |
.fas { | |
color: #fff; | |
} | |
.minimize { | |
right: 30px; | |
} | |
.title-text { | |
color: #fff; | |
} | |
.chat-main { | |
flex-grow: 1; | |
overflow: auto; | |
/* border-radius: 8px; */ | |
/* padding: 16px; */ | |
display: flex; | |
flex-direction: column; | |
justify-content: space-between; | |
} | |
.chat-main.minimized { | |
display: none; | |
} | |
.chat-log { | |
/* max-height: 175px; */ | |
/* border: 1px solid red; */ | |
overflow: auto; | |
height: 100%; | |
} | |
.chat-log::-webkit-scrollbar { | |
width: 0; | |
} | |
.chat-log.show-scroll::-webkit-scrollbar { | |
width: 0.5rem; | |
} | |
.chat-log .common { | |
line-height: 1.6; | |
padding-left: 0.5rem; | |
font-size: 14px; | |
} | |
.chat-log .common:first-of-type { | |
margin-top: 1rem; | |
} | |
.common span { | |
text-decoration: underline; | |
} | |
.chat-input { | |
display: flex; | |
justify-content: center; | |
/* padding: 5px 8px 10px 0; */ | |
padding: 0.8em 0.5em; | |
border-top: 1px solid rgba(0, 0, 0, 0.19); | |
/* border-bottom: 1px solid rgba(0, 0, 0, 0.19); */ | |
font-family: Arial, Helvetica, sans-serif; | |
font-size: 15px; | |
align-items: center; | |
background: #fff; | |
} | |
.input-message { | |
background: #fff; | |
vertical-align: middle; | |
resize: none; | |
min-height: 46px; | |
max-height: 134px; | |
width: calc(100% + 18px); | |
height: 46px; | |
font-family: Arial, Helvetica, sans-serif; | |
font-size: 15px; | |
border: 0; | |
box-shadow: none; | |
} | |
.input-message:focus { | |
outline: none; | |
} | |
.btn-Send { | |
background: #003882; | |
color: #fff; | |
cursor: pointer; | |
border: 1px solid #003882; | |
border-radius: 50%; | |
width: 32px; | |
height: 30px; | |
padding: 5px; | |
} | |
.btn-Send i { | |
box-shadow: 0 6px 20px 0 rgba(0, 0, 0, 0.19); | |
background: transparent; | |
} | |
.btn-Send:focus { | |
outline: none; | |
} | |
.chat-message-div, | |
.prompt { | |
display: flex; | |
align-items: flex-end; | |
} | |
.chat-message-div .timestamp { | |
font-size: 0.8em; | |
margin-bottom: 0.5rem; | |
} | |
.chat-message-div .timestamp.response { | |
margin-right: 0.5rem; | |
} | |
.chat-message-div .linkButton { | |
background: #fff; | |
border: 1px solid #003882; | |
border-radius: 3px; | |
color: #003882; | |
cursor: pointer; | |
margin-left: 0.15rem; | |
padding: 5px; | |
text-decoration: none; | |
} | |
.chat-message-div .linkButton:hover { | |
background: #003882; | |
color: #fff; | |
} | |
.fa-ellipsis-h { | |
color: gray; | |
} | |
.chat-message { | |
background-color: #fff; | |
margin: 8px 16px; | |
padding: 4px 6px; | |
animation-name: fadeIn; | |
animation-iteration-count: 1; | |
animation-timing-function: ease-in; | |
animation-duration: 100ms; | |
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1); | |
color: black; | |
border-radius: 5px; | |
} | |
.chat-message.message { | |
background: #0d8bcd; | |
color: #fff; | |
} | |
.chat-message ul { | |
list-style: none; | |
padding: 0; | |
} | |
.chat-message ul li { | |
color: black; | |
font-family: Arial, Helvetica, sans-serif; | |
} | |
.chat-footer { | |
background: #fff; | |
border-radius: 8px; | |
} | |
.chat-footer.minimized { | |
display: none; | |
} | |
@keyframes fadeIn { | |
from { | |
opacity: 0; | |
} | |
to { | |
opacity: 1; | |
} | |
} | |
@keyframes spaceInDown { | |
0% { | |
opacity: 0; | |
transform-origin: 50% 100%; | |
transform: scale(0.2) translate(0%, 200%); | |
} | |
100% { | |
opacity: 1; | |
transform-origin: 50% 100%; | |
transform: scale(1) translate(0%, 0%); | |
} | |
} | |
@keyframes spaceInRight { | |
0% { | |
opacity: 0; | |
transform-origin: 100% 50%; | |
transform: scale(0.2) translate(200%, 0%); | |
} | |
100% { | |
opacity: 1; | |
transform-origin: 100% 50%; | |
transform: scale(1) translate(0%, 0%); | |
} | |
} | |
::-webkit-scrollbar { | |
width: 10px; | |
} | |
::-webkit-scrollbar-track { | |
background: #f1f1f1; | |
} | |
::-webkit-scrollbar-thumb { | |
background: #888; | |
} | |
::-webkit-scrollbar-thumb:hover { | |
background: #555; | |
} | |
@media (max-width: 768px) { | |
.chat-box { | |
height: 90%; | |
width: 100%; | |
right: 0; | |
font-size: 2em; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment