Files
qihuo/static/js/symbol.js
T

132 lines
4.9 KiB
JavaScript

(function () {
function formatSub(item) {
return '同花顺 ' + item.ths_code +
(item.market_code ? ' · ' + item.market_code : '') +
' · ' + (item.exchange || '');
}
function formatInputLabel(item) {
return item.input_label || (item.name + ' ' + item.ths_code);
}
function initSymbolInput(wrapper) {
const input = wrapper.querySelector('.symbol-input');
const hiddenThs = wrapper.querySelector('input[name="symbol"]');
const hiddenName = wrapper.querySelector('input[name="symbol_name"]');
const hiddenMarket = wrapper.querySelector('input[name="market_code"]');
const hiddenSina = wrapper.querySelector('input[name="sina_code"]');
const dropdown = wrapper.querySelector('.symbol-dropdown');
const selectedEl = wrapper.querySelector('.symbol-selected');
let timer = null;
let abortCtrl = null;
const cache = new Map();
function hideDropdown() {
dropdown.classList.remove('show');
}
function selectItem(item) {
const label = formatInputLabel(item);
input.value = label;
hiddenThs.value = item.ths_code;
hiddenName.value = item.name;
if (hiddenMarket) hiddenMarket.value = item.market_code || '';
if (hiddenSina) hiddenSina.value = item.sina_code || '';
selectedEl.textContent = formatSub(item);
hideDropdown();
}
function renderItems(items) {
dropdown.innerHTML = '';
if (!items.length) {
dropdown.innerHTML = '<div class="symbol-option">无匹配,可输入同花顺代码如 ag2608</div>';
} else {
items.forEach(function (item) {
const div = document.createElement('div');
div.className = 'symbol-option';
div.innerHTML = item.display +
'<div class="sub">' + formatSub(item) + '</div>';
div.addEventListener('mousedown', function (e) {
e.preventDefault();
selectItem(item);
});
dropdown.appendChild(div);
});
}
dropdown.classList.add('show');
}
function search(q) {
if (cache.has(q)) {
renderItems(cache.get(q));
return;
}
if (abortCtrl) {
abortCtrl.abort();
}
abortCtrl = new AbortController();
fetch('/api/symbols/search?q=' + encodeURIComponent(q), {
signal: abortCtrl.signal,
})
.then(function (r) { return r.json(); })
.then(function (items) {
cache.set(q, items);
renderItems(items);
})
.catch(function (err) {
if (err && err.name === 'AbortError') return;
hideDropdown();
});
}
input.addEventListener('input', function () {
hiddenThs.value = '';
hiddenName.value = '';
if (hiddenMarket) hiddenMarket.value = '';
if (hiddenSina) hiddenSina.value = '';
selectedEl.textContent = '';
const q = input.value.trim();
if (!q) {
hideDropdown();
return;
}
clearTimeout(timer);
timer = setTimeout(function () {
search(q);
}, 120);
});
input.addEventListener('blur', function () {
setTimeout(hideDropdown, 150);
});
input.addEventListener('focus', function () {
const q = input.value.trim();
if (q && !hiddenThs.value) {
search(q);
}
});
}
document.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.symbol-wrap').forEach(initSymbolInput);
document.querySelectorAll('form').forEach(function (form) {
if (!form.querySelector('.symbol-wrap')) return;
form.addEventListener('submit', function (e) {
const ths = form.querySelector('input[name="symbol"]');
const market = form.querySelector('input[name="market_code"]');
if (ths && !ths.value.trim()) {
e.preventDefault();
alert('请从下拉列表选择品种');
return;
}
if (market && !market.value.trim()) {
e.preventDefault();
alert('请从下拉列表选择品种(需含同花顺行情代码)');
}
});
});
});
})();