feat: Add Category autocomplete with config in settings
diff --git a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.json b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.json
index 76bf283..bfdfb0d 100644
--- a/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.json
+++ b/erpnext/e_commerce/doctype/e_commerce_settings/e_commerce_settings.json
@@ -46,7 +46,8 @@
   "shop_by_category_section",
   "slideshow",
   "item_search_settings_section",
-  "search_index_fields"
+  "search_index_fields",
+  "show_categories_in_search_autocomplete"
  ],
  "fields": [
   {
@@ -313,12 +314,18 @@
    "fieldname": "item_search_settings_section",
    "fieldtype": "Section Break",
    "label": "Item Search Settings"
+  },
+  {
+   "default": "1",
+   "fieldname": "show_categories_in_search_autocomplete",
+   "fieldtype": "Check",
+   "label": "Show Categories in Search Autocomplete"
   }
  ],
  "index_web_pages_for_search": 1,
  "issingle": 1,
  "links": [],
- "modified": "2021-04-23 13:30:50.286088",
+ "modified": "2021-04-26 09:50:40.581354",
  "modified_by": "Administrator",
  "module": "E-commerce",
  "name": "E Commerce Settings",
diff --git a/erpnext/e_commerce/website_item_indexing.py b/erpnext/e_commerce/website_item_indexing.py
index 0e48a2d..faf5760 100644
--- a/erpnext/e_commerce/website_item_indexing.py
+++ b/erpnext/e_commerce/website_item_indexing.py
@@ -17,6 +17,7 @@
 WEBSITE_ITEM_INDEX = 'website_items_index'
 WEBSITE_ITEM_KEY_PREFIX = 'website_item:'
 WEBSITE_ITEM_NAME_AUTOCOMPLETE = 'website_items_name_dict'
+WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE = 'website_items_category_dict'
 
 ALLOWED_INDEXABLE_FIELDS_SET = {
 	'item_code',
@@ -108,27 +109,36 @@
 	return True
 
 def define_autocomplete_dictionary():
-	print("Defining ac dict...")
-	# AC for name
-	# TODO: AC for category
+	"""Creates an autocomplete search dictionary for `name`.
+	   Also creats autocomplete dictionary for `categories` if 
+	   checked in E Commerce Settings"""
 
 	r = redis.Redis("localhost", 13000)
-	ac = AutoCompleter(WEBSITE_ITEM_NAME_AUTOCOMPLETE, port=13000)
+	name_ac = AutoCompleter(WEBSITE_ITEM_NAME_AUTOCOMPLETE, port=13000)
+	cat_ac = AutoCompleter(WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE, port=13000)
 
+	ac_categories = frappe.db.get_single_value(
+		'E Commerce Settings', 
+		'show_categories_in_search_autocomplete'
+	)
+	
+	# Delete both autocomplete dicts
 	try:
 		r.delete(WEBSITE_ITEM_NAME_AUTOCOMPLETE)
+		r.delete(WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE)
 	except:
 		return False
 	
 	items = frappe.get_all(
 		'Website Item', 
-		fields=['web_item_name'], 
+		fields=['web_item_name', 'item_group'], 
 		filters={"published": True}
 	)
 
 	for item in items:
-		print("adding suggestion: " + item.web_item_name)
-		ac.add_suggestions(Suggestion(item.web_item_name))
+		name_ac.add_suggestions(Suggestion(item.web_item_name))
+		if ac_categories and item.item_group:
+			cat_ac.add_suggestions(Suggestion(item.item_group))
 
 	return True
 
diff --git a/erpnext/templates/pages/product_search.py b/erpnext/templates/pages/product_search.py
index d935a7a..755dfec 100644
--- a/erpnext/templates/pages/product_search.py
+++ b/erpnext/templates/pages/product_search.py
@@ -9,7 +9,11 @@
 
 # For SEARCH -------
 from redisearch import AutoCompleter, Client, Query
-from erpnext.e_commerce.website_item_indexing import WEBSITE_ITEM_INDEX, WEBSITE_ITEM_NAME_AUTOCOMPLETE
+from erpnext.e_commerce.website_item_indexing import (
+	WEBSITE_ITEM_INDEX, 
+	WEBSITE_ITEM_NAME_AUTOCOMPLETE,
+	WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE
+)
 # -----------------
 
 no_cache = 1
@@ -83,3 +87,14 @@
 
 def convert_to_dict(redis_search_doc):
 	return redis_search_doc.__dict__
+
+@frappe.whitelist(allow_guest=True)
+def get_category_suggestions(query):
+	if not query:
+		# TODO: return top/recent searches
+		return []
+
+	ac = AutoCompleter(WEBSITE_ITEM_CATEGORY_AUTOCOMPLETE, port=13000)
+	suggestions = ac.get_suggestions(query, num=10)
+
+	return [s.string for s in suggestions]
\ No newline at end of file
diff --git a/erpnext/www/all-products/search.html b/erpnext/www/all-products/search.html
index ef74536..1c58e65 100644
--- a/erpnext/www/all-products/search.html
+++ b/erpnext/www/all-products/search.html
@@ -12,7 +12,19 @@
 
 {% block page_content %}
 <input type="text" name="query" id="search-box">
-<ul id="results">
 
-</ul>
+<!-- Search Results -->
+<h2>Products</h2>
+<ul id="results">Start typing...</ul>
+
+{% set show_categories = frappe.db.get_single_value('E Commerce Settings', 'show_categories_in_search_autocomplete') %}
+
+{% if show_categories %}
+<div id="categories">
+	<h2>Categories</h2>
+	<ul id="category-suggestions">
+	</ul>
+</div>
+{% endif %}
+
 {% endblock %}
\ No newline at end of file
diff --git a/erpnext/www/all-products/search.js b/erpnext/www/all-products/search.js
index 2080f35..aa47a4d 100644
--- a/erpnext/www/all-products/search.js
+++ b/erpnext/www/all-products/search.js
@@ -1,10 +1,10 @@
-console.log("search.js reloaded");
+console.log("search.js loaded");
 
-const search_box = document.getElementById("search-box");
+const searchBox = document.getElementById("search-box");
 const results = document.getElementById("results");
+const categoryList = document.getElementById("category-suggestions");
 
 function populateResults(data) {
-    console.log(data);
     html = ""
     for (let res of data.message) {
         html += `<li>
@@ -12,11 +12,24 @@
         <a href="/${res.route}">${res.web_item_name}</a>
         </li>`
     }
-    console.log(html);
     results.innerHTML = html;
 }
 
-search_box.addEventListener("input", (e) => {
+function populateCategoriesList(data) {
+    if (data.length === 0) {
+        categoryList.innerText = "No matches";
+        return;
+    }
+
+    html = ""
+    for (let category of data.message) {
+        html += `<li>${category}</li>`
+    }
+
+    categoryList.innerHTML = html;
+}
+
+searchBox.addEventListener("input", (e) => {
     frappe.call({
         method: "erpnext.templates.pages.product_search.search", 
         args: {
@@ -25,5 +38,19 @@
         callback: (data) => {
             populateResults(data);
         }
-    })
-});
\ No newline at end of file
+    });
+
+    // If there is a suggestion list node
+    if (categoryList) {
+        frappe.call({
+            method: "erpnext.templates.pages.product_search.get_category_suggestions",
+            args: {
+                query: e.target.value
+            },
+            callback: (data) => {
+                populateCategoriesList(data);
+            }
+        });
+    }
+});
+