homepage search improvements

#511
This commit is contained in:
Hamid Reza Mohammadi 2026-10-02 13:00:36 +03:30
parent a0a7558d8b
commit b2e03dd839
3 changed files with 123 additions and 28 deletions

View File

@ -57,7 +57,10 @@ else
<div class="actionbox">
<form action="/search" method="get" id="searchhorm">
<input type="text" name="s" id="s" placeholder="جستجو" class="inputText" size="35" value="">
<span class="home-search-input-wrap">
<input type="text" name="s" id="s" placeholder="جستجو" class="inputText" size="35" value="" autocomplete="off" oninput="onHomeSearchInput(this.value)">
<span id="home-search-clear" class="home-search-clear" style="display:none" title="پاک‌کردن" onclick="clearHomeSearch()">×</span>
</span>
<input type="hidden" name="es" id="es" value="1">
<select name="author" id="author">
<option value="0" selected>در آثار همهٔ سخنوران</option>
@ -72,11 +75,15 @@ else
</form>
</div>
<div class="spacer" id="home-found-poets" style="display:none"></div>
<p class="up-hint" id="home-search-hint" style="display:none"><small>برای جستجوی کامل در شعرها کلید اینتر را بزنید یا روی «بیاب» کلیک کنید؛ فهرست زیر فقط جستجوی نام سخنوران است.</small></p>
<partial name="_InlineLoginPartial" model="Model" />
<div id="main">
<div id="guides">
<div id="home-popular-poets-row">
<div class="century">
سخنوران پرمخاطب
</div>
@ -93,7 +100,7 @@ else
<div class="spacer">
@foreach (var poet in popularGroup.Poets)
{
<div class="poet">
<div class="poet" data-value="@poet.Nickname">
<a href="@poet.FullUrl" title="@poet.Name">
<img src="@(GanjooRazor.APIRoot.InternetUrl+poet.ImageUrl)" alt="@poet.Name">
</a>
@ -103,10 +110,10 @@ else
</div>
}
</div>
<div class="clear-both">
<input type="text" id="findpoet" placeholder="جستجوی سخنور" size="35" value="" oninput="onInlineSearch(this.value, 'found-poets', 'poet')">
<div class="spacer" id="found-poets"></div>
}
</div>
@{
<div class="century" id="cl">
دسته‌بندی بر اساس قرن
</div>

View File

@ -303,6 +303,45 @@ select {
text-align: left
}
/* #searchhorm input, #searchhorm select, #searchhorm label (further below in this file) float
them all right, which is how the search box's input/combo/button end up in the right order in
this RTL layout - each one floats to the right of the one before it. Wrapping the text input in
this span for the clear button moved it out from under that rule (a plain, non-floated span
isn't selected by "#searchhorm input"), which is what reshuffled the search box the first time
this shipped. Floating the wrapper itself the same way, and cancelling the float that still lands
on the nested input, restores the original left-to-right float order. */
#searchhorm .home-search-input-wrap {
position: relative;
float: right;
margin: 1px;
}
#searchhorm .home-search-input-wrap input {
float: none;
margin: 0;
}
#searchhorm .home-search-input-wrap .inputText {
padding-inline-end: 20px;
}
.home-search-clear {
position: absolute;
inset-inline-end: 4px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
font-size: 1.1em;
line-height: 1;
color: var(--text-muted);
padding: 0 3px;
user-select: none;
}
.home-search-clear:hover {
color: var(--ink-black);
}
#guides {
max-width: 860px;
display: block;

View File

@ -1554,6 +1554,55 @@ function persianizeNumerals(value) {
.replace(/9/gi, "۹");
}
// Home page (Index.cshtml) only: the top search box (#s) used to just submit a full poem search
// (POST-free GET to /search) and the home page separately had its own "جستجوی سخنور" inline box
// (#findpoet, now removed) that filtered the poet list live as you typed. This merges that second
// behavior into the top box: typing filters poets live (same underlying match as onInlineSearch,
// against every ".poet" element's data-value), while submitting the form (Enter / the "بیاب" button)
// still does the original full poem search unchanged - so nothing about submission itself changes.
function onHomeSearchInput(value) {
var clearBtn = document.getElementById('home-search-clear');
var popularRow = document.getElementById('home-popular-poets-row');
var foundNode = document.getElementById('home-found-poets');
var hintNode = document.getElementById('home-search-hint');
if (!foundNode) return;
var hasValue = value.length > 0;
if (clearBtn) clearBtn.style.display = hasValue ? 'inline' : 'none';
if (popularRow) popularRow.style.display = hasValue ? 'none' : '';
if (hintNode) hintNode.style.display = hasValue ? 'block' : 'none';
foundNode.innerHTML = '';
if (!hasValue) {
foundNode.style.display = 'none';
return;
}
var replaced = persianizeNumerals(value);
// querySelectorAll (not getElementsByClassName) is required here: getElementsByClassName
// returns a LIVE collection, and the clones we append below also carry class="poet" and land
// earlier in document order than the originals (home-found-poets sits above the poet lists) -
// every append was reshuffling the live collection's indices so the same source element kept
// reappearing at the loop's current index forever, hanging the page. querySelectorAll takes a
// static snapshot up front, so appends during the loop can't affect it.
var poets = document.querySelectorAll('.poet');
for (var i = 0; i < poets.length; i++) {
var dataValue = poets[i].getAttribute('data-value');
if (dataValue != null && dataValue.indexOf(replaced) !== -1) {
foundNode.appendChild(poets[i].cloneNode(true));
}
}
foundNode.style.display = foundNode.childElementCount > 0 ? '' : 'none';
}
function clearHomeSearch() {
var input = document.getElementById('s');
if (!input) return;
input.value = '';
onHomeSearchInput('');
input.focus();
}
function onInlineSearch(value, resultBlockId, itemsClass) {
const foundPoetsNode = document.getElementById(resultBlockId);
foundPoetsNode.innerHTML = '';