refactor: 日终价格联想逻辑抽成共享 eodUnderlyingSuggest.js 并修复下拉静默失效

- 三编辑页重复的 eodSuggest/eodRenderSuggest/eodHideSuggest/checkSubmitData/初始化 抽成 eodUnderlyingSuggest.js 一处引用,禁止逐页复制内联脚本

- 修复静默 bug:cshtml 缺 #eodSuggestBox 容器且 class 无 CSS 导致下拉从未渲染;改为 JS 动态创建盒子+样式内联

- 修复点选 ReferenceError:回调由对象字面量求值改为 window['lookup'+kind] 安全解析+typeof 校验
This commit is contained in:
hjhan
2026-07-13 13:30:35 +08:00
parent 045361dd9b
commit d978f7048d
4 changed files with 93 additions and 204 deletions
@@ -6,17 +6,8 @@
}
@section JS
{
<script src="~/Scripts/app/eod/eodUnderlyingSuggest.js?v=@(HtmlUtil.JsVersion)"></script>
<script type="text/javascript">
$(function () {
$(".datepicker").datepicker({ changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true });
$(".form-group").addClass("col-md-6");
});
function checkSubmitData() {
var pass = $('#form1').valid();
return pass;
}
// 手工输入债券代码后失焦:校验标的存在且已上市,并带出市场
function lookupBond() {
var el = document.getElementById('bond_id');
@@ -42,64 +33,6 @@
main.parentReloadData();
});
}
// 服务端模糊联想:输入时按需查前20条匹配(代码或名称),原生下拉,不用插件
var _eodSuggestTimer = null;
function eodSuggest(input, kind) {
clearTimeout(_eodSuggestTimer);
var q = (input.value || '').trim();
if (q.length < 1) { eodHideSuggest(); return; }
_eodSuggestTimer = setTimeout(function () {
main.post('/eodPrice/SuggestUnderlyingForEod', { q: q, kind: kind }).done(function (res) {
if (res.success && res.obj && res.obj.length) {
eodRenderSuggest(res.obj, input, kind);
} else {
eodHideSuggest();
}
});
}, 250);
}
function eodRenderSuggest(list, input, kind) {
var box = document.getElementById('eodSuggestBox');
if (!box) return;
box.innerHTML = '';
list.forEach(function (item) {
var div = document.createElement('div');
div.className = 'eod-suggest-item';
var code = document.createElement('span');
code.className = 'eod-suggest-code';
code.textContent = item.Code;
var name = document.createElement('span');
name.className = 'eod-suggest-name';
name.textContent = item.Name || '';
div.appendChild(code); div.appendChild(name);
div.onmousedown = function (e) {
e.preventDefault();
input.value = item.Code;
eodHideSuggest();
var fn = { bond: lookupBond, future: lookupFuture, stock: lookupStock }[kind];
if (fn) fn();
};
box.appendChild(div);
});
var r = input.getBoundingClientRect();
box.style.left = r.left + 'px';
box.style.top = (r.bottom + 2) + 'px';
box.style.width = Math.max(r.width, 220) + 'px';
box.style.display = 'block';
}
function eodHideSuggest() {
var b = document.getElementById('eodSuggestBox');
if (b) b.style.display = 'none';
}
document.addEventListener('click', function (e) {
var b = document.getElementById('eodSuggestBox');
if (b && b.style.display === 'block' && !b.contains(e.target)
&& e.target.id !== 'bond_id' && e.target.id !== 'UnderlyingCode') {
b.style.display = 'none';
}
});
</script>
}
<form class="yc-panel" id="form1" method="post" onsubmit="return false;">
@@ -6,17 +6,8 @@
}
@section JS
{
<script src="~/Scripts/app/eod/eodUnderlyingSuggest.js?v=@(HtmlUtil.JsVersion)"></script>
<script type="text/javascript">
$(function () {
$(".datepicker").datepicker({ changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true });
$(".form-group").addClass("col-md-6");
});
function checkSubmitData() {
var pass = $('#form1').valid();
return pass;
}
// 手工输入期货合约代码后失焦:校验标的存在且已上市,带出市场并回填 UnderlyingId(列表查询按此 join)
function lookupFuture() {
var el = document.getElementById('UnderlyingCode');
@@ -48,64 +39,6 @@
main.parentReloadData();
});
}
// 服务端模糊联想:输入时按需查前20条匹配(代码或名称),原生下拉,不用插件
var _eodSuggestTimer = null;
function eodSuggest(input, kind) {
clearTimeout(_eodSuggestTimer);
var q = (input.value || '').trim();
if (q.length < 1) { eodHideSuggest(); return; }
_eodSuggestTimer = setTimeout(function () {
main.post('/eodPrice/SuggestUnderlyingForEod', { q: q, kind: kind }).done(function (res) {
if (res.success && res.obj && res.obj.length) {
eodRenderSuggest(res.obj, input, kind);
} else {
eodHideSuggest();
}
});
}, 250);
}
function eodRenderSuggest(list, input, kind) {
var box = document.getElementById('eodSuggestBox');
if (!box) return;
box.innerHTML = '';
list.forEach(function (item) {
var div = document.createElement('div');
div.className = 'eod-suggest-item';
var code = document.createElement('span');
code.className = 'eod-suggest-code';
code.textContent = item.Code;
var name = document.createElement('span');
name.className = 'eod-suggest-name';
name.textContent = item.Name || '';
div.appendChild(code); div.appendChild(name);
div.onmousedown = function (e) {
e.preventDefault();
input.value = item.Code;
eodHideSuggest();
var fn = { bond: lookupBond, future: lookupFuture, stock: lookupStock }[kind];
if (fn) fn();
};
box.appendChild(div);
});
var r = input.getBoundingClientRect();
box.style.left = r.left + 'px';
box.style.top = (r.bottom + 2) + 'px';
box.style.width = Math.max(r.width, 220) + 'px';
box.style.display = 'block';
}
function eodHideSuggest() {
var b = document.getElementById('eodSuggestBox');
if (b) b.style.display = 'none';
}
document.addEventListener('click', function (e) {
var b = document.getElementById('eodSuggestBox');
if (b && b.style.display === 'block' && !b.contains(e.target)
&& e.target.id !== 'bond_id' && e.target.id !== 'UnderlyingCode') {
b.style.display = 'none';
}
});
</script>
}
<form class="yc-panel" id="form1" method="post" onsubmit="return false;">
@@ -6,17 +6,8 @@
}
@section JS
{
<script src="~/Scripts/app/eod/eodUnderlyingSuggest.js?v=@(HtmlUtil.JsVersion)"></script>
<script type="text/javascript">
$(function () {
$(".datepicker").datepicker({ changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true });
$(".form-group").addClass("col-md-6");
});
function checkSubmitData() {
var pass = $('#form1').valid();
return pass;
}
// 手工输入股票代码后失焦:校验标的存在且已上市,并带出市场
function lookupStock() {
var el = document.getElementById('UnderlyingCode');
@@ -42,64 +33,6 @@
main.parentReloadData();
});
}
// 服务端模糊联想:输入时按需查前20条匹配(代码或名称),原生下拉,不用插件
var _eodSuggestTimer = null;
function eodSuggest(input, kind) {
clearTimeout(_eodSuggestTimer);
var q = (input.value || '').trim();
if (q.length < 1) { eodHideSuggest(); return; }
_eodSuggestTimer = setTimeout(function () {
main.post('/eodPrice/SuggestUnderlyingForEod', { q: q, kind: kind }).done(function (res) {
if (res.success && res.obj && res.obj.length) {
eodRenderSuggest(res.obj, input, kind);
} else {
eodHideSuggest();
}
});
}, 250);
}
function eodRenderSuggest(list, input, kind) {
var box = document.getElementById('eodSuggestBox');
if (!box) return;
box.innerHTML = '';
list.forEach(function (item) {
var div = document.createElement('div');
div.className = 'eod-suggest-item';
var code = document.createElement('span');
code.className = 'eod-suggest-code';
code.textContent = item.Code;
var name = document.createElement('span');
name.className = 'eod-suggest-name';
name.textContent = item.Name || '';
div.appendChild(code); div.appendChild(name);
div.onmousedown = function (e) {
e.preventDefault();
input.value = item.Code;
eodHideSuggest();
var fn = { bond: lookupBond, future: lookupFuture, stock: lookupStock }[kind];
if (fn) fn();
};
box.appendChild(div);
});
var r = input.getBoundingClientRect();
box.style.left = r.left + 'px';
box.style.top = (r.bottom + 2) + 'px';
box.style.width = Math.max(r.width, 220) + 'px';
box.style.display = 'block';
}
function eodHideSuggest() {
var b = document.getElementById('eodSuggestBox');
if (b) b.style.display = 'none';
}
document.addEventListener('click', function (e) {
var b = document.getElementById('eodSuggestBox');
if (b && b.style.display === 'block' && !b.contains(e.target)
&& e.target.id !== 'bond_id' && e.target.id !== 'UnderlyingCode') {
b.style.display = 'none';
}
});
</script>
}
<form class="yc-panel" id="form1" method="post" onsubmit="return false;">
@@ -0,0 +1,90 @@
// 日终价格编辑页公共逻辑:标的代码输入联想(服务端模糊匹配 + 原生下拉)
// 由 eodBondPriceEdit / eodFuturePriceEdit / eodStockPriceEdit 三个页面共用,避免重复代码。
// 下拉盒子由本文件动态创建、样式全部内联,不依赖任何 HTML 容器或外部 CSS。
$(function () {
$(".datepicker").datepicker({ changeMonth: true, changeYear: true, showButtonPanel: true, showOtherMonths: true, selectOtherMonths: true });
$(".form-group").addClass("col-md-6");
ensureEodSuggestBox();
});
function checkSubmitData() {
var pass = $('#form1').valid();
return pass;
}
var _eodSuggestTimer = null;
var _eodSuggestActiveInput = null;
function ensureEodSuggestBox() {
if (document.getElementById('eodSuggestBox')) return;
var box = document.createElement('div');
box.id = 'eodSuggestBox';
box.style.cssText = 'display:none;position:fixed;z-index:9999;background:#fff;border:1px solid #ccc;' +
'max-height:240px;overflow:auto;box-shadow:0 2px 8px rgba(0,0,0,.15);font-size:13px;';
document.body.appendChild(box);
}
// 服务端模糊联想:输入时按需查前20条匹配(代码或名称),原生下拉,不用插件
function eodSuggest(input, kind) {
_eodSuggestActiveInput = input;
clearTimeout(_eodSuggestTimer);
var q = (input.value || '').trim();
if (q.length < 1) { eodHideSuggest(); return; }
_eodSuggestTimer = setTimeout(function () {
main.post('/eodPrice/SuggestUnderlyingForEod', { q: q, kind: kind }).done(function (res) {
if (res.success && res.obj && res.obj.length) {
eodRenderSuggest(res.obj, input, kind);
} else {
eodHideSuggest();
}
});
}, 250);
}
function eodRenderSuggest(list, input, kind) {
var box = document.getElementById('eodSuggestBox');
if (!box) return;
box.innerHTML = '';
list.forEach(function (item) {
var div = document.createElement('div');
div.style.cssText = 'padding:6px 10px;cursor:pointer;white-space:nowrap;border-bottom:1px solid #f0f0f0;';
div.onmouseenter = function () { div.style.background = '#f2f6ff'; };
div.onmouseleave = function () { div.style.background = '#fff'; };
var code = document.createElement('span');
code.style.cssText = 'display:inline-block;min-width:90px;font-weight:600;color:#333;';
code.textContent = item.Code;
var name = document.createElement('span');
name.style.cssText = 'display:inline-block;color:#888;margin-left:10px;';
name.textContent = item.Name || '';
div.appendChild(code); div.appendChild(name);
div.onmousedown = function (e) {
e.preventDefault();
input.value = item.Code;
eodHideSuggest();
// 按 kind 安全解析各页面自定义的 lookup 回调(函数名字符串,避免引用未定义函数导致 ReferenceError
var fnName = { bond: 'lookupBond', future: 'lookupFuture', stock: 'lookupStock' }[kind];
if (fnName && typeof window[fnName] === 'function') window[fnName]();
};
box.appendChild(div);
});
var r = input.getBoundingClientRect();
box.style.left = r.left + 'px';
box.style.top = (r.bottom + 2) + 'px';
box.style.width = Math.max(r.width, 240) + 'px';
box.style.display = 'block';
}
function eodHideSuggest() {
var b = document.getElementById('eodSuggestBox');
if (b) b.style.display = 'none';
}
document.addEventListener('click', function (e) {
var b = document.getElementById('eodSuggestBox');
if (b && b.style.display === 'block' && !b.contains(e.target) && e.target !== _eodSuggestActiveInput) {
b.style.display = 'none';
}
});