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 HTMLElements 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 Bookmarks 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.
