erpnext.ProductSearch = class {
constructor() {
this.MAX_RECENT_SEARCHES = 4;
this.searchBox = $("#search-box");
this.setupSearchDropDown();
this.bindSearchAction();
}
setupSearchDropDown() {
this.search_area = $("#dropdownMenuSearch");
this.setupSearchResultContainer();
this.populateRecentSearches();
}
bindSearchAction() {
let me = this;
// Show Search dropdown
this.searchBox.on("focus", () => {
this.search_dropdown.removeClass("hidden");
});
// If click occurs outside search input/results, hide results.
// Click can happen anywhere on the page
$("body").on("click", (e) => {
let searchEvent = $(e.target).closest('#search-box').length;
let resultsEvent = $(e.target).closest('#search-results-container').length;
let isResultHidden = this.search_dropdown.hasClass("hidden");
if (!searchEvent && !resultsEvent && !isResultHidden) {
this.search_dropdown.addClass("hidden");
}
});
// Process search input
this.searchBox.on("input", (e) => {
let query = e.target.value;
if (query.length == 0) {
me.populateResults([]);
me.populateCategoriesList([]);
}
if (query.length < 3 || !query.length) return;
// Populate recent search chips
me.setRecentSearches(query);
// Fetch and populate product results
frappe.call({
method: "erpnext.templates.pages.product_search.search",
args: {
query: query
},
callback: (data) => {
me.populateResults(data);
}
});
// Populate categories
if (me.category_container) {
frappe.call({
method: "erpnext.templates.pages.product_search.get_category_suggestions",
args: {
query: query
},
callback: (data) => {
me.populateCategoriesList(data);
}
});
}
this.search_dropdown.removeClass("hidden");
});
}
setupSearchResultContainer() {
this.search_dropdown = this.search_area.append(`
`).find("#search-results-container");
this.setupCategoryContainer()
this.setupProductsContainer();
this.setupRecentsContainer();
}
setupProductsContainer() {
this.products_container = this.search_dropdown.append(`
`).find("#product-scroll");
}
setupCategoryContainer() {
this.category_container = this.search_dropdown.append(`
`).find(".category-chips");
}
setupRecentsContainer() {
let $recents_section = this.search_dropdown.append(`
`).find(".recent-searches");
this.recents_container = $recents_section.append(`
`).find("#recents");
}
getRecentSearches() {
return JSON.parse(localStorage.getItem("recent_searches") || "[]");
}
attachEventListenersToChips() {
let me = this;
const chips = $(".recent-search");
window.chips = chips;
for (let chip of chips) {
chip.addEventListener("click", () => {
me.searchBox[0].value = chip.innerText.trim();
// Start search with `recent query`
me.searchBox.trigger("input");
me.searchBox.focus();
});
}
}
setRecentSearches(query) {
let recents = this.getRecentSearches();
if (recents.length >= this.MAX_RECENT_SEARCHES) {
// Remove the `first` query
recents.splice(0, 1);
}
if (recents.indexOf(query) >= 0) {
return;
}
recents.push(query);
localStorage.setItem("recent_searches", JSON.stringify(recents));
this.populateRecentSearches();
}
populateRecentSearches() {
let recents = this.getRecentSearches();
if (!recents.length) {
this.recents_container.html(`No searches yet.`);
return;
}
let html = "";
recents.forEach((key) => {
html += `
`;
});
this.recents_container.html(html);
this.attachEventListenersToChips();
}
populateResults(data) {
if (data.length === 0 || data.message.results.length === 0) {
let empty_html = ``;
this.products_container.html(empty_html);
return;
}
let html = "";
let search_results = data.message.results;
search_results.forEach((res) => {
let thumbnail = res.thumbnail || '/assets/erpnext/images/ui-states/cart-empty-state.png';
html += `
`;
});
this.products_container.html(html);
}
populateCategoriesList(data) {
if (data.length === 0 || data.message.results.length === 0) {
let empty_html = `
`;
this.category_container.html(empty_html);
return;
}
let html = `
${ __("Categories") }
`;
let search_results = data.message.results;
search_results.forEach((category) => {
html += `
${ category.name }
`;
});
this.category_container.html(html);
}
};