class Chatbot { #currentSectionIdx; #selectSectionIdx; #form; complete = false; chat; audio; pre_audio; config = { 'wrap' : '.chat_wrap', //wrap Selector 'backgroundColor': '#f3f3f3', //bgColor 'profileImg': '//static.hotblood.co.kr/event/v_8742/profile.png', //Profile Image 'progressText': 'percent', //진행상황 표시 'chatLoading': true, //로딩 표시 'maxHeight': '50vh', //최대 높이 'autoFocus': true, 'scrollSpeed': 100, }; constructor(chat, config) { var _this = this; this.#form = $('form', $(this.config.wrap).parents('.chatbot')); this.chat = chat; if(typeof config != 'undefined') { $.each(config, function(key, val) { _this.config[key] = val; }) } if(this.config.maxHeight) $(this.config.wrap).css('max-height', this.config.maxHeight); if(this.config.height) $(this.config.wrap).css('height', this.config.height); if(this.config.backgroundColor) $(this.config.wrap).css('background-color', this.config.backgroundColor); $(this.config.wrap).css('overflow-y', 'auto'); this.goToSection(0); } goToSection(idx) { //idx 기준 섹션 이동 if(typeof idx == undefined) this.#nextSection(); var selectSection = (typeof this.chat[idx] != "undefined") ? this.chat[idx] : null; if(selectSection == null) { console.warn('해당 섹션이 존재하지 않습니다.'); return false; } this.#selectSectionIdx = idx; this.#appendSection(selectSection); this.#currentSectionIdx = idx; } #nextSection() { //다음페이지 this.goToSection(++this.#currentSectionIdx); } #prevSection() { //이전페이지 this.goToSection(--this.#currentSectionIdx); } #appendSection(selectSection) { //섹션 추가 var $this = this; var $chat = this.#makeChat(selectSection); $chat = this.#setLoader($chat); var $chatbox = $(this.config.wrap).append($chat); this.scrollToBottom(); $chatbox.find('.loader_box').delay(500).fadeOut(function() { $(this).remove(); $chatbox.find('.chat_box').css({'display':'inline-block'}); $chatbox.find('.chat_box.right').css({'display':'flex'}); $this.scrollToBottom(); }); function chkAppend(t) { var append_chk = false; if($('section:last-child .chat_box', t.config.wrap).css('display') != 'none') { setTimeout(function() { t.scrollToBottom(); }, 100); append_chk = true; } if(append_chk == false) { setTimeout(function() { chkAppend(t); }, 500); } } chkAppend(this); if(this.config.autoFocus) setTimeout(function() { $chatbox.find('input[type="text"], input[type="number"], input[type="tel"]').focus(); }, 1000); //audio 자동재생 var audio_file = ""; this.pre_audio = this.audio; selectSection.forEach((row, i) => { if(row.audio) audio_file = row.audio; }); if(audio_file) { this.audio = new Audio(audio_file); if(typeof this.pre_audio == 'object') this.pre_audio.pause(); if(this.pre_audio != this.audio) { this.audio.play(); } } var chatbot = this; $('section:not(:last-child)').find('button, input').click(function(e) { return false; }); $(this.config.wrap).find('input:radio').unbind('click'); $('section:last-child', this.config.wrap).find('input:radio').bind('click', function(e) { //radio 버튼 자동 submit 처리 e.stopPropagation(); chatbot.chatbotSubmit(); var selectedInputName = $(this).attr('name'); $('.chat_box.right label input[name="' + selectedInputName + '"]:not(:checked)').closest('label').css('display', 'none'); $('.chat_box.right label input[name="' + selectedInputName + '"]:checked').closest('label').addClass('on'); }); if(typeof PageOnLoad == 'function') { var pageOnLoad = new PageOnLoad(this); //각 페이지 유효성 함수 클래스 분리 var method = `load_${this.#selectSectionIdx}`; if(typeof eval(`pageOnLoad.${method}`) == 'function') setTimeout(function() { eval(`pageOnLoad.${method}()`); }, 1500); } } #setLoader($chat) { //로딩 추가 if(!this.config.chatLoading) return $chat; var loader = `
로딩중...
`; $chat.find('.chat_box').css({'display':'none'}); $chat = $chat.append(loader); return $chat; } #makeChat(section) { //채팅 html 생성 var chat = `
`; //질문, 답변을 한개의 컨테이너로 세팅 if(this.config.progressText) { //진행상황 true or text일 경우 var text = ''; switch(this.config.progressText) { case 'step': if(this.#currentSectionIdx) text = `${this.#currentSectionIdx}/${this.chat.length-1}`; break; case true: case 'percent': dafault: if(this.#currentSectionIdx) text = (this.#currentSectionIdx / (this.chat.length-1)) * 100 +'%'; break; } if(this.config.progressTextLabel){ if(text) chat += `
${this.config.progressTextLabel} ${text}
`; }else{ if(text) chat += `
진행상황 ${text}
`; } } chat += `
`; section.forEach((row, idx) => { //한 섹션 내 메세지 세팅 if(idx == 0 && this.config.profileImg) chat += `
`; }); chat += `
`; section.forEach((row, idx) => { //한 섹션 내 메세지 세팅 if(typeof row.class == 'undefined') row.class = ''; chat += `
`; chat += this.#setContent(row); chat += `
`; }); chat += `
`; chat += `
`; return $(chat); } #setContent(data) { //컨텐츠 세팅 var content = ''; switch(data.type) { case 'date' : content += this.#getDate(); default : content += this.#getMessage(data); } return content; } #getMessage(data) { //섹션내 메세지 가져오기 return data.message; } #getDate() { //날짜세팅 var date = new Date(); return (`${date.getFullYear()}년 ${date.getMonth()+1}월 ${date.getDate()}일${this.#getDay(date)}`); } #getDay(date) { //요일세팅 if(typeof date != 'object') return; var day = date.getDay(); var days = ['일','월','화','수','목','금','토']; return ` ${days[day]}요일`; } scrollToBottom() { //스크롤 하단으로 이동 $(this.config.wrap).animate({ scrollTop: $(this.config.wrap).prop('scrollHeight') }, this.config.scrollSpeed, 'linear'); } #validator() { //form 유효성 체크 var result = true; if(typeof PageValidator == 'function') { var pageValidator = new PageValidator(this.#form); //각 페이지 유효성 함수 클래스 분리 var method = `check_${this.#currentSectionIdx}`; // console.log(this.#currentSectionIdx, typeof eval(`pageValidator.${method}`)) if(typeof eval(`pageValidator.${method}`) == 'function') result = eval(`pageValidator.${method}()`); } return result; } setComplete() { //전체 폼 체크가 완료됐을 경우 호출해야 할 함수 this.complete = true; } chatbotSubmit() { //챗봇 폼 전송 캐치 console.log('chatbot Submit'); var valid = this.#validator(); if(!valid) return false; if(this.complete === true) { this.#form.submit(); return false; } else { //complete 되지 않았으면 자동으로 다음페이지 이동 this.#nextSection(); } } } class Validator { #form; #data; constructor(form) { this.#form = form; } check(data) { this.#data = {"name":data[0],"desc":data[1]}; var result = false; switch(this.#data.name) { case 'name' : result = this.#checkName(); break; case 'age' : result = this.#checkAge(); break; case 'phone' : result = this.#checkPhone(); break; case 'agree' : result = this.#checkAgree(); break; } return result; } #checkName() { if (!$('[name="' + this.#data.name + '"]', this.#form).val()) { alert(this.#data.desc + " 항목을 입력해주세요."); $('[name="' + this.#data.name + '"]', this.#form).focus(); return false; } return true; } #checkAge() { if (!$('[name="' + this.#data.name + '"]', this.#form).val()) { alert(this.#data.desc + " 항목을 입력해주세요."); $('[name="' + this.#data.name + '"]', this.#form).focus(); return false; } return true; } #checkPhone() { if (!$('[name="' + this.#data.name + '"]', this.#form).val()) { alert(this.#data.desc + " 항목을 입력해주세요."); $('[name="' + this.#data.name + '"]', this.#form).focus(); return false; } else if (!$('[name="' + this.#data.name + '"]', this.#form).val().match(/[\d]+/)) { alert(this.#data.desc + " 항목은 숫자만 입력할 수 있습니다."); $('[name="' + this.#data.name + '"]', this.#form).focus(); return false; } else if (/^010[2-9]{1}[0-9]{3}[0-9]{4}$/.test($('[name="' + this.#data.name + '"]', this.#form).val()) == false) { alert("올바른 연락처가 아닙니다."); $('[name="' + this.#data.name + '"]', this.#form).focus(); return false; } return true; } #checkAgree() { if(!$('[name="' + this.#data.name + '"]', this.#form).is(':checked')) { alert('개인정보 처리방침에 동의하지 않으실 경우 이벤트에 참여하실 수 없습니다.'); $('[name="' + this.#data.name + '"]', this.#form).focus(); return false; } return true; } }