feat: Search UI
- Search UI with dropdown results
- Client class to handle Product Search actions and results
- Integrated Search bar into all-products and item group pages
- Run db search without redisearch
- Cleanup: [Search] change decorator names and variables
- Sider fixes
diff --git a/erpnext/templates/generators/item_group.html b/erpnext/templates/generators/item_group.html
index 20ad7fb..0b2fb03 100644
--- a/erpnext/templates/generators/item_group.html
+++ b/erpnext/templates/generators/item_group.html
@@ -2,7 +2,16 @@
{% extends "templates/web.html" %}
{% block header %}
-<!-- <h2>{{ title }}</h2> -->
+<div class="row mb-6" style="width: 65vw">
+ <div class="mb-6 col-4 order-1">{{ title }}</div>
+
+ <div class="input-group mb-6 col-8 order-2">
+ <div class="dropdown w-100" id="dropdownMenuSearch">
+ <input type="search" name="query" id="search-box" class="form-control" placeholder="Search for products..." aria-label="Product" aria-describedby="button-addon2">
+ <!-- Results dropdown rendered in product_search.js -->
+ </div>
+ </div>
+</div>
{% endblock header %}
{% block script %}
@@ -19,7 +28,7 @@
<div class="item-group-content" itemscope itemtype="http://schema.org/Product"
data-item-group="{{ name }}">
<div class="item-group-slideshow">
- {% if slideshow %}<!-- slideshow -->
+ {% if slideshow %} <!-- slideshow -->
{{ web_block(
"Hero Slider",
values=slideshow,
@@ -28,8 +37,8 @@
add_bottom_padding=0,
) }}
{% endif %}
- <h2 class="mt-3">{{ title }}</h2>
- {% if description %}<!-- description -->
+
+ {% if description %} <!-- description -->
<div class="item-group-description text-muted mb-5" itemprop="description">{{ description or ""}}</div>
{% endif %}
</div>
diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js
index 28fe882..c766dfd 100644
--- a/erpnext/templates/includes/cart.js
+++ b/erpnext/templates/includes/cart.js
@@ -163,7 +163,7 @@
item_code: item_code,
qty: 0
});
- })
+ });
},
render_tax_row: function($cart_taxes, doc, shipping_rules) {
diff --git a/erpnext/templates/pages/product_search.py b/erpnext/templates/pages/product_search.py
index 12967fa..190abfd 100644
--- a/erpnext/templates/pages/product_search.py
+++ b/erpnext/templates/pages/product_search.py
@@ -7,7 +7,6 @@
from erpnext.setup.doctype.item_group.item_group import get_item_for_list_in_html
from erpnext.e_commerce.shopping_cart.product_info import set_product_info_for_website
-# For SEARCH -------
from redisearch import AutoCompleter, Client, Query
from erpnext.e_commerce.website_item_indexing import (
is_search_module_loaded,
@@ -16,7 +15,6 @@
WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE,
make_key
)
-# -----------------
no_cache = 1
@@ -36,30 +34,29 @@
def get_product_data(search=None, start=0, limit=12):
# limit = 12 because we show 12 items in the grid view
# base query
- query = """select I.name, I.item_name, I.item_code, I.route, I.image, I.website_image, I.thumbnail, I.item_group,
- I.description, I.web_long_description as website_description, I.is_stock_item,
- case when (S.actual_qty - S.reserved_qty) > 0 then 1 else 0 end as in_stock, I.website_warehouse,
- I.has_batch_no
- from `tabItem` I
- left join tabBin S on I.item_code = S.item_code and I.website_warehouse = S.warehouse
- where (I.show_in_website = 1)
- and I.disabled = 0
- and (I.end_of_life is null or I.end_of_life='0000-00-00' or I.end_of_life > %(today)s)"""
+ query = """
+ Select
+ web_item_name, item_name, item_code, brand, route,
+ website_image, thumbnail, item_group,
+ description, web_long_description as website_description,
+ website_warehouse, ranking
+ from `tabWebsite Item`
+ where published = 1
+ """
# search term condition
if search:
- query += """ and (I.web_long_description like %(search)s
- or I.description like %(search)s
- or I.item_name like %(search)s
- or I.name like %(search)s)"""
+ query += """ and (item_name like %(search)s
+ or web_item_name like %(search)s
+ or brand like %(search)s
+ or web_long_description like %(search)s)"""
search = "%" + cstr(search) + "%"
# order by
- query += """ order by I.weightage desc, in_stock desc, I.modified desc limit %s, %s""" % (cint(start), cint(limit))
+ query += """ order by ranking asc, modified desc limit %s, %s""" % (cint(start), cint(limit))
return frappe.db.sql(query, {
- "search": search,
- "today": nowdate()
+ "search": search
}, as_dict=1)
@frappe.whitelist(allow_guest=True)
@@ -112,11 +109,19 @@
@frappe.whitelist(allow_guest=True)
def get_category_suggestions(query):
- search_results = {"from_redisearch": True, "results": []}
+ search_results = {"results": []}
if not is_search_module_loaded():
- # Redisearch module not loaded
- search_results["from_redisearch"] = False
+ # Redisearch module not loaded, query db
+ categories = frappe.db.get_all(
+ "Item Group",
+ filters={
+ "name": ["like", "%{0}%".format(query)],
+ "show_in_website": 1
+ },
+ fields=["name", "route"]
+ )
+ search_results['results'] = categories
return search_results
if not query: