diff --git a/docs/chapter-14.rst b/docs/chapter-14.rst index 37b75a2fc..effe6bad3 100644 --- a/docs/chapter-14.rst +++ b/docs/chapter-14.rst @@ -181,7 +181,6 @@ The Grid object class Grid: def __init__( self, - path, query, search_form=None, search_queries=None, @@ -190,6 +189,7 @@ The Grid object show_id=False, orderby=None, left=None, + groupby=None, headings=None, create=True, details=True, @@ -208,55 +208,31 @@ The Grid object T=lambda text: text, ): -- path: the route of this request -- query: pydal query to be processed -- search_form: py4web FORM to be included as the search form. If - search_form is passed in then the developer is responsible for - applying the filter to the query passed in. This differs from - search_queries -- search_queries: list of query lists to use to build the search form. - Ignored if search_form is used -- columns: list of fields or columns to display on the list page, - see the :ref:`Custom columns` paragraph later. - If blank, the table will use all readable fields of the searched table -- show_id: show the record id field on list page - default = False -- orderby: pydal orderby field or list of fields -- left: if joining other tables, specify the pydal left expression here -- headings: list of headings to be used for list page - if not provided - use the field label -- create: URL to redirect to for creating records - set to True to - automatically generate the URL - set to False to not display the - button -- details: URL to redirect to for displaying records - set to True to - automatically generate the URL - set to False to not display the - button (*) -- editable: URL to redirect to for editing records - set to True to - automatically generate the URL - set to False to not display the - button (*) -- deletable: URL to redirect to for deleting records - set to True to - automatically generate the URL - set to False to not display the - button (*) -- validation: optional validation function to pass to create and edit forms -- pre_action_buttons: list of action_button instances to include before - the standard action buttons -- post_action_buttons: list of action_button instances to include after - the standard action buttons -- auto_process: Boolean - whether or not the grid should be processed - immediately. If False, developer must call grid.process() once all - params are setup -- rows_per_page: number of rows to display per page. Default 15 -- include_action_button_text: boolean telling the grid whether or not - you want text on action buttons within your grid -- search_button_text: text to appear on the submit button on your - search form -- formstyle: py4web Form formstyle used to style your form when - automatically building CRUD forms -- grid_class_style: GridClassStyle class used to override defaults for - styling your rendered grid. Allows you to specify classes or styles - to apply at certain points in the grid -- icon_style: default: IconStyleFontawsome. used to get icon css classes. - Other options: IconStyle, IconStyleBootstrapIcons -- T: optional pluralize object + - query: pydal query to be processed + - search_form: py4web FORM to be included as the search form. If search_form is passed in then the developer is responsible for applying the filter to the query passed in. This differs from search_queries. + - search_queries: list of query lists to use to build the search form. Ignored if search_form is used. + - columns: list of fields or columns to display on the list page, see the :ref:`Custom columns` paragraph later. If blank, the table will use all readable fields of the searched table. + - show_id: show the record id field on list page. Default is None, which enables automatic detection if any field is of type "id". + - orderby: pydal orderby field or list of fields. Controls the default sort order of the grid. + - left: if joining other tables, specify the pydal left expression here + - groupby: pydal groupby expression. Used to group results in the grid. + - headings: list of headings to be used for list page - if not provided use the field label + - create: Controls whether the grid allows record creation. Can be True (show button), False (hide button), a URL string, or a callable for custom logic. + - details: Controls whether the grid allows viewing record details. Can be True, False, a URL string, or a callable for custom logic. + - editable: Controls whether the grid allows editing records. Can be True, False, a URL string, or a callable for custom logic. + - deletable: Controls whether the grid allows deleting records. Can be True, False, a URL string, or a callable for custom logic. + - required_fields: list of fields that must be included in the grid's queries and forms. Used to ensure certain fields are always loaded. + - validation: optional validation function to pass to create and edit forms + - pre_action_buttons: list of action_button instances to include before the standard action buttons + - post_action_buttons: list of action_button instances to include after the standard action buttons + - auto_process: Boolean - whether or not the grid should be processed immediately. If False, developer must call grid.process() once all params are setup. + - rows_per_page: number of rows to display per page. Default 15 + - include_action_button_text: boolean telling the grid whether or not you want text on action buttons within your grid + - search_button_text: text to appear on the submit button on your search form + - formstyle: py4web Form formstyle used to style your form when automatically building CRUD forms + - grid_class_style: GridClassStyle class used to override defaults for styling your rendered grid. Allows you to specify classes or styles to apply at certain points in the grid + - icon_style: default: IconStyleFontawsome. used to get icon css classes. Other options: IconStyle, IconStyleBootstrapIcons + - T: optional pluralize object (*) The parameters ``details``, ``editable`` and ``deletable`` can also take a **callable** that will be passed the current row of the grid. This is useful because you can then turn a button on or off @@ -280,15 +256,11 @@ There are two ways to build a search form: - Provide a search_queries list - Build your own custom search form -If you provide a search_queries list to grid, it will: - - build a search form. If more than one search query in the list, it will also generate a dropdown to select which search field to search against -- gather filter values and filter the grid However, if this doesn’t give you enough flexibility you can provide -your own search form and handle all the filtering (building the queries) by yourself. CRUD settings @@ -307,7 +279,6 @@ Custom columns -------------- If the grid does not involve a join but displays results from a single table -you can specify a list of columns. Columns are highly customizable. .. code:: python @@ -348,7 +319,6 @@ Batman only, as explained before. Using templates --------------- -Use the following to render your grid or CRUD forms in your templates. Display the grid or a CRUD Form @@ -385,16 +355,58 @@ the grid or a form. Use the following to decide: [[pass]] +Grid 'path' parameter: Old vs New Usage +--------------------------------------- + +In previous versions of py4web, the `Grid` object required a `path` parameter in its constructor. This was used to help the grid parse the URL and determine the current action (such as select, edit, details, delete, etc.). + +**Old usage example:** + +.. code:: python + + grid = Grid( + path=request.path, + query=(db.person.id > 0), + # ...other parameters... + ) + +However, starting with py4web 1.20240501 and later, the `path` parameter is no longer needed or supported. The grid now automatically determines the current action and routing from the py4web request context and URL parameters. You should simply omit the `path` argument and use the constructor as follows: + +**New usage example:** + +.. code:: python + + grid = Grid( + query=(db.person.id > 0), + # ...other parameters... + ) + +This change makes the API simpler and less error-prone. All routing and action handling is now managed by py4web's @action decorator and the request context, so you do not need to manually pass the path. + +If you are updating older code, simply remove the `path` argument from your Grid instantiations. + +Grid mode parameter (path replacement) +------------------- + +The `Grid` object uses a `mode` variable, which is passed via the `request.query` object in py4web. This variable determines what kind of page or form the grid will render. Possible values for `mode` are: + +- `select`: Shows the main grid listing all records (default if not specified). +- `new`: Shows a form to create a new record. +- `details`: Shows a read-only form with details of a single record. +- `edit`: Shows a form to edit an existing record. +- `delete`: Shows a confirmation form to delete a record. + +The grid automatically parses the `mode` from the URL query parameters. For example, if you visit `/myapp/mygrid?mode=edit&id=5`, the grid will render the edit form for the record with ID 5. If no `mode` is specified, the grid defaults to `select` and shows the main table view. + +If you want to customize navigation or actions, you can generate links or buttons that set the desired `mode` and `id` in the query string. + Customizing style ------------------ +------------------- You can provide your own formstyle or grid classes and style to grid. -- formstyle is the same as a Form formstyle, used to style the CRUD forms. -- grid_class_style is a class that provides the classes and/or styles used for certain portions of the grid. -- icon_style is a class which provides the icon classes, for example for FontAwesome The default ``GridClassStyle`` - based on **no.css**, primarily uses styles to modify the layout of the grid. We've already seen that it's possible @@ -405,24 +417,19 @@ your choice. With icon_style, you can customize the icon font used. Currently, the following exist: -- ``IconStyleFontawsome`` is the current default (for backwards compatibility). You need to add `fontawesome `__ icon font CSS to use this. -- ``IconStyle`` which doesn't correspond to any font or icon set. It inserts simple css classes like ``icon-edit-button`` which you can write your own css for. -- ``IconStyleBootstrapIcons`` You need to add the icon font CSS from `Bootstrap Icons `__ to your html templates to use this. Custom Action Buttons ---------------------- +--------------- As with web2py, you can add additional buttons to each row in your grid. You do this by providing ``pre_action_buttons`` or ``post_action_buttons`` to the Grid **init** method. -- ``pre_action_buttons`` - list of action_button instances to include before the standard action buttons -- ``post_action_buttons`` - list of action_button instances to include after the standard action buttons You can build your own Action Button class to pass to pre/post action @@ -462,22 +469,10 @@ Sample Action Button Class self.ignore_attribute_plugin = ignore_attribute_plugin self.attrs = attrs -- url: the page to navigate to when the button is clicked -- text: text to display on the button -- icon: the icon corresponding to your icon-style to display before the text, for example "fa-calendar" for IconStyleFontawesome. -- additional_classes: a space-separated list of classes to include on the button element -- additional_styles: a string containing additional styles to add to the button -- override_classes: a space-separated list of classes to place on the control that will replace the default classes -- override_styles: a string containing the styles to be applied to the control -- message: confirmation message to display if ‘confirmation’ class is added to additional classes -- append_id: if True, add id_field_name=id_value to the url querystring for the button -- name: the name to apply to the control -- ignore_attribute_plugin: boolean - respect the attribute plugin specified on the grid or ignore it -- attrs: additional attributes to apply to the control After defining the custom GridActionButton class, you need to define your Action buttons: @@ -505,13 +500,6 @@ A recent improvement to py4web allows you to pass a **callable** instead of a Gr of standard and custom Actions. -Callable can be used with: - -- details -- editable -- deletable -- additional_classes -- additional_styles - override_classes - override_styles @@ -523,33 +511,33 @@ Example usage: @action("example") def example(): - pre_action_buttons = [ - lambda row: GridActionButton( - URL("test", row.id), - text="Click me", - icon=IconStyleFontawsome.add_button, # same as "fa-plus" - additional_classes=row.id, - additional_styles=["height: 10px" if row.bar else None], - ) - ] - - post_action_buttons = [ - lambda row: GridActionButton( - URL("test", row.id), - text="Click me!!!", - icon="fa-plus", - additional_classes=row.id, - additional_styles=["height: 10px" if row.bar else None], - ) - ] - - grid = Grid( - query=db.foo, - pre_action_buttons=pre_action_buttons, - post_action_buttons=post_action_buttons, - ) - - return dict(grid=grid.render()) + pre_action_buttons = [ + lambda row: GridActionButton( + URL("test", row.id), + text="Click me", + icon=IconStyleFontawsome.add_button, # same as "fa-plus" + additional_classes=row.id, + additional_styles=["height: 10px" if row.bar else None], + ) + ] + + post_action_buttons = [ + lambda row: GridActionButton( + URL("test", row.id), + text="Click me!!!", + icon="fa-plus", + additional_classes=row.id, + additional_styles=["height: 10px" if row.bar else None], + ) + ] + + grid = Grid( + query=db.foo, + pre_action_buttons=pre_action_buttons, + post_action_buttons=post_action_buttons, + ) + + return dict(grid=grid.render()) Reference Fields @@ -598,7 +586,6 @@ This method allows you to sort and filter, but doesn’t allow you to combine fields to be displayed together as the filter_out method would You need to determine which method is best for your use case -understanding the different grids in the same application may need to behave differently.