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 exposed method named query_fields(). Each argument is defined by assigning a Field to an attribute of fields:

    @exposed
    def query_fields(self, fields):
        fields.selected = 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.