Restructure, improive keyboard input handling, debouncing
This commit is contained in:
parent
204d5837c5
commit
d49b934c9a
139
3CX_TAPI.user.js
139
3CX_TAPI.user.js
@ -1,6 +1,9 @@
|
||||
// ==UserScript==
|
||||
// @name 3CX TAPI
|
||||
// @version 1
|
||||
// @author Daniel Triendl
|
||||
// @namespace http://cp-solutions.at
|
||||
// @copyright Copyright 2020 CP Solutions GmbH
|
||||
// @version 2
|
||||
// @grant GM.xmlHttpRequest
|
||||
// @include https://192.168.0.154:5001/webclient*
|
||||
// @include https://cpsolution.my3cx.at:5001/webclient*
|
||||
@ -10,7 +13,22 @@
|
||||
|
||||
console.log('TAPI init');
|
||||
|
||||
function fireChangeEvents(element) {
|
||||
const debounce = (func, wait) => {
|
||||
let timeout;
|
||||
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
};
|
||||
|
||||
const tapi = {
|
||||
fireChangeEvents: (element) => {
|
||||
var changeEvent = null;
|
||||
changeEvent = document.createEvent("HTMLEvents");
|
||||
changeEvent.initEvent("input", true, true);
|
||||
@ -24,20 +42,48 @@ function fireChangeEvents(element) {
|
||||
changeEvent.initEvent("change", true, true);
|
||||
element.dispatchEvent(changeEvent);
|
||||
console.debug('change event dispatched for element: ' + element.id);
|
||||
}
|
||||
},
|
||||
|
||||
function removeSearchResults() {
|
||||
removeSearchResults: () => {
|
||||
var resultList = document.getElementById('tapiResults');
|
||||
if (resultList) {
|
||||
resultList.parentNode.removeChild(resultList);
|
||||
}
|
||||
tapi.currentSearchText = '';
|
||||
},
|
||||
|
||||
dial: (item) => {
|
||||
console.log(item);
|
||||
var contact = item.contact;
|
||||
var searchInput = document.getElementsByName('searchByNumberInput');
|
||||
if (searchInput.length > 0) {
|
||||
searchInput[0].value = contact.tD_NUMBER_TAPI;
|
||||
searchInput[0].focus();
|
||||
|
||||
tapi.fireChangeEvents(searchInput[0]);
|
||||
}
|
||||
},
|
||||
|
||||
selectResult: (resultLi) => {
|
||||
var items = document.getElementsByClassName('tapi-search-result');
|
||||
for (var item of items) {
|
||||
item.classList.remove('bg-light');
|
||||
item.classList.remove('tapi-search-result-selected');
|
||||
}
|
||||
|
||||
var doSearch = function () {
|
||||
resultLi.classList.add('bg-light');
|
||||
resultLi.classList.add('tapi-search-result-selected');
|
||||
},
|
||||
|
||||
currentSearchText: '',
|
||||
|
||||
doSearch: debounce(() => {
|
||||
var search = document.getElementById('tapiSearchInput');
|
||||
var searchText = search.value.trim();
|
||||
if (searchText == '') {
|
||||
removeSearchResults();
|
||||
tapi.removeSearchResults();
|
||||
return;
|
||||
} else if (searchText == tapi.currentSearchText) {
|
||||
return;
|
||||
}
|
||||
console.log('Searching TAPI');
|
||||
@ -48,9 +94,10 @@ var doSearch = function () {
|
||||
console.log('TAPI Search response', response);
|
||||
var contacts = JSON.parse(response.responseText);
|
||||
console.log('TAPI Contacts', contacts);
|
||||
removeSearchResults();
|
||||
tapi.removeSearchResults();
|
||||
tapi.currentSearchText = searchText;
|
||||
|
||||
resultList = document.createElement('ul');
|
||||
var resultList = document.createElement('ul');
|
||||
resultList.id = 'tapiResults';
|
||||
resultList.classList.add('search-nav-absolute');
|
||||
resultList.classList.add('search-nav-ul');
|
||||
@ -59,25 +106,16 @@ var doSearch = function () {
|
||||
resultList.innerHTML = '';
|
||||
for (var i = 0; i < contacts.length; i++) {
|
||||
var li = document.createElement('li');
|
||||
li.classList.add('tapi-search-result');
|
||||
li.classList.add('search-result');
|
||||
li.classList.add('pointer');
|
||||
li.onmouseover = function () {
|
||||
this.classList.add('bg-light');
|
||||
};
|
||||
li.onmouseout = function () {
|
||||
this.classList.remove('bg-light');
|
||||
tapi.selectResult(this);
|
||||
};
|
||||
li.contact = contacts[i];
|
||||
li.onclick = function () {
|
||||
var contact = this.contact;
|
||||
var searchInput = document.getElementsByName('searchByNumberInput');
|
||||
if (searchInput.length > 0) {
|
||||
searchInput[0].value = contact.tD_NUMBER_TAPI;
|
||||
searchInput[0].focus();
|
||||
|
||||
fireChangeEvents(searchInput[0]);
|
||||
tapi.dial(this);
|
||||
}
|
||||
};
|
||||
li.style.listStyle = 'outside none none'; // display: flex; align-items: center;
|
||||
|
||||
var resultText = document.createElement('div');
|
||||
@ -96,15 +134,60 @@ var doSearch = function () {
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}, 200),
|
||||
|
||||
waitForKeyElements('div.nav-search', (element) => {
|
||||
doSearchKeyDown: (ev) => {
|
||||
var items;
|
||||
if (ev.key == 'ArrowUp') {
|
||||
items = document.getElementsByClassName('tapi-search-result-selected');
|
||||
if (items.length > 0) {
|
||||
var prev = items[0].previousSibling;
|
||||
}
|
||||
if (!prev) {
|
||||
items = document.getElementsByClassName('tapi-search-result');
|
||||
if (items.length > 0) {
|
||||
prev = items[items.length - 1];
|
||||
}
|
||||
}
|
||||
if (prev) {
|
||||
tapi.selectResult(prev);
|
||||
prev.scrollIntoView(true);
|
||||
}
|
||||
} else if (ev.key == 'ArrowDown') {
|
||||
items = document.getElementsByClassName('tapi-search-result-selected');
|
||||
if (items.length > 0) {
|
||||
var next = items[0].nextSibling;
|
||||
}
|
||||
if (!next) {
|
||||
items = document.getElementsByClassName('tapi-search-result');
|
||||
if (items.length > 0) {
|
||||
next = items[0];
|
||||
}
|
||||
}
|
||||
if (next) {
|
||||
tapi.selectResult(next);
|
||||
next.scrollIntoView(false);
|
||||
}
|
||||
} else {
|
||||
tapi.doSearch();
|
||||
}
|
||||
},
|
||||
|
||||
createSearchBox: (element) => {
|
||||
console.log('Create TAPI Search');
|
||||
|
||||
var form = document.createElement('form');
|
||||
form.style.width = '200px';
|
||||
form.style.float = 'right';
|
||||
form.style.marginRight = '20px';
|
||||
form.onsubmit = function () {
|
||||
var items = document.getElementsByClassName('tapi-search-result-selected');
|
||||
if (items.length > 0) {
|
||||
tapi.dial(items[0]);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
var searchBox = document.createElement('div');
|
||||
searchBox.classList.add('contact-search-box');
|
||||
@ -118,19 +201,20 @@ waitForKeyElements('div.nav-search', (element) => {
|
||||
|
||||
var search = document.createElement('input');
|
||||
search.id = 'tapiSearchInput';
|
||||
search.autocomplete = 'off';
|
||||
search.classList.add('padder');
|
||||
search.classList.add('rounded');
|
||||
search.classList.add('bg-light');
|
||||
search.classList.add('no-border');
|
||||
search.classList.add('contact-search-box');
|
||||
search.placeholder = 'TAPI Suche';
|
||||
search.onfocus = doSearch;
|
||||
search.onkeyup = doSearch;
|
||||
search.onfocus = tapi.doSearch;
|
||||
search.onkeydown = tapi.doSearchKeyDown;
|
||||
search.onblur = function () {
|
||||
console.log('TAPI Search exit');
|
||||
setTimeout(function () {
|
||||
console.log('TAPI clear search results');
|
||||
removeSearchResults();
|
||||
tapi.removeSearchResults();
|
||||
}, 500);
|
||||
};
|
||||
searchWrapper.appendChild(search);
|
||||
@ -143,4 +227,7 @@ waitForKeyElements('div.nav-search', (element) => {
|
||||
searchWrapper.appendChild(icon);
|
||||
|
||||
element.appendChild(form);
|
||||
}, false);
|
||||
}
|
||||
};
|
||||
|
||||
waitForKeyElements('div.nav-search', tapi.createSearchBox, false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user