Exemplo n.º 1
0
    def render_action_button(self,
                             url,
                             button_text,
                             icon,
                             size='small',
                             row_id=None,
                             user_signature=None,
                             page=None):
        separator = '?'
        if row_id:
            url += '/%s' % (row_id)
        if user_signature:
            url += '%suser_signature=%s' % (separator, user_signature)
            separator = '&'
        if page:
            url += '%spage=%s' % (separator, page)

        if self.include_action_button_text:
            _a = A(_href=url, _class='button is-%s' % size, _title=button_text)
            _span = SPAN(_class='icon is-%s' % size)
            _span.append(I(_class='fas %s' % icon))
            _a.append(_span)
            _a.append(SPAN(button_text))
        else:
            _a = A(I(_class='fas %s' % icon),
                   _href=url,
                   _class='button is-%s' % size,
                   _title=button_text)

        return _a
Exemplo n.º 2
0
    def script(self):
        js = (
            '<script type="text/javascript">'
            '    $(document).ready(function() {'
            '        $(\'#datatables_table\').DataTable( {'
            '            dom: "lfrtip", '
            '            processing: true, '
            '            serverSide: true, '
            '            lengthMenu: [  [10, 15, 20, -1], [10, 15, 20, \'All\']  ], '
            '            pageLength: %s, '
            '            pagingType: "numbers", '
            '            ajax: "%s", '
            '            columns: [' % (self.page_length, self.data_url))
        #  add the field values
        for field in self.fields:
            js += (
                '{'
                '    "data": "%s", '
                '    "name": "%s", '
                '    "visible": %s, '
                '},' %
                (field.name, field.name, 'true' if field.visible else 'false'))
        #  add the row buttons
        js += (
            '{'
            '    data: null,'
            '    render: function ( data, type, row ) {'
            '      var edit_url=\'%s\'; '
            '      edit_url = edit_url.replace("record_id", row.DT_RowId); '
            '      var delete_url=\'%s\'; '
            '      delete_url = delete_url.replace("record_id", row.DT_RowId); '
            '      return edit_url + "&nbsp;" + delete_url '
            '    }, '
            '    orderable: false, '
            '}' % (A(I(_class='fas fa-edit'),
                     _href=self.edit_url if self.edit_url else '#',
                     _class='button is-small'),
                   A(I(_class='fas fa-trash'),
                     _href=self.delete_url if self.delete_url else '#',
                     _class='button is-small',
                     _message='Delete Record')))
        js += '], columnDefs: ['
        for index, field in enumerate(self.fields):
            if not field.visible:
                js += '{"visible": false, "targets": %s},' % index
        js += '{className: "has-text-centered", "targets": %s}' % (index + 1)

        js += ('],' 'order: ')
        for sort in self.sort_sequence:
            js += '[ %s, "%s" ]' % (sort[0], sort[1])

        js += (','
               '        stateSave: true, '
               '        select: true, '
               '    });'
               '    $(".dataTables_filter input").focus().select();'
               '});'
               '</script>')

        return str(js)
Exemplo n.º 3
0
    def render_table_header(self):

        up = I(**self.param.grid_class_style.get("grid-sorter-icon-up"))
        dw = I(**self.param.grid_class_style.get("grid-sorter-icon-down"))
        columns = []
        sort_order = request.query.get("orderby", "")

        for index, field in enumerate(self.param.fields):
            if field.readable and (field.type != "id" or self.param.show_id):
                key = "%s.%s" % (field.tablename, field.name)
                heading = (
                    self.param.headings[index]
                    if index < len(self.param.headings)
                    else field.label
                )
                heading = title(heading)
                #  add the sort order query parm
                sort_query_parms = dict(self.query_parms)

                attrs = {}
                if isinstance(field, FieldVirtual):
                    col = DIV(heading)
                elif key == sort_order:
                    sort_query_parms["orderby"] = "~" + key
                    url = URL(self.endpoint, vars=sort_query_parms)
                    attrs = self.attributes_plugin.link(url=url)
                    col = A(heading, up, **attrs)
                else:
                    sort_query_parms["orderby"] = key
                    url = URL(self.endpoint, vars=sort_query_parms)
                    attrs = self.attributes_plugin.link(url=url)
                    col = A(heading, dw if "~" + key == sort_order else "", **attrs)
                columns.append((key, col))

        thead = THEAD(_class=self.param.grid_class_style.classes.get("grid-thead", ""))
        for key, col in columns:
            col_class = " grid-col-%s" % key
            thead.append(
                TH(
                    col,
                    _class=self.param.grid_class_style.classes.get("grid-th", "")
                    + col_class,
                    _style=self.param.grid_class_style.styles.get("grid-th"),
                )
            )

        if (
            self.param.details
            or self.param.editable
            or self.param.deletable
            or self.param.pre_action_buttons
            or self.param.post_action_buttons
        ):
            thead.append(
                TH("", **self.param.grid_class_style.get("grid-th-action-button"))
            )

        return thead
