Пример #1
0
    def render_field(self, row, field):
        """
        Render a field

        if only 1 table in the query, the no table name needed when getting the row value - however, if there
        are multiple tables in the query (self.use_tablename == True) then we need to use the tablename as well
        when accessing the value in the row object

        the row object sent in can take
        :param row:
        :param field:
        :return:
        """
        if self.use_tablename:
            field_value = row[field.tablename][field.name]
        else:
            field_value = row[field.name]
        if field.type == 'date':
            _td = TD(XML("<script>\ndocument.write("
                       "moment(\"%s\").format('L'));\n</script>" % field_value) \
                       if row and field and field_value else '',
                     _class='has-text-centered')
        elif field.type == 'boolean':
            #  True/False - only show on True, blank for False
            if row and field and field_value:
                _td = TD(_class='has-text-centered')
                _span = SPAN(_class='icon is-small')
                _span.append(I(_class='fas fa-check-circle'))
                _td.append(_span)
            else:
                _td = TD(XML('&nbsp;'))
        else:
            _td = TD(field_value if row and field and field_value else '')

        return _td
Пример #2
0
    def render_default_form(self):

        seach_type = safe_int(request.query.get("seach_type", 0), default=0)
        seach_string = request.query.get("seach_string")
        options = [
            OPTION(items[0], _value=k, _selected=(k == seach_type))
            for k, items in enumerate(self.param.search_queries)
        ]
        hidden_fields = [
            INPUT(_name=key, _value=request.query.get(key), _type="hidden")
            for key in request.query
            if not key in ("seach_type", "seach_string")
        ]
        form = FORM(*hidden_fields, **dict(_method="GET", _action=self.endpoint))
        select = SELECT(*options, **dict(_name="seach_type",))
        input = INPUT(_type="text", _name="seach_string", _value=seach_string,)
        submit = INPUT(_type="submit", _value="Search")
        clear_script = "document.querySelector('[name=seach_string]').value='';"
        clear = INPUT(_type="submit", _value="Clear", _onclick=clear_script)
        div = DIV(_id="grid-search", **self.param.grid_class_style.get("grid-search"))

        # we do not need classes for these elements
        tr = TR()
        if len(options) > 1:
            tr.append(TD(select))
        tr.append(TD(input))
        tr.append(TD(submit, clear))
        form.append(TABLE(tr))
        div.append(form)
        return div
Пример #3
0
def FormStyleDefault(table, vars, errors, readonly, deletable):

    form = FORM(TABLE(),_method='POST',_action='#',_enctype='multipart/form-data')
    for field in table:

        input_id = '%s_%s' % (field.tablename, field.name)
        value = field.formatter(vars.get(field.name))
        error = errors.get(field.name)
        field_class = field.type.split()[0].replace(':','-')

        if field.type == 'blob': # never display blobs (mistake?)
            continue
        elif readonly or field.type=='id':
            if not field.readable:
                continue
            else:
                control = field.represent and field.represent(value) or value or ''
        elif not field.writable:
            continue
        elif field.widget:
            control = field.widget(table, value)
        elif field.type == 'text':
            control = TEXTAREA(value or '', _id=input_id,_name=field.name)
        elif field.type == 'boolean':
            control = INPUT(_type='checkbox', _id=input_id, _name=field.name,
                            _value='ON', _checked = value)
        elif field.type == 'upload':
            control = DIV(INPUT(_type='file', _id=input_id, _name=field.name))
            if value:
                control.append(A('download', _href=donwload_url(value)))
                control.append(INPUT(_type='checkbox',_value='ON',
                                     _name='_delete_'+field.name))
                control.append('(check to remove)')
        elif hasattr(field.requires, 'options'):
            multiple = field.type.startswith('list:')
            value = value if isinstance(value, list) else [value]
            options = [OPTION(v,_value=k,_selected=(k in value))
                       for k,v in field.requires.options()]
            control = SELECT(*options, _id=input_id, _name=field.name,
                              _multiple=multiple)
        else:
            field_type = 'password' if field.type == 'password' else 'text'
            control = INPUT(_type=field_type, _id=input_id, _name=field.name,
                            _value=value, _class=field_class)

        form[0].append(TR(TD(LABEL(field.label,_for=input_id)),
                          TD(control,DIV(error,_class='error') if error else ''),
                          TD(field.comment or '')))

    td = TD(INPUT(_type='submit',_value='Submit'))
    if deletable:
        td.append(INPUT(_type='checkbox',_value='ON',_name='_delete'))
        td.append('(check to delete)')
    form[0].append(TR(TD(),td,TD()))
    return form
