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.setupProductsContainer(); this.setupCategoryRecentsContainer(); 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"); } setupProductsContainer() { let $products_section = this.search_dropdown.append(`
`).find("#product-results"); this.products_container = $products_section.append(`
${ __("Type something ...") }
`).find("#product-scroll"); } setupCategoryRecentsContainer() { let $category_recents_section = $("#search-results-container").append(`
`).find("#category-recents-container"); this.category_container = $category_recents_section.append(`
${ __("Categories") }
${ __('No results') }
`).find(".categories"); let $recents_section = $("#category-recents-container").append(`
${ __("Recent") }
`).find(".recent-searches"); this.recents_container = $recents_section.append(`
`).find("#recent-chips"); } getRecentSearches() { return JSON.parse(localStorage.getItem("recent_searches") || "[]"); } attachEventListenersToChips() { let me = this; const chips = $(".recent-chip"); window.chips = chips; for (let chip of chips) { chip.addEventListener("click", () => { me.searchBox[0].value = chip.innerText; // 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) { 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 = `
${ __('No results') }
`; this.products_container.html(empty_html); return; } let html = ""; let search_results = data.message.results; search_results.forEach((res) => { html += ` `; }); this.products_container.html(html); } populateCategoriesList(data) { if (data.length === 0 || data.message.results.length === 0) { let empty_html = ` ${__('No results')} `; this.category_container.html(empty_html); return; } let html = ""; let search_results = data.message.results; search_results.forEach((category) => { html += `
${category.name}
`; }); this.category_container.html(html); } };