Browse Source

[feat] search: shift/ctrl click a category to select multiple categories

Bnyro 5 months ago
parent
commit
6a9b97cad2

+ 39 - 14
searx/static/themes/simple/src/js/main/search.js

@@ -166,21 +166,46 @@
       searxng.on(d.getElementById('language'), 'change', submitIfQuery);
       searxng.on(d.getElementById('language'), 'change', submitIfQuery);
     }
     }
 
 
-    // most common browsers at the time of writing this support :has, except for Firefox
-    // can be removed when Firefox / Firefox ESL starts supporting it as well
-    try {
-      // this fails when the browser does not support :has
-      d.querySelector("html:has(body)");
-    } catch (_) {
-      // manually deselect the old selection when a new category is selected
-      for (let button of d.querySelectorAll("button.category_button")) {
-        searxng.on(button, 'click', () => {
-          const selected = d.querySelector("button.category_button.selected");
-          console.log(selected);
-          selected.classList.remove("selected");
-        })
-      }
+    // remove CSS class that's only needed when the browser supports no JavaScript
+    const categoriesContainer = d.querySelector("#categories_container");
+    if (categoriesContainer) {
+      categoriesContainer.classList.remove("nojs");
+    }
+
+    const categoryButtons = d.querySelectorAll("button.category_button");
+    for (let button of categoryButtons) {
+      searxng.on(button, 'click', (event) => {
+        if (event.shiftKey) {
+          event.preventDefault();
+          button.classList.toggle("selected");
+          return;
+        }
+
+        // manually deselect the old selection when a new category is selected
+        const selectedCategories = d.querySelectorAll("button.category_button.selected");
+        for (let categoryButton of selectedCategories) {
+          categoryButton.classList.remove("selected");
+        }
+        button.classList.add("selected");
+      })
     }
     }
+
+    // override form submit action to update the actually selected categories
+    const form = d.querySelector("#search");
+    searxng.on(form, 'submit', (event) => {
+      event.preventDefault();
+      const categoryValuesInput = d.querySelector("#selected-categories");
+      if (categoryValuesInput) {
+        let categoryValues = [];
+        for (let categoryButton of categoryButtons) {
+          if (categoryButton.classList.contains("selected")) {
+            categoryValues.push(categoryButton.name.replace("category_", ""));
+          }
+        }
+        categoryValuesInput.value = categoryValues.join(",");
+      }
+      form.submit();
+    });
   });
   });
 
 
 })(window, document, window.searxng);
 })(window, document, window.searxng);

+ 12 - 5
searx/static/themes/simple/src/less/search.less

@@ -77,16 +77,23 @@ button.category_button {
   }
   }
 
 
   &.selected,
   &.selected,
-  &:active,
-  &:focus-within {
+  &:active {
     color: var(--color-categories-item-selected-font);
     color: var(--color-categories-item-selected-font);
     border-bottom: 2px solid var(--color-categories-item-border-selected);
     border-bottom: 2px solid var(--color-categories-item-border-selected);
   }
   }
 }
 }
 
 
-#categories_container:has(button.category_button:focus-within) button.category_button.selected {
-  color: var(--color-base-font);
-  border-bottom: none;
+// only used when JavaScript is disabled
+.no-js #categories_container:has(button.category_button:focus-within) button.category_button {
+  &.selected {
+    color: var(--color-base-font);
+    border-bottom: none;
+  }
+
+  &:focus-within {
+    color: var(--color-categories-item-selected-font);
+    border-bottom: 2px solid var(--color-categories-item-border-selected);
+  }
 }
 }
 
 
 #search_logo {
 #search_logo {

+ 1 - 0
searx/templates/simple/categories.html

@@ -31,6 +31,7 @@
                     <div class="category_name">{{- _(category) -}}</div>{{- '' -}}
                     <div class="category_name">{{- _(category) -}}</div>{{- '' -}}
                 </button>{{- '' -}}
                 </button>{{- '' -}}
             {%- endfor -%}
             {%- endfor -%}
+            <input name="categories" id="selected-categories" type="hidden" />
             {{- '\n' -}}
             {{- '\n' -}}
         {%- endif -%}
         {%- endif -%}
     </div>{{- '' -}}
     </div>{{- '' -}}