Exemplo n.º 4
0
 def api(self, id=None):
     """Returns data according to the API request."""
     # Builds the header.
     header = dict(
         is_header=True,
         cells=[
             dict(text="First Name", sortable=True),
             dict(text="Last Name", sortable=True),
             dict(text="Arrival Time", sortable=True),
             dict(text="", sortable=False),  # Icons
         ],
     )
     # Gets the request parameters, and copies the sort order in the header.
     req = self._get_request_params(header)
     timezone = request.query.get("timezone")
     q = request.query.get("q", "")  # Query string
     # Forms the query.
     if q:
         query = db(
             db.vue_form_table.first_name.contains(q)
             | db.vue_form_table.last_name.contains(q))
     else:
         query = db.vue_form_table
     # Forms the select.
     rows = db(query).select(**req.search_args)
     # Builds the result rows.
     result_rows = []
     for r in rows:
         cells = []
         cells.append(dict(text=r.first_name))
         cells.append(dict(text=r.last_name))
         cells.append(dict(text=r.arrival_time.isoformat(), type="date"))
         cells.append(
             dict(raw_html=SPAN(
                 A(
                     I(_class="fa fa-eye"),
                     _href=URL("vue_view_form", r.id, signer=self.signer),
                 ),
                 " ",
                 A(
                     I(_class="fa fa-pen"),
                     _href=URL("vue_edit_form", r.id, signer=self.signer),
                 ),
             ).xml()))
         result_rows.append(
             dict(cells=cells,
                  delete=URL("delete_row", r.id, signer=self.signer)))
     has_more, result_rows = self._has_more(result_rows)
     return dict(
         page=req.page,
         has_search=True,
         has_delete=True,
         search_placeholder="",
         has_more=has_more,
         rows=[header] + result_rows,
     )
Exemplo n.º 5
0
def example_html_grid(path=None):
    #  controllers and used for all grids in the app
    grid_param = dict(rows_per_page=5,
                      include_action_button_text=True,
                      search_button_text="Filter",
                      formstyle=FormStyleDefault,
                      grid_class_style=GridClassStyle)

    search_queries = [
        ['By Name', lambda value: db.thing.name.contains(value)],
        ['By Color', lambda value: db.thing.color == value],
        [
            'By Name or Color', lambda value: db.thing.name.contains(value) |
            (db.thing.color == value)
        ],
    ]

    query = db.thing.id > 0
    orderby = [db.thing.name]

    grid = Grid(path,
                query,
                fields=[field for field in db.thing if field.readable],
                search_queries=search_queries,
                orderby=orderby,
                **grid_param)

    grid.formatters['thing.color'] = lambda color: I(_class="fa fa-circle",
                                                     _style="color:" + color)

    return dict(grid=grid)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
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
Exemplo n.º 8
0
    def render_action_button(
        self,
        url,
        button_text,
        icon,
        icon_size="small",
        additional_classes=None,
        additional_styles=None,
        override_classes=None,
        override_styles=None,
        message=None,
        onclick=None,
        row_id=None,
        name="grid-button",
        row=None,
        **attr,
    ):
        separator = "?"
        if row_id:
            url += "/%s" % row_id

        classes = self.param.grid_class_style.classes.get(name, "")
        styles = self.param.grid_class_style.styles.get(name, "")

        def join(items):
            return (
                " ".join(items) if isinstance(items, (list, tuple)) else " %s" % items
            )

        if override_classes:
            classes = join(override_classes)
        elif additional_classes:
            classes += join(additional_classes)
        if override_styles:
            styles = join(override_styles)
        elif additional_styles:
            styles += join(additional_styles)

        if callable(url):
            url = url(row)

        link = A(
            I(_class="fa %s" % icon),
            _href=url,
            _role="button",
            _class=classes,
            _message=message,
            _title=button_text,
            _style=styles,
            **attr,
        )
        if self.param.include_action_button_text:
            link.append(
                XML(
                    '<span class="grid-action-button-text">&nbsp;%s</span>'
                    % button_text
                )
            )

        return link
Exemplo n.º 9
0
    def render_table_header(self):
        _thead = THEAD()
        for index, field in enumerate(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)):
                try:
                    heading = self.headings[index]
                except:
                    if field.table == self.tablename:
                        heading = field.label
                    else:
                        heading = str(field.table)
                #  add the sort order query parm
                sort_query_parms = dict(self.query_parms)
                sort_query_parms['sort'] = index
                current_sort_dir = 'asc'

                if '%s.%s' % (field.tablename, field.name) in self.storage_values['orderby']:
                    sort_query_parms['sort'] = -index
                    _h = A(heading.replace('_', ' ').upper(),
                           _href=URL(self.endpoint, vars=sort_query_parms))
                    _h.append(SPAN(I(_class='fas fa-sort-up'), _class='is-pulled-right'))
                elif '~%s.%s' % (field.tablename, field.name) in self.storage_values['orderby']:
                    _h = A(heading.replace('_', ' ').upper(),
                           _href=URL(self.endpoint, vars=sort_query_parms))
                    _h.append(SPAN(I(_class='fas fa-sort-down'), _class='is-pulled-right'))
                else:
                    _h = A(heading.replace('_', ' ').upper(),
                           _href=URL(self.endpoint, vars=sort_query_parms))

                if 'sort_dir' in sort_query_parms:
                    current_sort_dir = sort_query_parms['sort_dir']
                    del sort_query_parms['sort_dir']
                if index == int(request.query.get('sort', 0)) and current_sort_dir == 'asc':
                    sort_query_parms['sort_dir'] = 'desc'

                _th = TH()
                _th.append(_h)

                _thead.append(_th)

        if self.editable or self.deletable:
            _thead.append(TH('ACTIONS', _style='text-align: center; width: 1px; white-space: nowrap;'))

        return _thead
