コード例 #1
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
コード例 #2
0
ファイル: grid.py プロジェクト: yamandu/py4web
    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 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()
             ]
         )
コード例 #4
0
ファイル: grid.py プロジェクト: karbiv/py4web
    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")
コード例 #5
0
ファイル: datatables.py プロジェクト: DonaldMcC/py4gdms
    def table(self):
        _html = DIV()
        if self.create_url and self.create_url != '':
            _a = A('',
                   _href=self.create_url,
                   _class='button',
                   _style='margin-bottom: 1rem;')
            _span = SPAN(_class='icon is-small')
            _span.append(I(_class='fas fa-plus'))
            _a.append(_span)
            _a.append(SPAN('New'))
            _html.append(_a)

        _table = TABLE(_id='datatables_table',
                       _class='compact stripe hover cell-border order-column',
                       _style='padding-top: 1rem;')
        _thead = THEAD()
        _tr = TR()
        for field in self.fields:
            _tr.append(TH(field.label, _class='datatables-header'))
        _tr.append(
            TH('ACTIONS',
               _class='datatables-header has-text-centered',
               _style='color: black; width: 1px; white-space: nowrap;'))
        _thead.append(_tr)
        _table.append(_thead)
        _table.append(TBODY())

        _html.append(_table)
        return str(_html)
コード例 #6
0
ファイル: grid.py プロジェクト: Kkeller83/Elliot
    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])
                td.append(self.param.search_form.custom["wrapped_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
コード例 #7
0
    def render_table(self):
        _html = DIV(_class='field')
        _top_div = DIV(_style='padding-bottom: 1rem;')

        #  build the New button if needed
        if self.create and self.create != '':
            if isinstance(self.create, str):
                create_url = self.create
            else:
                create_url = create_url = URL(self.endpoint) + '/new/%s/0' % self.tablename

            _top_div.append(self.render_action_button(create_url, 'New', 'fa-plus', size='normal'))

        #  build the search form if provided
        if self.search_form:
            _top_div.append(self.render_search_form())

        _html.append(_top_div)

        _table = TABLE(_class='table is-bordered is-striped is-hoverable is-fullwidth')

        # build the header
        _table.append(self.render_table_header())

        #  include moment.js to present dates in the proper locale
        _html.append(XML('<script src="https://momentjs.com/downloads/moment.js"></script>'))

        #  build the rows
        _table.append(self.render_table_body())

        #  add the table to the html
        _html.append(_table)

        #  add the row counter information
        _row_count = DIV(_class='is-pulled-left')
        _row_count.append(
            P('Displaying rows %s thru %s of %s' % (self.page_start + 1 if self.number_of_pages > 1 else 1,
                                                    self.page_end if self.page_end < self.total_number_of_rows else
                                                    self.total_number_of_rows,
                                                    self.total_number_of_rows)))
        _html.append(_row_count)

        #  build the pager
        if self.number_of_pages > 1:
            _html.append(self.render_table_pager())

        if self.deletable:
            _html.append((XML("""
                <script type="text/javascript">
                $('.confirmation').on('click', function () {
                    return confirm($(this).attr('message') +' - Are you sure?');
                });
                </script>
            """)))

        return XML(_html)
コード例 #8
0
    def render_table(self):
        html = DIV(**self.param.grid_class_style.get("grid-wrapper"))
        grid_header = DIV(**self.param.grid_class_style.get("grid-header"))

        #  build the New button if needed
        if self.param.create and self.param.create != "":
            if isinstance(self.param.create, str):
                create_url = self.param.create
            else:
                create_url = self.endpoint + "/new"

            create_url += "?%s" % self.referrer

            grid_header.append(
                self.render_action_button(
                    create_url,
                    self.param.new_action_button_text,
                    "fa-plus",
                    icon_size="normal",
                    override_classes=self.param.grid_class_style.classes.get(
                        "grid-new-button", ""),
                    override_styles=self.param.grid_class_style.get(
                        "new_button"),
                ))

        #  build the search form if provided
        if self.param.search_form:
            grid_header.append(self.render_search_form())
        elif self.param.search_queries and len(self.param.search_queries) > 0:
            grid_header.append(self.render_default_form())

        html.append(grid_header)

        table = TABLE(**self.param.grid_class_style.get("grid-table"))

        # build the header
        table.append(self.render_table_header())

        #  build the rows
        table.append(self.render_table_body())

        #  add the table to the html
        html.append(
            DIV(table,
                **self.param.grid_class_style.get("grid-table-wrapper")))

        #  add the row counter information
        footer = DIV(**self.param.grid_class_style.get("grid-footer"))

        row_count = DIV(**self.param.grid_class_style.get("grid-info"))
        row_count.append("Displaying rows %s thru %s of %s" % (
            self.page_start + 1 if self.number_of_pages > 1 else 1,
            self.page_end if self.page_end < self.total_number_of_rows else
            self.total_number_of_rows,
            self.total_number_of_rows,
        )) if self.number_of_pages > 0 else row_count.append(
            "No rows to display")
        footer.append(row_count)

        #  build the pager
        if self.number_of_pages > 1:
            footer.append(self.render_table_pager())

        html.append(footer)
        return XML(html)
コード例 #9
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
コード例 #10
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
            ]),
        ),
    )