Пример #4
0
    def render_search_form(self):
        # TODO: Do we need this?
        div = DIV(_id="grid-search", **self.param.grid_class_style.get("grid-search"))
        div.append(self.param.search_form.custom["begin"])
        tr = TR(**self.param.grid_class_style.get("search_form_tr"))
        for field in self.param.search_form.table:
            td = TD(**self.param.grid_class_style.get("search_form_td"))
            if field.type == "boolean":
                sb = DIV(**self.param.grid_class_style.get("search_boolean"))
                sb.append(self.param.search_form.custom["widgets"][field.name])
                sb.append(field.label)
                td.append(sb)
            else:
                td.append(self.param.search_form.custom["widgets"][field.name])
            if (
                field.name in self.param.search_form.custom["errors"]
                and self.param.search_form.custom["errors"][field.name]
            ):
                td.append(
                    DIV(
                        self.param.search_form.custom["errors"][field.name],
                        _style="color:#ff0000",
                    )
                )
            tr.append(td)
        if self.param.search_button_text:
            tr.append(
                TD(
                    INPUT(
                        _class="button",
                        _type="submit",
                        _value=self.param.search_button_text,
                    ),
                    **self.param.grid_class_style.get("search_form_td"),
                )
            )
        else:
            tr.append(
                TD(
                    self.param.search_form.custom["submit"],
                    **self.param.grid_class_style.get("search_form_td"),
                )
            )
        div.append(TABLE(tr, **self.param.grid_class_style.get("search_form_table")))
        for hidden_widget in self.param.search_form.custom["hidden_widgets"].keys():
            div.append(self.param.search_form.custom["hidden_widgets"][hidden_widget])

        div.append(self.param.search_form.custom["end"])

        return div
Пример #5
0
 def dict_renderer(key, value, rec):
     if isinstance(value, dict):
         return TABLE(
             *[
                 TR(TH(k, ":"), TD(rec(key + "." + k, v)))
                 for k, v in value.items()
             ]
         )
Пример #6
0
    def render_field(self, row, field, field_index):
        """
        Render a field

        if only 1 table in the query, the no table name needed when getting the row value - however, if there
        are multiple tables in the query (self.use_tablename == True) then we need to use the tablename as well
        when accessing the value in the row object

        the row object sent in can take
        :param row:
        :param field:
        :return:
        """
        if isinstance(field, FieldVirtual):
            #  handle virtual fields in table display
            if self.use_tablename:
                field_value = field.f(row[field.tablename])
            else:
                field_value = field.f(row)
        elif self.use_tablename:
            field_value = row[field.tablename][field.name]
        else:
            field_value = row[field.name]
        key = "%s.%s" % (field.tablename, field.name)
        formatter = (
            self.formatters.get(key)
            or self.formatters_by_type.get(field.type)
            or self.formatters_by_type.get("default")
        )

        class_type = "grid-cell-type-%s" % str(field.type).split(":")[0].split("(")[0]
        class_col = " grid-col-%s" % key
        td = TD(
            formatter(field_value)
            if formatter.__code__.co_argcount == 1  # if formatter has only 1 argument
            else formatter(field_value, row),
            _class=(
                self.param.grid_class_style.classes.get("grid-td", "")
                + " "
                + class_type
                if class_type
                not in self.param.grid_class_style.classes.get(class_type, "").split(
                    " "
                )
                else ""
                + " "
                + self.param.grid_class_style.classes.get(class_type, "")
                + " "
                + class_col
            ).strip(),
            _style=(
                self.param.grid_class_style.styles.get(class_type)
                or self.param.grid_class_style.styles.get("grid-td")
            ),
        )

        return td
