Refreshing Widgets using query_arguments¶
You can build a Widget
which gets refreshed
without reloading the entire page.
The howtos.ajaxbootstrap example has Nav
and a Div
. The
contents of the Div
changes each time an item is selected on the
Nav
without reloading the entire page.
Only HTMLElement
s can refresh. To let an HTMLElement
refresh, it
needs arguments and needs to call
enable_refresh()
in its __init__
method.
In the example, RefreshedPanel is given arguments in an
ExposedNames
namespace called
query_fields
. Each argument is defined by
assigning a callable for it to an attribute of the ExposedNames
. The
callable is called with an instance as argument and should return
a Field
describing that argument. The query_fields declared on
RefreshedPanel is merged with that on query_fields
at runtime:
query_fields = ExposedNames()
query_fields.selected = lambda i: IntegerField(required=False, default=1)
This makes the value of self.selected available in RefreshedPanel.__init__ to be
used when generating the RefreshedPanel (self.selected is set from
the URL or the default of the Field
):
class RefreshedPanel(Div):
def __init__(self, view, css_id):
super().__init__(view, css_id=css_id)
self.add_child(P(view, text='You selected link number %s' % self.selected))
self.enable_refresh()
A special “in-page” Bookmark
refers to a Widget
on the current
UrlBoundView
, but with different argument values.
Construct such a Bookmark
for a given value of selected by calling
for_widget()
with suitable
query_arguments. Before using the Bookmark
, call
on_view()
to bind it to the current
View
.
def get_bookmark(self, for_selected):
return Bookmark.for_widget('Select %s' % for_selected, query_arguments={'selected': for_selected}).on_view(self.view)
Use such bound Bookmark
s as usual:
class HomePanel(Div):
def __init__(self, view):
super().__init__(view)
panel = RefreshedPanel(view, 'my_refreshedpanel')
bookmarks = [panel.get_bookmark(1),
panel.get_bookmark(2),
panel.get_bookmark(3)]
self.add_child(H(view, 1, text='Refreshing widget'))
self.add_child(Nav(view).use_layout(TabLayout()).with_bookmarks(bookmarks))
self.add_child(panel)
Note
If a Widget
declares query_fields, it must have a unique css_id.