- Layout image_select previews (zibll PNGs under assets/images/header-layout) - Localize aksrtAdminData.themeUri for admin SPA asset URLs - Layout-2 inline search AJAX suggestions via aksrt_search_suggestions - Appearance→Menus visual senior submenu editor (cards/columns) - Acceptance checklist + automated source contract report
141 lines
4.7 KiB
JavaScript
141 lines
4.7 KiB
JavaScript
/**
|
|
* Enhance layout-2 inline search with AJAX suggestions (aksrt_search_suggestions).
|
|
* Extends existing panel search without dual systems.
|
|
*/
|
|
(function () {
|
|
"use strict";
|
|
|
|
function initInlineSearchSuggest() {
|
|
var form = document.querySelector('form[data-aksrt-search-form="inline"]');
|
|
if (!form || !window.aksrtData || !aksrtData.ajaxUrl) return;
|
|
|
|
var input = form.querySelector(".search-input");
|
|
var group = form.querySelector(".form-group.relative, .form-group");
|
|
if (!input || !group) return;
|
|
|
|
var panel = group.querySelector(".navbar-inline-search-panel");
|
|
if (!panel) {
|
|
panel = document.createElement("div");
|
|
panel.className = "dropdown-menu hover-show-con navbar-inline-search-panel";
|
|
group.appendChild(panel);
|
|
}
|
|
|
|
var timer = null;
|
|
var searchConfig = (window.aksrtData && aksrtData.search) || {};
|
|
var suggestionsEnabled = searchConfig.suggestionsEnabled !== false;
|
|
|
|
function typeValue() {
|
|
var t = form.querySelector('input[name="aksrt_search_type"]');
|
|
return (t && t.value) || searchConfig.defaultType || "post";
|
|
}
|
|
|
|
function renderItems(items) {
|
|
var html = "";
|
|
if (items && items.length) {
|
|
html += '<div class="muted-2-color em09 mb6">' + (searchConfig.suggestTitle || "搜索建议") + "</div>";
|
|
html += '<div class="navbar-inline-search-suggest">';
|
|
items.forEach(function (it) {
|
|
html +=
|
|
'<a class="navbar-inline-search-suggest__item" href="' +
|
|
(it.url || "#") +
|
|
'"><span class="title">' +
|
|
(it.title || "") +
|
|
'</span>' +
|
|
(it.meta ? '<span class="meta muted-2-color em09">' + it.meta + "</span>" : "") +
|
|
"</a>";
|
|
});
|
|
html += "</div>";
|
|
}
|
|
// Keep hot keywords block if present as static sibling content was replaced —
|
|
// re-append hots from data attribute if we stored them.
|
|
var hots = form.getAttribute("data-hots");
|
|
if (hots) {
|
|
try {
|
|
var arr = JSON.parse(hots);
|
|
if (arr && arr.length) {
|
|
html += '<div class="muted-2-color em09 mb6 mt10">热门搜索</div><div class="navbar-inline-search-hots">';
|
|
arr.forEach(function (kw) {
|
|
html +=
|
|
'<a class="but jb-sm" href="' +
|
|
(window.location.origin || "") +
|
|
"/?s=" +
|
|
encodeURIComponent(kw) +
|
|
'">' +
|
|
kw +
|
|
"</a> ";
|
|
});
|
|
html += "</div>";
|
|
}
|
|
} catch (e) {}
|
|
}
|
|
panel.innerHTML = html || panel.innerHTML;
|
|
panel.classList.add("is-open");
|
|
panel.style.display = "block";
|
|
panel.style.visibility = "visible";
|
|
}
|
|
|
|
// Persist hot keywords for re-render after suggestions
|
|
var hotLinks = panel.querySelectorAll(".navbar-inline-search-hots a");
|
|
if (hotLinks.length) {
|
|
var kws = [];
|
|
hotLinks.forEach(function (a) {
|
|
kws.push((a.textContent || "").trim());
|
|
});
|
|
form.setAttribute("data-hots", JSON.stringify(kws));
|
|
}
|
|
|
|
function request(q) {
|
|
if (!suggestionsEnabled || q.length < 2) {
|
|
// restore hots-only
|
|
if (form.getAttribute("data-hots")) {
|
|
renderItems([]);
|
|
}
|
|
return;
|
|
}
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open("POST", aksrtData.ajaxUrl, true);
|
|
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
|
xhr.onload = function () {
|
|
if (xhr.status < 200 || xhr.status >= 300) return;
|
|
try {
|
|
var json = JSON.parse(xhr.responseText);
|
|
if (json.success && json.data && json.data.items) {
|
|
renderItems(json.data.items);
|
|
}
|
|
} catch (e) {}
|
|
};
|
|
xhr.send(
|
|
"action=aksrt_search_suggestions&nonce=" +
|
|
encodeURIComponent(aksrtData.nonce) +
|
|
"&q=" +
|
|
encodeURIComponent(q) +
|
|
"&type=" +
|
|
encodeURIComponent(typeValue())
|
|
);
|
|
}
|
|
|
|
input.addEventListener("input", function () {
|
|
var q = (input.value || "").trim();
|
|
if (timer) clearTimeout(timer);
|
|
timer = setTimeout(function () {
|
|
request(q);
|
|
}, 180);
|
|
});
|
|
|
|
input.addEventListener("focus", function () {
|
|
panel.style.display = "block";
|
|
panel.style.visibility = "visible";
|
|
});
|
|
}
|
|
|
|
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === "function") {
|
|
window.AksrtFrontend.register("aksrt-inline-search-suggest", function () {
|
|
initInlineSearchSuggest();
|
|
});
|
|
} else if (document.readyState === "loading") {
|
|
document.addEventListener("DOMContentLoaded", initInlineSearchSuggest);
|
|
} else {
|
|
initInlineSearchSuggest();
|
|
}
|
|
})();
|