Пример #7
0
    def make(self):
        """makes the grid, must be called inside an action"""

        T, db, table, query = self.T, self.db, self.table, self.query
        # bypass rest API if it is a form
        id = safeint(request.query.get("id") or request.forms.get("id"))
        if id is not None:
            if (id == 0 and not self.create) or (id > 0 and not self.editable):
                raise HTTP(404)
            record = db(query)(table.id == id).select().first() if id else None
            form = Form(table,
                        record,
                        deletable=self.deletable,
                        **self.form_attributes)
            form.action = (request.url.split("?")[0] + "?" +
                           urllib.parse.urlencode(request.query))
            del request.query["id"]
            if form.deleted:
                message = T("Record deleted")
            elif form.accepted:
                message = T("Record created") if not id else T("Record Saved")
            else:
                return DIV(self.header(id), form, _class="py4web-grid")
        else:
            message = ""

        if self.denormalize:
            lookup = []
            for k, fs in self.denormalize.items():
                lookup.append("%s!:%s[%s]" % (k, k, ",".join(fs)))
            request.query["@lookup"] = ",".join(lookup)
        offset = safeint(request.query.get("@offset", 0))
        request.query["@count"] = "true"
        request.query["@limit"] = offset + self.limit
        id = None
        data = self.restapi("GET", self.table._tablename, None, request.query)
        items = data.get("items", [])
        count = data.get("count", 0)
        table = TABLE(_class="table")
        fields = (items[0].keys() if items else
                  [f.rsplit(".", 1)[0] for f in request.query if f[:1] != "@"])
        table.append(TR(*[TH(self.sortlink(key)) for key in fields]))
        table.append(TR(*[TH(self.filterlink(key)) for key in fields]))
        for item in items:
            table.append(
                TR(*[
                    TD(self.render(key, value)) for key, value in item.items()
                ]))
        header = self.header(id, message)
        footer = self.footer(count, offset, len(items))
        return DIV(header, table, footer, _class="py4web-grid")
Пример #8
0
    def render_field(self, row, field, field_index):
        """
        Render a field

        if only 1 table in the query, the no table name needed when getting the row value - however, if there
        are multiple tables in the query (self.use_tablename == True) then we need to use the tablename as well
        when accessing the value in the row object

        the row object sent in can take
        :param row:
        :param field:
        :return:
        """
        if self.use_tablename:
            field_value = row[field.tablename][field.name]
        else:
            field_value = row[field.name]
        key = "%s.%s" % (field.tablename, field.name)
        formatter = (
            self.formatters.get(key)
            or self.formatters_by_type.get(field.type)
            or self.formatters_by_type.get('default')
        )

        class_type = "grid-cell-type-%s" % str(field.type).split(":")[0]
        class_col = "grid-col-%s" % key
        td = TD(
            formatter(field_value),
            _class=(
                self.param.grid_class_style.classes.get("grid-td", "")
                + " "
                + class_type if class_type not in self.param.grid_class_style.classes.get(class_type,
                                                                                          "").split(" ") else ""
                + " "
                + self.param.grid_class_style.classes.get(class_type, "")
                + " "
                + class_col
            ).strip(),
            _style=(
                self.param.grid_class_style.styles.get(class_type)
                or self.param.grid_class_style.styles.get("grid-td")
            ),
        )

        return td
    def render_table_body(self):
        tbody = TBODY()
        for row in self.rows:
            #  find the row id - there may be nested tables....
            if self.use_tablename and self.tablename in row and "id" not in row:
                row_id = row[self.tablename]["id"]
            else:
                row_id = row["id"]
                self.use_tablename = False

            tr = TR(
                _role="row",
                _class=self.param.grid_class_style.classes.get("grid-tr"),
                _style=self.param.grid_class_style.styles.get("grid-tr"),
            )
            #  add all the fields to the row
            for index, field in enumerate(self.param.fields):
                if field.readable and (field.type != "id"
                                       or self.param.show_id):
                    tr.append(self.render_field(row, field, index))

            td = None

            #  add the action buttons
            if ((self.param.details and self.param.details != "")
                    or (self.param.editable and self.param.editable != "")
                    or (self.param.deletable and self.param.deletable != "")
                    or (self.param.post_action_buttons
                        or self.param.pre_action_buttons)):
                classes = (
                    self.param.grid_class_style.classes.get("grid-td", "") +
                    " " + self.param.grid_class_style.classes.get(
                        "grid-td-action-button")).strip()
                styles = (
                    self.param.grid_class_style.styles.get("grid-td", "") +
                    " " + self.param.grid_class_style.styles.get(
                        "grid-td-action-button")).strip()
                td = TD(_class=classes, _style=styles)
                if self.param.pre_action_buttons:
                    for btn in self.param.pre_action_buttons:
                        if btn.onclick:
                            btn.url = None
                        td.append(
                            self.render_action_button(
                                btn.url,
                                btn.text,
                                btn.icon,
                                _onclick=btn.onclick,
                                additional_classes=btn.additional_classes,
                                message=btn.message,
                                row_id=row_id if btn.append_id else None,
                                row=row,
                            ))
                if self.param.details and self.param.details != "":
                    if isinstance(self.param.details, str):
                        details_url = self.param.details
                    else:
                        details_url = self.endpoint + "/details"
                    details_url += "/%s?%s" % (row_id, self.referrer)
                    td.append(
                        self.render_action_button(
                            details_url,
                            self.param.details_action_button_text,
                            "fa-id-card",
                            name="grid-details-button",
                        ))

                if self.param.editable and self.param.editable != "":
                    if isinstance(self.param.editable, str):
                        edit_url = self.param.editable
                    else:
                        edit_url = self.endpoint + "/edit"
                    edit_url += "/%s?%s" % (row_id, self.referrer)
                    td.append(
                        self.render_action_button(
                            edit_url,
                            self.param.edit_action_button_text,
                            "fa-edit",
                            name="grid-edit-button",
                        ))

                if self.param.deletable and self.param.deletable != "":
                    if isinstance(self.param.deletable, str):
                        delete_url = self.param.deletable
                    else:
                        delete_url = self.endpoint + "/delete"
                    delete_url += "/%s?%s" % (row_id, self.referrer)
                    td.append(
                        self.render_action_button(
                            delete_url,
                            self.param.delete_action_button_text,
                            "fa-trash",
                            additional_classes="confirmation",
                            message="Delete record",
                            name="grid-delete-button",
                            _onclick=
                            "if(!confirm('sure you want to delete')) return false;",
                        ))
                if self.param.post_action_buttons:
                    for btn in self.param.post_action_buttons:
                        if btn.onclick:
                            btn.url = None
                        td.append(
                            self.render_action_button(
                                btn.url,
                                btn.text,
                                btn.icon,
                                _onclick=btn.onclick,
                                additional_classes=btn.additional_classes,
                                message=btn.message,
                                row_id=row_id if btn.append_id else None,
                                row=row,
                            ))
                tr.append(td)
            tbody.append(tr)

        return tbody
