fixed field object search ranking
This commit is contained in:
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user