CuneiTable

จาก คูนิฟ็อกซ์ วิกิ

CuneiTable is designed specifically to enable in-line data entry. Design-wise, it is more limited than CuneiForm since design flexibility is not highly expected from table-rype objects. In essence, CuneiTable is a wrapper for the accompanying CuneiForm, whether that form be the in-line type or the full expansion type.

Define

Defining a CuneiTable is essentially declaring a CuneiForm with a few additional class variables. Below is an example of a very basic CuneiTable:

class AccCodeTable(CuneiTable):
    MASTER_colsizes = [10, 20, 50, 20]
    MASTER_colnames = ["StID", "Account Code", "Account Name", "Account Group"]
    MASTER_coltypes = ["int", "str", "str", "sel"]
    MASTER_choicecols = ["accgrp"]
    MASTER_choices = [[
                         ("1", "Asset"),
                         ("2", "Liability"),
                         ("3", "Equity"),
                         ("4", "Revenue"),
                         ("5", "Expense")
                     ]]
    MASTER_firstonly = ["stid"]
    class SubForm(FlaskForm, CuneiSubForm):
        stid = StringField("StID")
        code = StringField("Code", validators=[InputRequired("Required!")])
        name = StringField("Name", validators=[InputRequired("Required!")])
        accgrp = SelectField("Group", default=1)
        def validate_stid(self, stid):
            # Validation goes here

The subclass SubForm is defined like the stripped down version of CuneiForm. Only put fields and validation logics here. All other behaviours are controlled by the MASTER variables from the CuneiTable level.

NOTE THAT neither of the Submit-delete Field Set (submit, is_del, and del_submit) is declared in the SubForm. These fields are taken care of automatically during CuneiTable initiation.

The Holy Trinity of CuneiTable

The 3 MASTER variables listed below are required for all CuneiTable classes.

  • MASTER_colnames ([str,]): The list of column headers to appear on the page.
  • MASTER_coltypes ([str,]): The list of column value types. Available types include:
    • All types listed in the main article for CuneiForm.
    • 'str': Normal string value.
    • 'check': Value represented by a checkbox.
    • 'sel': Value with multiple choices. In other words, this is equivalent to a drop-list field in forms. In the same fashion, the displayed values for this type is not exactly the same as the values stored in the database. The raw value must pass through a map first before being displayed.
    • 'rad': Similar to 'sel', but this value type is represented by radio buttons in multiple sub-columns instead.
    • 'submit', 'del_submit': Submit button. (Not handled manually, they are handled automatically during initiation.)
  • MASTER_colsizes ([float/int,]): The list of relative column sizes. CuneiFox will calculate the display sizes automatically.

NOTE #1: The member order in each of these lists follow the definition order of fields in the SubForm. DO CHECK that all of these 3 lists and the SubForm fields share the same length.

NOTE #2: On the client-side, a radio field ('rad') is displayed as multiple sub-columns (one for each choice). Hence:

  • The display headers of sub-columns are not dictated by the corresponding value in MASTER_colnames, but by the values in MASTER_radios (Detailed in a sub-section below) instead.
  • The corresponding member in the MASTER_colsizes list is NOT merely one numerical value, BUT a list of numerical values instead.

Choices and Radios

Columns with limited choices of predesignated values should utilize 'choice' or 'radio' representation; especially when the stored values must be mapped to another set of more readable or localizable display values. Ideally:

  • Columns utilizing choice representation is typed 'sel' (MASTER_coltypes[i] = 'sel'), and the corresponding field in the SubForm is a SelectField.
  • Columns utilizing radio representation is typed 'rad' (MASTER_coltypes[i] = 'rad'), and the corresponding field in the SubForm is a RadioField.
MASTER_choicecols = [str choice_col0, str choice_col1, ...]
MASTER_choices    = [
                        [ (str col0_choice0, str col0_display0),
                          (str col0_choice1, str col0_display1),
                          ... ],
                        [ (str col1_choice0, str col1_display0),
                          (str col1_choice1, str col1_display1),
                          ... ],
                        ...
                    ]

MASTER_radiocols  = [str choice_col0, str choice_col1, ...]
MASTER_radios     = [
                        [ (str col0_choice0, str col0_display0),
                          (str col0_choice1, str col0_display1),
                          ... ],
                        [ (str col1_choice0, str col1_display0),
                          (str col1_choice1, str col1_display1),
                          ... ],
                        ...
                    ]

An example can be seen in the code at the top of the article.

NOTE #1: Take care that MASTER_choicecols and MASTER_choices have the same length. Similarly for MASTER_radiocols and MASTER_radios.

NOTE #2: The SelectField and RadioField defined in the SubForm DOES NOT include the choices. (Again, see example at the top.)

Search and Fill

Since the in-line form of a table is programmatically generated, the search-fill function cannot wait until the designing step like CuneiForm's does. The search-fill function of an in-line form is defined in this step via the variable MASTER_schfill.

MASTER_schfill = {
                     str search_col0: [str search_spec0, str fill_spec0],
                     str search_col1: [str search_spec1, str fill_spec1],
                     ...
                 }

# Example from Bank Account table
MASTER_schfill = {
                     "bank_code":    ["ModalBank:code",    "bank_stid:stid,bank_name:name,bank_branch:branch"],
                     "acccode_code": ["ModalAccCode:code", "acccode_name:name,acccode_stid:stid"]
                 }

NOTE: The formats of search_spec and fill_spec is similar to arguments search and fill in CuneiForm's render_blank macro.

Instant Calculation

Auto-numbering Function

Table with a Separate Form Modal

Sometimes, the entries have either too many columns or columns not suitable for display in the table format. In such cases, developers can use the full-form option. CuneiTable with an associated full-form is only defined with essential columns for a 'quick glance' view. The full form is shown in a pop-up modal for entry addition/edit.

A CuneiTable can be linked to a full-form via the class variable MASTER_fullform which takes the following format:

MASTER_fullform = [str module_code, str fullform_class_name, str fullform_modal_header_text, str modal_size]

# Example from Product table
MASTER_fullform = ['cunei_iv', 'ProductFullForm', 'Product Information', 'xl']
  • size dictates the modal size displayed on the client-side. It utilizes BootStrap 4's 'modal-<size>' classes. Available choices are 'sm', 'md' (corresponds to default modal size), 'lg', and 'xl'.

NOTES on full-form class and macro:

  • The CuneiForm class fullform_class_name must be found under module_code in the file cuneifox/<module_code>/forms.py or cuneifox/<module_code>/forms.pyc.
  • The definition of the full-form class DOES NOT include the Submit-delete Field Set
  • The Jinja2 macro for the full-form design must also be named fullform_class_name and must be found under module_code in the file cuneifox/<module_code>/template/<module_code>/form_macro.html.
  • Refer to the main CuneiForm article for more details on form definition and design. For information specific the full-form macros, refer to a dedicated sub-section below.

In-line Form with Expansion

Other Table Definition Variables

Initiate

Design & Pre-made Scripts

Full-form Macro

Notable Sub-routines