Пример #10
0
    def render_table_body(self):
        tbody = TBODY()
        for row in self.rows:
            #  find the row id - there may be nested tables....
            if self.use_tablename and self.tablename in row and "id" not in row:
                row_id = row[self.tablename]["id"]
            else:
                row_id = row["id"]
                self.use_tablename = False

            tr = TR(
                _role="row",
                _class=self.param.grid_class_style.classes.get("grid-tr"),
                _style=self.param.grid_class_style.styles.get("grid-tr"),
            )
            #  add all the fields to the row
            for index, field in enumerate(self.param.fields):
                if field.readable and (field.type != "id" or self.param.show_id):
                    tr.append(self.render_field(row, field, index))

            td = None

            #  add the action buttons
            if (
                (self.param.details and self.param.details != "")
                or (self.param.editable and self.param.editable != "")
                or (self.param.deletable and self.param.deletable != "")
                or (self.param.post_action_buttons or self.param.pre_action_buttons)
            ):
                classes = (
                    self.param.grid_class_style.classes.get("grid-td", "")
                    + " "
                    + self.param.grid_class_style.classes.get("grid-td-action-button")
                ).strip()
                styles = (
                    self.param.grid_class_style.styles.get("grid-td", "")
                    + " "
                    + self.param.grid_class_style.styles.get("grid-td-action-button")
                ).strip()
                td = TD(_class=classes, _style=styles)
                if self.param.pre_action_buttons:
                    for btn in self.param.pre_action_buttons:
                        if callable(btn):
                            # a button can be a callable, to indicate whether or not a button should
                            # be displayed. call the function with the row object
                            btn = btn(row)
                            if btn is None:
                                # if None was returned, no button is available for this row: ignore this value in the
                                # list
                                continue
                        if btn.onclick:
                            btn.url = None
                        td.append(
                            self.render_action_button(
                                btn.url,
                                btn.text,
                                btn.icon,
                                _onclick=btn.onclick,
                                additional_classes=btn.additional_classes,
                                message=btn.message,
                                row_id=row_id if btn.append_id else None,
                                row=row,
                            )
                        )
                if self.param.details and self.param.details != "":
                    if isinstance(self.param.details, str):
                        details_url = self.param.details
                    else:
                        details_url = self.endpoint + "/details"
                    details_url += "/%s?%s" % (row_id, self.referrer)
                    td.append(
                        self.render_action_button(
                            url=details_url,
                            button_text=self.param.details_action_button_text,
                            icon="fa-id-card",
                            name="grid-details-button",
                        )
                    )

                if self.param.editable and self.param.editable != "":
                    if isinstance(self.param.editable, str):
                        edit_url = self.param.editable
                    else:
                        edit_url = self.endpoint + "/edit"
                    edit_url += "/%s?%s" % (row_id, self.referrer)
                    td.append(
                        self.render_action_button(
                            url=edit_url,
                            button_text=self.param.edit_action_button_text,
                            icon="fa-edit",
                            name="grid-edit-button",
                        )
                    )

                if self.param.deletable and self.param.deletable != "":
                    if isinstance(self.param.deletable, str):
                        delete_url = self.param.deletable
                    else:
                        delete_url = self.endpoint + "/delete"
                    delete_url += "/%s?%s" % (row_id, self.referrer)
                    attrs = self.attributes_plugin.confirm(
                        message="Are you sure you want to delete?"
                    )
                    td.append(
                        self.render_action_button(
                            url=delete_url,
                            button_text=self.param.delete_action_button_text,
                            icon="fa-trash",
                            additional_classes="confirmation",
                            message="Delete record",
                            name="grid-delete-button",
                            **attrs,
                        )
                    )
                if self.param.post_action_buttons:
                    for btn in self.param.post_action_buttons:
                        if callable(btn):
                            # a button can be a callable, to indicate whether or not a button should
                            # be displayed. call the function with the row object
                            btn = btn(row)
                            if btn is None:
                                # if None was returned, no button is available for this row: ignore this value in the
                                # list
                                continue
                        if btn.onclick:
                            btn.url = None
                        td.append(
                            self.render_action_button(
                                btn.url,
                                btn.text,
                                btn.icon,
                                _onclick=btn.onclick,
                                additional_classes=btn.additional_classes,
                                message=btn.message,
                                row_id=row_id if btn.append_id else None,
                                row=row,
                            )
                        )
                tr.append(td)
            tbody.append(tr)

        return tbody
