fixed field object search ranking

This commit is contained in:
2026-07-22 14:04:50 +02:00
parent df1ddce0a6
commit a300932421
+64 -2
View File
@@ -143,7 +143,54 @@
}),
);
}
// Ranking inizio/centro/fine per select con dati già in memoria.
// Restituisce { matcher, sorter } da passare a select2().
function rankedLocalSelect2() {
return {
matcher: function (params, data) {
const term = $.trim(params.term || "").toLowerCase();
if (term === "") return data;
if (typeof data.text === "undefined") return null;
// AND multi-termine, posizione indipendente
const text = data.text.toLowerCase();
const terms = term.split(/\s+/).filter(Boolean);
const all = terms.every((t) => text.indexOf(t) !== -1);
return all ? data : null;
},
sorter: function (results) {
const term = $(
".select2-container--open .select2-search__field",
).val();
const search = (term || "").toLowerCase().trim();
if (!search) return results;
const first = search.split(/\s+/)[0];
function score(text) {
const t = (text || "").toLowerCase();
if (t === search) return 0; // match esatto
if (t.indexOf(first) === 0) return 1; // inizia col termine
if (new RegExp("(^|\\s)" + escapeRegExp(first)).test(t))
return 2; // inizio parola
return 3; // in mezzo
}
return results.slice().sort(function (a, b) {
const sa = score(a.text);
const sb = score(b.text);
if (sa !== sb) return sa - sb;
return (a.text || "").localeCompare(b.text || "", "it", {
sensitivity: "base",
});
});
},
};
}
function escapeRegExp(s) {
return String(s).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function sortSelect2ResultsByStart(data) {
const term = $(".select2-container--open .select2-search__field").val();
@@ -683,7 +730,7 @@
const reqCls = col.isRequired ? " required-input" : "";
const req = col.isRequired ? " required" : "";
return `<select class="cell-input manual-input fixed-input ${selectClass}${reqCls}" data-fixed-key="${escAttr(col.key)}" data-current-value="${escAttr(value)}"${req}>${options}</select>`;
return `<select class="cell-input manual-input fixed-input searchable-fixed ${selectClass}${reqCls}" data-fixed-key="${escAttr(col.key)}" data-current-value="${escAttr(value)}"${req}>${options}</select>`;
}
function buildDropdownOptionsHTML(fieldId, selectedValue) {
@@ -1203,6 +1250,12 @@
items.forEach((item) =>
sel.add(new Option(item.text, item.id)),
);
$(sel).select2({
placeholder: "Seleziona...",
allowClear: true,
width: "100%",
...rankedLocalSelect2(),
});
}
});
@@ -1705,9 +1758,18 @@
const fieldId = this.dataset.fieldId;
if (fieldId) $(this).select2(sceltaSelect2Config(fieldId));
});
$(this)
.find(".searchable-fixed:not(.select2-hidden-accessible)")
.each(function () {
$(this).select2({
placeholder: "Seleziona...",
allowClear: true,
width: "100%",
...rankedLocalSelect2(),
});
});
});
}
// ── Column resize ──────────────────────────────────────────────────────
function initColumnResizers() {