Exemplo n.º 10
0
    def render_table_header(self):

        up = I(**self.param.grid_class_style.get("grid-sorter-icon-up"))
        dw = I(**self.param.grid_class_style.get("grid-sorter-icon-down"))
        columns = []
        sort_order = request.query.get("orderby", "")

        for index, field in enumerate(self.param.fields):
            if field.readable and (field.type != "id" or self.param.show_id):
                key = "%s.%s" % (field.tablename, field.name)
                heading = (self.param.headings[index] if
                           index < len(self.param.headings) else field.label)
                heading = title(heading)
                #  add the sort order query parm
                sort_query_parms = dict(self.query_parms)

                if key == sort_order:
                    sort_query_parms["orderby"] = "~" + key
                    href = URL(self.endpoint, vars=sort_query_parms)
                    col = A(heading, up, _href=href)
                else:
                    sort_query_parms["orderby"] = key
                    href = URL(self.endpoint, vars=sort_query_parms)
                    col = A(heading,
                            dw if "~" + key == sort_order else "",
                            _href=href)
                columns.append((key, col))

        thead = THEAD()
        for key, col in columns:
            col_class = "grid-col-%s" % key
            thead.append(
                TH(
                    col,
                    _class=self.param.grid_class_style.classes.get(
                        "grid-th", "") + col_class,
                    _style=self.param.grid_class_style.styles.get("grid-th"),
                ))

        if self.param.details or self.param.editable or self.param.deletable:
            thead.append(
                TH("",
                   **self.param.grid_class_style.get('grid-th-action-button')))

        return thead
Exemplo n.º 11
0
def employees(path=None):
    queries = [(db.employee.id > 0)]
    orderby = [db.employee.last_name, db.employee.first_name]

    search_queries = [['Search by Company', lambda val: db.company.id == val,
                       db.employee.company.requires],
                      ['Search by Department', lambda val: db.department.id == val,
                       db.employee.department.requires],
                      ['Search by Name', lambda val: "first_name || ' ' || last_Name LIKE '%%%s%%'" % val]]
    search = GridSearch(search_queries, queries)

    fields = [db.employee.id,
              db.employee.first_name,
              db.employee.last_name,
              db.company.name,
              db.department.name,
              db.employee.hired,
              db.employee.supervisor,
              db.employee.active]

    grid = Grid(path,
                search.query,
                search_form=search.search_form,
                fields=fields,
                left=[db.company.on(db.employee.company == db.company.id),
                      db.department.on(db.employee.department == db.department.id)],
                orderby=orderby,
                create=True,
                details=True,
                editable=True,
                deletable=True,
                **GRID_DEFAULTS)

    grid.formatters_by_type['boolean'] = lambda value: SPAN(I(_class='fas fa-check-circle')) if value else ""
    grid.formatters_by_type['date'] =lambda value: XML(
        '<script>document.write((new Date(%s,%s,%s)).toLocaleDateString({month: "2-digit", day: "2-digit", year: "numeric"}).split(",")[0])</script>'
        % (value.year, value.month, value.day,)
    )
    return dict(grid=grid)
Exemplo n.º 12
0
def example_html_grid(path=None):
    #  controllers and used for all grids in the app
    grid_param = dict(
        rows_per_page=5,
        include_action_button_text=True,
        search_button_text="Filter",
        formstyle=FormStyleDefault,
        grid_class_style=GridClassStyle,
    )

    search_queries = [
        ["By Name", lambda value: db.thing.name.contains(value)],
        ["By Color", lambda value: db.thing.color == value],
        [
            "By Name or Color",
            lambda value: db.thing.name.contains(value) |
            (db.thing.color == value),
        ],
    ]

    query = db.thing.id > 0
    orderby = [db.thing.name]
    columns = [field for field in db.thing if field.readable]
    columns.insert(0, Column("Custom", lambda row: A("click me")))
    grid = Grid(path,
                query,
                columns=columns,
                search_queries=search_queries,
                orderby=orderby,
                show_id=False,
                T=T,
                **grid_param)

    grid.formatters["thing.color"] = lambda color: I(_class="fa fa-circle",
                                                     _style="color:" + color)

    return dict(grid=grid)