頁面提供關鍵字選擇介面:點擊按鈕彈出層 (DIV),層內為 CheckBoxList,使用者勾選後按「確定」,將選中項目的 文字 (Text) 以 | 分隔填入隱藏的 TextBox,送往後端儲存。
<asp:TextBox ID="txtKeywords" runat="server" ReadOnly="true" CssClass="inp" />
<input type="button" id="btnSelect" value="選擇" onclick="showKeywordPanel(this)" />
<div id="keywordPanel" class="panel" style="display:none; position:absolute; border:2px solid #6FA1D9; background:#EAF1FD; width:260px; z-index:100;">
<div class="panel-header" style="background:#6FA1D9; height:20px; cursor:move;">
<span>關鍵字選擇</span>
<button type="button" onclick="confirmKeywords()" style="float:right;">確定</button>
<button type="button" onclick="hidePanel()" style="float:right;">關閉</button>
</div>
<div class="panel-body">
<asp:CheckBoxList ID="cblKeywords" runat="server" RepeatColumns="2" />
</div>
</div>
<script type="text/javascript">
// 顯示面板於按鈕下方
function showKeywordPanel(btn) {
var panel = document.getElementById('keywordPanel');
var left = 0, top = 0;
var el = btn;
while (el) { left += el.offsetLeft; top += el.offsetTop; el = el.offsetParent; }
panel.style.left = left + 'px';
panel.style.top = (top + btn.offsetHeight) + 'px';
panel.style.display = 'block';
// 重置核取方塊
var inputs = panel.querySelectorAll('input[type=checkbox]');
inputs.forEach(function(cb) { cb.checked = false; });
}
function hidePanel() {
document.getElementById('keywordPanel').style.display = 'none';
}
// 取得選中項目文字並寫入 TextBox
function confirmKeywords() {
var cbl = document.getElementById('<%= cblKeywords.ClientID %>');
var checkboxes = cbl.querySelectorAll('input[type=checkbox]');
var labels = cbl.querySelectorAll('label');
var selectedTexts = [];
checkboxes.forEach(function(cb, idx) {
if (cb.checked) {
// 透過 label[for=checkboxId] 找到對應文字
var label = Array.from(labels).find(function(l) {
return l.htmlFor === cb.id;
});
if (label) selectedTexts.push(label.innerText || label.textContent);
}
});
document.getElementById('<%= txtKeywords.ClientID %>').value = selectedTexts.join('|');
hidePanel();
}
</script>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("SELECT KeywordId, KeywordName FROM Keywords", conn))
using (var da = new SqlDataAdapter(cmd))
{
var dt = new DataTable();
da.Fill(dt);
cblKeywords.DataSource = dt;
cblKeywords.DataTextField = "KeywordName";
cblKeywords.DataValueField = "KeywordId";
cblKeywords.DataBind();
}
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
string raw = txtKeywords.Text; // 格式: "關鍵字1|關鍵字2|關鍵字3"
string[] keywords = raw.Split(new[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
// 存入資料庫 (範例: 關聯表)
foreach (string kw in keywords)
{
// INSERT INTO ArticleKeywords (ArticleId, Keyword) VALUES (@aid, @kw)
}
}
| 點 | 說明 |
|---|---|
| ClientID | 使用 <%= cblKeywords.ClientID %> 確保 JS 能精準選取母版頁/命名容器下的控制項。 |
| Label 關聯 | CheckBoxList 渲染為 <input id="cbl_0"><label for="cbl_0">文字</label>,透過 label.htmlFor === checkbox.id 取得顯示文字。 |
| 面板定位 | 累加 offsetLeft/Top 取得按鈕絕對位置,面板 position:absolute 顯示於按鈕下方。 |
| 重置狀態 | 每次開啟面板清空勾選,避免殘留上次選擇誤導使用者。 |
["kw1","kw2"] 替代分隔字串,避免關鍵字本身含 | 造成解析錯誤。