Пример #11
0
def FormStyleDefault(table, vars, errors, readonly, deletable):

    form = FORM(TABLE(),
                _method='POST',
                _action='#',
                _enctype='multipart/form-data')
    for field in table:

        input_id = '%s_%s' % (field.tablename, field.name)
        value = field.formatter(vars.get(field.name))
        error = errors.get(field.name)
        field_class = field.type.split()[0].replace(':', '-')

        if field.type == 'blob':  # never display blobs (mistake?)
            continue
        elif readonly or field.type == 'id':
            if not field.readable:
                continue
            else:
                control = field.represent and field.represent(
                    value) or value or ''
        elif not field.writable:
            continue
        elif field.widget:
            control = field.widget(table, value)
        elif field.type == 'text':
            control = TEXTAREA(value or '', _id=input_id, _name=field.name)
        elif field.type == 'boolean':
            control = INPUT(_type='checkbox',
                            _id=input_id,
                            _name=field.name,
                            _value='ON',
                            _checked=value)
        elif field.type == 'upload':
            control = DIV(INPUT(_type='file', _id=input_id, _name=field.name))
            if value:
                control.append(A('download', _href=donwload_url(value)))
                control.append(
                    INPUT(_type='checkbox',
                          _value='ON',
                          _name='_delete_' + field.name))
                control.append('(check to remove)')
        elif hasattr(field.requires, 'options'):
            multiple = field.type.startswith('list:')
            value = value if isinstance(value, list) else [value]
            options = [
                OPTION(v, _value=k, _selected=(k in value))
                for k, v in field.requires.options()
            ]
            control = SELECT(*options,
                             _id=input_id,
                             _name=field.name,
                             _multiple=multiple)
        else:
            field_type = 'password' if field.type == 'password' else 'text'
            control = INPUT(_type=field_type,
                            _id=input_id,
                            _name=field.name,
                            _value=value,
                            _class=field_class)

        form[0].append(
            TR(TD(LABEL(field.label, _for=input_id)),
               TD(control,
                  DIV(error, _class='error') if error else ''),
               TD(field.comment or '')))

    td = TD(INPUT(_type='submit', _value='Submit'))
    if deletable:
        td.append(INPUT(_type='checkbox', _value='ON', _name='_delete'))
        td.append('(check to delete)')
    form[0].append(TR(TD(), td, TD()))
    return form
