.. include:: hyperlinks.txt .. _customize viewport: Customize the Viewport ====================== The viewport is the main interface exposed to the user. .. figure:: images/fr200.png :align: center :width: 50% The viewport widget. The panel on the left is a fast navigation tool giving access to the database tables and to some actions. It is a list of of nodes containing leaves. An action is performed by clicking on a leaf. The panel on the right side display the results of the selected action. The typical actions are: * view the content of database table and modify its records; * view the content of an URL; * launch actions like reporting or wizards. Configure the viewport ---------------------- The viewport is an instance of the ``Dbui.viewport.Viewport`` which derives from the base class ``Ext.container.Viewport``. Its configuration parameters are described in the `Ext JS API`_ documentation and can be customized in the python model. The recommend practice is to do it in the file ``widgets_viewport.py``. To configure the viewport, instantiate the ``ViewportModifier`` and use the method ``configure``. Its keyword arguments corresponds to the configuration parameters of the ``Ext.container.Viewport`` class. There are no limitation on the number of keyword arguments which can be used:: viewportModifier = dbui.ViewportModifier() viewportModifier.configure(param1='right', param2=100) Te main step of the configuration is to add nodes and leaves. The how-to is presented in the next sections. Add a node ---------- The example shows how to create two node ``Tables`` and ``Reports`` and to add them to the viewport:: gridNode = dbui.Node(T('Tables')) reportNode = dbui.Node(T('Reports')) viewportModifier = dbui.ViewportModifier() viewportModifier.add_node(gridNode, reportNode) Add a leaf to display the content of a database table ----------------------------------------------------- The example shows how to add a leaf displaying the grid associated to the database table ``people``:: to_grid = lambda tablename: dbui.to_gridPanel(db[tablename]) gridNode = dbui.Node(T('Tables')) gridNode.add_child(T('people'), to_grid('people')) It is possible to add all database tables in one go:: to_grid = lambda tablename: dbui.to_gridPanel(db[tablename]) gridNode = dbui.Node(T('Tables')) gridNode.add_children(db.tables, func=to_grid) In the previous procedure, it is also possible to exclude some tables:: gridNode = dbui.Node(T('Tables')) gridNode.add_children(db.tables, func=to_grid, hidden=['mytable']) Add a leaf to display an URL ---------------------------- In your application, you have a controller ``help`` containing the actions ``about`` and ``documentation``. Each action return an HTML document. The example shows how to trigger these actions from a node entitled ``Help``:: loader = dict(autoLoad=True, renderer='html', scripts=False, url=URL('help', 'about')) aboutLeaf = dbui.Panel(loader=loader, plugins=['pPanelLoaderException'], autoScroll=True) loader = dict(autoLoad=True, renderer='html', scripts=True, url=URL('help', 'documentations')) docLeaf = dbui.Panel(loader=loader, plugins=['pPanelLoaderException'], autoScroll=True) helpNode = dbui.Node(T('Help')) helpNode.add_child(T('about'), aboutLeaf) helpNode.add_child(T('documentation'), docLeaf) Add a leaf to display a panel with a selector --------------------------------------------- A panel with a selector is a powerful widget. It contains a panel on the left side and a selector on the right side. The latter is mainly a form interfaced with the server. .. figure:: images/fr600.png :align: center :width: 50% A panel with a selector. The selector has two buttons *Go* and *Reset*. The parameters entered in the selector form are sent to a *controller/action* when the Go button is clicked. The results of the action is displayed in the left panel. Take the model with two tables ``countries`` and ``people``:: db.define_table("countries", Field("country", "string", notnull=True, unique=True), migrate="countries.table") db.define_table("people", Field("first_name", "string", notnull=True), Field("last_name", "string", notnull=True), Field("initials", "string", notnull=True), Field("birth_date", "date"), Field("id_countries", "reference countries", default=undef, label="Country"), Field("note", "text"), migrate="people.table") We want to select people by their by ``last_name``, by ``country``, by ``birth of date`` and by any combination of these three criteria. The first step is to set up a selector. The recommend practice is to do it in the model via the file ``vt_people_selector.py``. The selector will be instantiated via a table belonging to the virtual database named ``virtdb``:: virtdb = DAL(None) virtdb.define_table('people_selector', Field('last_name', 'string'), Field('id_countries', 'reference countries', label='Country'), Field('birth_date', 'date')) virtdb.people_selector.id_countries.requires = \ IS_IN_DB(db, 'countries.country') The second step is to implement the selection algorithm, for example, in the controller ``reports`` and the action ``list``:: from plugin_dbui import Selector def list(): selector = Selector(virtdb.people_selector) return str(selector) This minimal version return a string with a the value entered by the user. the last step is create a leaf in the viewport to launch the action:: listLeaf = dbui.to_panelWithUrlSelector(virtdb.people_selector, baseUrl=URL('reports', 'list')) reportNode = dbui.Node(T('Reports')) reportNode.add_child(T('lists'), listLeaf) The python ``Selector`` and its associated ``Dbui.panel.WithUrlSelector`` widget are a very powerful tool which can be used to build reports or to perform some actions on the database. It has several interesting keyword parameters described in the plugin_dbui API. Sort leaves in alphabetic order -------------------------------- Leaves, belonging to the same node, can be sort in alphabetic order:: reportNode = dbui.Node(T('Reports')) reportNode.sort_children() Add plugins to Viewport ----------------------- Javascript plugins have been designed to enhance the functionalities of the Viewport: * ``pViewportLogin`` activate the *Login Menu*. It is located on the right side of the top bar and exposes the following items: ==================== ============================================= item action ==================== ============================================= login myapplication/admin Change password myapplication/default/user/change_password Logout myapplication/default/user/logout ==================== ============================================= To activate plugins:: viewportModifier = dbui.ViewportModifier() viewportModifier.configure(plugins=['pViewportLogin']) Open a leaf at startup ---------------------- To open the leaf at startup and trigger its action:: viewportModifier = dbui.ViewportModifier() viewportModifier.default_node(T('node'), T('leaf')) This is useful to display the content of a table.