Adding search control
This commit is contained in:
55
src/myfasthtml/controls/Search.py
Normal file
55
src/myfasthtml/controls/Search.py
Normal 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()
|
||||||
@@ -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}');")
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user