Пример #12
0
    def render_table_body(self):
        _tbody = TBODY()
        for row in self.rows:
            #  find the row id - there may be nested tables....
            if self.use_tablename:
                row_id = row[self.tablename]['id']
            else:
                row_id = row['id']

            _tr = TR()
            #  add all the fields to the row
            for field in self.fields:
                if field.name not in [x.name for x in self.hidden_fields] and \
                        (field.name != 'id' or (field.name == 'id' and self.show_id)):
                    _tr.append(self.render_field(row, field))

            _td = None

            #  add the action buttons
            if (self.details and self.details != '') or \
                    (self.editable and self.editable != '') or \
                    (self.deletable and self.deletable != ''):
                _td = TD(_class='center', _style='text-align: center; white-space: nowrap;')
                if self.pre_action_buttons:
                    for btn in self.pre_action_buttons:
                        _td.append(self.render_action_button(btn.url,
                                                             btn.text,
                                                             btn.icon,
                                                             row_id=row_id if btn.append_id else None,
                                                             user_signature=self.user_signature
                                                                if btn.append_signature else None,
                                                             page=self.current_page_number
                                                                if btn.append_page else None))
                if self.details and self.details != '':
                    if isinstance(self.details, str):
                        details_url = self.details
                    else:
                        details_url = URL(self.endpoint) + '/details/%s' % self.tablename
                    details_url += '/%s?user_signature=%s&page=%s' % (row_id,
                                                                      self.user_signature,
                                                                      self.current_page_number)
                    _td.append(self.render_action_button(details_url, 'Details', 'fa-id-card'))

                if self.editable and self.editable != '':
                    if isinstance(self.editable, str):
                        edit_url = self.editable
                    else:
                        edit_url = URL(self.endpoint) + '/edit/%s' % self.tablename
                    _td.append(self.render_action_button(edit_url, 'Edit', 'fa-edit', row_id=row_id,
                                                         user_signature=self.user_signature,
                                                         page=self.current_page_number))

                if self.deletable and self.deletable != '':
                    if isinstance(self.deletable, str):
                        delete_url = self.deletable
                    else:
                        delete_url = URL(self.endpoint) + '/delete/%s' % self.tablename
                    delete_url += '/%s?user_signature=%s' % (row_id, self.user_signature)
                    _td.append(self.render_action_button(delete_url, 'Delete', 'fa-trash'))
                if self.post_action_buttons:
                    for btn in self.post_action_buttons:
                        _td.append(self.render_action_button(btn.url,
                                                             btn.text,
                                                             btn.icon,
                                                             row_id=row_id if btn.append_id else None,
                                                             user_signature=self.user_signature
                                                                if btn.append_signature else None,
                                                             page=self.current_page_number
                                                                if btn.append_page else None))
                _tr.append(_td)
            _tbody.append(_tr)

        return _tbody
Пример #13
0
    def render_search_form(self):
        _sf = DIV(_class='is-pulled-right', _style='padding-bottom: 1rem;')
        _sf.append(self.search_form.custom['begin'])
        _tr = TR()
        for field in self.search_form.table:
            _td = TD(_style='padding-right: .5rem;')
            if field.type == 'boolean':
                _td.append(self.search_form.custom['widgets'][field.name])
                _td.append(field.label)
            else:
                _td.append(self.search_form.custom['widgets'][field.name])
            if field.name in self.search_form.custom['errors'] and self.search_form.custom['errors'][
                field.name]:
                _td.append(DIV(self.search_form.custom['errors'][field.name], _style="color:#ff0000"))
            _tr.append(_td)
        if self.search_button:
            _tr.append(TD(INPUT(_class='button', _type='submit', _value=self.search_button)))
        else:
            _tr.append(TD(self.search_form.custom['submit']))
        _sf.append(TABLE(_tr))
        for hidden_widget in self.search_form.custom['hidden_widgets'].keys():
            _sf.append(self.search_form.custom['hidden_widgets'][hidden_widget])

        _sf.append(self.search_form.custom['end'])

        return _sf
