window.lat.widget('ref-picker', function (root) {
var hidden = root.querySelector('[data-refpicker-id]');
var search = root.querySelector('[data-refpicker-search]');
var menu = root.querySelector('[data-refpicker-menu]');
if (!hidden || !search || !menu) return;
var searchUrl = root.getAttribute('data-search');
var resolveUrl = root.getAttribute('data-resolve');
var currentLabel = '';
function query(url, payload) {
return fetch(url, {
method: 'QUERY',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then(function (resp) {
var ct = resp.headers.get('content-type') || '';
if (!resp.ok || ct.indexOf('application/json') === -1) return null;
return resp.json();
}).catch(function () { return null; });
}
function closeMenu() {
menu.hidden = true;
menu.innerHTML = '';
root.classList.remove('is-open');
}
function choose(node) {
hidden.value = node.id;
currentLabel = node.label;
search.value = node.label;
closeMenu();
}
function renderMenu(items) {
menu.innerHTML = '';
if (!items || !items.length) {
closeMenu();
return;
}
items.forEach(function (node) {
var li = document.createElement('li');
li.className = 'lat-refpicker__item';
li.textContent = node.hint ? node.label + ' ยท ' + node.hint : node.label;
li._node = node;
menu.appendChild(li);
});
menu.hidden = false;
root.classList.add('is-open');
}
menu.addEventListener('mousedown', function (e) {
e.preventDefault();
});
menu.addEventListener('click', function (e) {
var li = e.target.closest('.lat-refpicker__item');
if (li && li._node) choose(li._node);
});
if (hidden.value) {
query(resolveUrl, { id: hidden.value }).then(function (data) {
if (data && data.item) {
currentLabel = data.item.label;
search.value = data.item.label;
}
});
}
var timer = null;
var seq = 0;
function runSearch(q) {
var mine = ++seq;
query(searchUrl, { q: q, limit: 20 }).then(function (data) {
if (mine !== seq) return; renderMenu(data && data.items);
});
}
search.addEventListener('focus', function () {
search.select();
runSearch('');
});
search.addEventListener('input', function () {
clearTimeout(timer);
var q = search.value.trim();
timer = setTimeout(function () {
runSearch(q);
}, 200);
});
search.addEventListener('blur', function () {
setTimeout(function () {
closeMenu();
search.value = currentLabel;
}, 150);
});
});