Adding search control

This commit is contained in:
2025-11-15 23:49:37 +01:00
parent 5ee671c6df
commit 09c4217cb6
4 changed files with 69 additions and 4 deletions

View File

@@ -0,0 +1,55 @@
import logging
from fasthtml.components import *
from myfasthtml.controls.BaseCommands import BaseCommands
from myfasthtml.controls.helpers import Ids, mk
from myfasthtml.core.commands import Command
from myfasthtml.core.instances import MultipleInstance
logger = logging.getLogger("Search")
class Commands(BaseCommands):
def search(self):
return (Command("Search", f"Search {self._owner.items_names}", self._owner.search).
htmx(trigger="keyup changed delay:300ms"))
class Search(MultipleInstance):
def __init__(self, session, items_names=None, template=None, _id=None):
super().__init__(session, Ids.Search, _id=_id)
self.items_names = items_names
self.items = []
self.filtered = []
self.template = template or Div
self.commands = Commands(self)
def set_items(self, items):
self.items = items
self.filtered = self.items
return self
def search(self, query):
logger.debug(f"search {query=}")
pass
def _mk_search_results(self):
return [self.template(item) for item in self.filtered]
def render(self):
return Div(
# mk.mk(Input(name="query", id=f"{self._id}-search", type="text", placeholder="Search...", cls="input input-xs"),
# command=self.commands.search()),
mk.mk(Input(name="query", id=f"{self._id}-search", type="search", placeholder="Search...", cls="input input-xs"),
),
Div(
*self._mk_search_results(),
id=f"{self._id}-results",
cls="mf-search-results",
),
id=f"{self._id}",
)
def __ft__(self):
return self.render()

View File

@@ -7,6 +7,7 @@ from fasthtml.common import Div, Span
from fasthtml.xtend import Script from fasthtml.xtend import Script
from myfasthtml.controls.BaseCommands import BaseCommands from myfasthtml.controls.BaseCommands import BaseCommands
from myfasthtml.controls.Search import Search
from myfasthtml.controls.VisNetwork import VisNetwork from myfasthtml.controls.VisNetwork import VisNetwork
from myfasthtml.controls.helpers import Ids, mk from myfasthtml.controls.helpers import Ids, mk
from myfasthtml.core.commands import Command from myfasthtml.core.commands import Command
@@ -96,6 +97,7 @@ class TabsManager(MultipleInstance):
self._state = TabsManagerState(self) self._state = TabsManagerState(self)
self.commands = Commands(self) self.commands = Commands(self)
self._boundaries = Boundaries() self._boundaries = Boundaries()
self._search = Search(self._session).set_items(self._get_tabs_labels())
logger.debug(f"TabsManager created with id: {self._id}") logger.debug(f"TabsManager created with id: {self._id}")
logger.debug(f" tabs : {self._get_ordered_tabs()}") logger.debug(f" tabs : {self._get_ordered_tabs()}")
logger.debug(f" active tab : {self._state.active_tab}") logger.debug(f" active tab : {self._state.active_tab}")
@@ -191,6 +193,7 @@ class TabsManager(MultipleInstance):
# finally, update the state # finally, update the state
self._state.update(state) self._state.update(state)
self._search.set_items(self._get_tabs_labels())
return tab_id return tab_id
@@ -248,6 +251,7 @@ class TabsManager(MultipleInstance):
# Update state # Update state
self._state.update(state) self._state.update(state)
self._search.set_items(self._get_tabs_labels())
return self return self
@@ -365,9 +369,7 @@ class TabsManager(MultipleInstance):
role="button", role="button",
cls="btn btn-xs"), cls="btn btn-xs"),
Div( Div(
Div("content"), self._search,
Div("content"),
Div("content"),
tabindex="-1", tabindex="-1",
cls="dropdown-content menu w-52 rounded-box bg-base-300 shadow-xl" cls="dropdown-content menu w-52 rounded-box bg-base-300 shadow-xl"
), ),
@@ -380,6 +382,9 @@ class TabsManager(MultipleInstance):
hx_swap_oob=f"beforeend:#{self._id}-content-wrapper", hx_swap_oob=f"beforeend:#{self._id}-content-wrapper",
) )
def _get_tabs_labels(self):
return [tab["label"] for tab in self._state.tabs.values()]
def update_boundaries(self): def update_boundaries(self):
return Script(f"updateBoundaries('{self._id}');") return Script(f"updateBoundaries('{self._id}');")

View File

@@ -11,6 +11,7 @@ class Ids:
Boundaries = "mf-boundaries" Boundaries = "mf-boundaries"
DbManager = "mf-dbmanager" DbManager = "mf-dbmanager"
Layout = "mf-layout" Layout = "mf-layout"
Search = "mf-search"
TabsManager = "mf-tabs-manager" TabsManager = "mf-tabs-manager"
UserProfile = "mf-user-profile" UserProfile = "mf-user-profile"
VisNetwork = "mf-vis-network" VisNetwork = "mf-vis-network"

View File

@@ -44,7 +44,7 @@ class BaseCommand:
def execute(self, client_response: dict = None): def execute(self, client_response: dict = None):
raise NotImplementedError raise NotImplementedError
def htmx(self, target="this", swap="innerHTML"): def htmx(self, target="this", swap="innerHTML", trigger=None):
if target is None: if target is None:
self._htmx_extra["hx-swap"] = "none" self._htmx_extra["hx-swap"] = "none"
elif target != "this": elif target != "this":
@@ -54,6 +54,10 @@ class BaseCommand:
self._htmx_extra["hx-swap"] = "none" self._htmx_extra["hx-swap"] = "none"
elif swap != "innerHTML": elif swap != "innerHTML":
self._htmx_extra["hx-swap"] = swap self._htmx_extra["hx-swap"] = swap
if trigger is not None:
self._htmx_extra["hx-trigger"] = trigger
return self return self
def bind_ft(self, ft): def bind_ft(self, ft):