Пример #14
0
def sql2table(
    tbl,
    db,
    tbl_query=None,
    order_by=None,
    rows_on_page=13,
    caller="index",
    csv=False,
    pagi=False,
    links=[],
    hlinks=[],
    fld_links={},
    fld_skip=[
        0,
    ],
    fld_length=15,
    page_d={},
    show_thead=True,
):
    def stop_button():
        return A('!',
                 _title='stop',
                 _role='button',
                 _style="background-color:lightgray;color:black;")

    if not tbl in db.tables:
        return f"unknown tbl: {tbl}"

    if tbl_query is None:
        tbl_query = db[tbl].id > 0

    if tbl_query and not isinstance(tbl_query, pydal.objects.Query):
        return f"bad tbl_query! tbl: {tbl}"

    if order_by is None:
        order_by = ~db[tbl].id

    try:
        pg = int(page_d.get("page", 1))
    except (ValueError, TypeError):
        pg = 1

    table_items = len(db(tbl_query).select())
    if rows_on_page > table_items:
        rows_on_page = table_items

    if table_items == 0:
        show_thead = False

    max_pages, rem = divmod(table_items, rows_on_page) if table_items else (0,
                                                                            0)
    if rem:
        max_pages += 1

    limitby = ((pg - 1) * rows_on_page, pg * rows_on_page)
    if not pagi:
        rows_on_page = table_items
        limitby = (0, table_items)

    rows = db(tbl_query).select(orderby=order_by, limitby=limitby)

    ij_start = -len(links)
    ff = [f for f in db[tbl].fields]
    hh = [db[tbl][f].label for f in ff]

    def h_func(x, jj):
        if jj < 0:
            if len(hlinks) >= -jj:
                return hlinks[len(hlinks) + jj]
            return "act"
        if jj in fld_skip:
            return ''

        if not x is None and isinstance(x, str) and len(x) > fld_length:
            x = x[:fld_length] + '...'

        return f"{x}"

    def r_func(x, ii, r, t, f_nm):
        if ii < 0:
            if len(links) >= -ii:
                return links[len(links) + ii](t, r.id)
            return "act"
        if ii in fld_skip:
            return ''
        if ii in fld_links:
            return fld_links[ii](t, x, r.id)
        if f_nm in fld_links:
            return fld_links[f_nm](t, x, r.id)

        if not x is None and isinstance(x, str) and len(x) > fld_length:
            x = x[:fld_length] + '~'

        return f"{x}"

    return DIV(
        SPAN("table_name: ", ),
        SPAN(f"{tbl}", _style="color:red"),
        SPAN(f"; {table_items} rows, {rows_on_page} rows_on_page, {pg} page "),
        DIV(  # <div>
            SPAN(
                A(
                    "prev",
                    _role="button",
                    _href=URL(
                        caller,
                        vars=dict(page=pg - 1 if pg > 1 else pg),
                    ),
                ) if pg > 1 else stop_button(),
                A(
                    "next",
                    _role="button",
                    _href=URL(
                        caller,
                        vars=dict(page=pg + 1 if pg < max_pages else pg),
                    ),
                ) if pg < max_pages else stop_button(),
            ) if pagi else "",
            SPAN(
                A(
                    "csv",
                    _role="button",
                    _title="table to csv file",
                    _href=URL(
                        "some_func",
                        vars=dict(t_=tbl, c="a"),
                    ),
                ),
                A(
                    "xls",
                    _role="button",
                    _title="table to xls file",
                    _href=URL(
                        "some_func",
                        vars=dict(t_=tbl, c="b"),
                    ),
                ),
            ) if csv else "",
        ),  # </div>
        TABLE(
            THEAD(
                TR(*[
                    TD(H6(h_func(hh[j], j))) for j in range(ij_start, len(hh))
                ])) if show_thead else "",
            TBODY(*[
                TR(*[
                    TD(r_func(row[ff[i]], i, row, tbl, ff[i]))
                    for i in range(ij_start, len(ff))
                ]) for row in rows
            ]),
        ),
    )