コード例 #1
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)
コード例 #2
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
コード例 #3
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
コード例 #4
0
ファイル: grid.py プロジェクト: Kkeller83/Elliot
 def render_table_pager(self):
     pager = DIV(**self.param.grid_class_style.get("grid-pagination"))
     previous_page_number = None
     for page_number in self.iter_pages(
         self.current_page_number, self.number_of_pages
     ):
         pager_query_parms = dict(self.query_parms)
         pager_query_parms["page"] = page_number
         # if there is a gat add a spacer
         if previous_page_number and page_number - previous_page_number > 1:
             pager.append(SPAN("...", _style="margin:0 10px;"))
         is_current = self.current_page_number == page_number
         page_name = (
             "grid-pagination-button-current"
             if is_current
             else "grid-pagination-button"
         )
         attrs = self.attributes_plugin.link(
             url=URL(self.endpoint, vars=pager_query_parms)
         )
         pager.append(
             A(
                 page_number,
                 **self.param.grid_class_style.get(page_name),
                 _role="button",
                 **attrs,
             )
         )
         previous_page_number = page_number
     return pager
コード例 #5
0
 def render_table_pager(self):
     pager = DIV(**self.param.grid_class_style.get("grid-pagination"))
     previous_page_number = None
     for page_number in self.iter_pages(self.current_page_number,
                                        self.number_of_pages):
         pager_query_parms = dict(self.query_parms)
         pager_query_parms["page"] = page_number
         # if there is a gat add a spacer
         if previous_page_number and page_number - previous_page_number > 1:
             pager.append(SPAN("...", _style="margin:0 10px;"))
         is_current = self.current_page_number == page_number
         page_name = ("grid-pagination-button-current"
                      if is_current else "grid-pagination-button")
         attrs = ({
             "_hx-get": URL(self.endpoint, vars=pager_query_parms),
             "_hx-target": self.param.htmx_target,
             "_hx-swap": "innertHTML",
         } if self.param.htmx_target else {
             "_href": URL(self.endpoint, vars=pager_query_parms)
         })
         pager.append(
             A(
                 page_number,
                 **self.param.grid_class_style.get(page_name),
                 _role="button",
                 **attrs,
             ))
         previous_page_number = page_number
     return pager
コード例 #6
0
def edit_phone(contact_id=None, phone_id=None):
    assert contact_id is not None
    assert phone_id is not None
    # match the phone owner's id as well as the number's id
    row = db(
        (db.phone.contact_id == contact_id) &
        (db.phone.id == phone_id)
    ).select().first()
    if row is None:
        redirect(URL('edit_phones', contact_id))

    contact_inf = db(db.contact.id == contact_id).select().first()
    if contact_inf.user_email != get_user_email():
        abort(403)

    form = Form([Field('Phone', 'string'), Field('Kind', 'string')],
                record=dict(Phone=row.number, Kind=row.phone_type), deletable=False, csrf_session=session, formstyle=FormStyleBulma)
    form.param.sidecar.append(SPAN(" ", A("Back", _class="button", _href=URL('edit_phones', contact_id))))

    if form.accepted:
        # insert the number for that contact
        number = form.vars['Phone']
        phone_type = form.vars['Kind']
        db((db.phone.contact_id == contact_id) & (db.phone.id == phone_id)).update(
            number=number,
            phone_type=phone_type
        )
        redirect(URL('edit_phones', contact_id))

    contact_inf = db.contact[contact_id]
    first_name = contact_inf.first_name
    last_name = contact_inf.last_name
    name = f"{first_name} {last_name}"
    return dict(form=form, name=name)
コード例 #7
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
コード例 #8
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,
     )
コード例 #9
0
 def test_find(self):
     a = DIV('A', _class='a')
     b = SPAN('B', _id='b')
     div = DIV(DIV(a), DIV(b))
     self.assertEqual(div.find('.a')[0], a)
     self.assertEqual(div.find('#b')[0], b)
     self.assertEqual(div.find('div.a')[0], a)
     self.assertEqual(div.find('span#b')[0], b)
     self.assertEqual(div.find('span')[0], b)
     self.assertEqual(len(div.find('div')), 4)
     self.assertEqual(len(div.find('abc')), 0)
コード例 #10
0
ファイル: grid.py プロジェクト: karbiv/py4web
 def footer(self, count, offset, len_items):
     """generates the footer"""
     T = self.T
     page = int(offset / self.limit)
     last_page = math.floor(count / self.limit)
     return DIV(
         A("First", _href=self.url(0), _class="button") if page > 1 else "",
         A("Previous", _href=self.url(page - 1), _class="button")
         if page > 0 else "",
         SPAN(
             T("page %s/%s (%s/%s records)") %
             (page + 1, last_page + 1, len_items, count)),
         A("Next", _href=self.url(page + 1), _class="button")
         if page < last_page else "",
         A("Last", _href=self.url(last_page - 1), _class="button")
         if page < last_page - 1 else "",
         SCRIPT(Grid.script),
         _class="py4web-grid-footer",
     )
コード例 #11
0
def add_phone(contact_id):
    assert contact_id is not None
    # contact_id is the id of the contact for which we are inserting an additional number

    form = Form([Field('Phone', 'string'), Field('Kind', 'string')], csrf_session=session, formstyle=FormStyleBulma)
    form.param.sidecar.append(SPAN(" ", A("Back", _class="button", _href=URL('edit_phones', contact_id))))

    if form.accepted:
        # insert the number for that contact
        number = form.vars['Phone']
        phone_type = form.vars['Kind']
        db.phone.insert(
            contact_id=contact_id,
            number=number,
            phone_type=phone_type
        )
        redirect(URL('edit_phones', contact_id))
    contact_inf = db.contact[contact_id]
    first_name = contact_inf.first_name
    last_name = contact_inf.last_name
    name = f"{first_name} {last_name}"
    return dict(form=form, name=name)
コード例 #12
0
ファイル: controllers.py プロジェクト: jpsteil/simple_table
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)
コード例 #13
0
ファイル: form.py プロジェクト: jparga/py4web
    def __call__(
        self,
        table,
        vars,
        errors,
        readonly,
        deletable,
        noncreate,
        show_id,
        kwargs=None,
    ):
        kwargs = kwargs if kwargs else {}

        form_method = "POST"
        form_action = request.url.split(":", 1)[1]
        form_enctype = "multipart/form-data"

        form = FORM(_method=form_method,
                    _action=form_action,
                    _enctype=form_enctype,
                    **kwargs)

        controls = Param(
            labels=dict(),
            widgets=dict(),
            wrappers=dict(),
            comments=dict(),
            hidden_widgets=dict(),
            placeholders=dict(),
            titles=dict(),
            errors=dict(),
            begin=XML(form.xml().split("</form>")[0]),
            submit="",
            delete="",
            end=XML("</form>"),
        )

        json_controls = dict(form_fields=[],
                             form_values=dict(),
                             form_buttons=[],
                             form_method=form_method,
                             form_action=form_action,
                             form_enctype=form_enctype,
                             **kwargs)

        class_label = self.classes["label"]
        class_outer = self.classes["outer"]
        class_inner = self.classes["inner"]
        class_error = self.classes["error"]
        class_info = self.classes["info"]

        all_fields = [x for x in table]
        if "_virtual_fields" in dir(table):
            all_fields += table._virtual_fields
        for field in all_fields:

            # Reset the json control fields.
            field_attributes = dict()
            field_value = None

            field_name = field.name
            field_type = field.type
            field_comment = field.comment if field.comment else ""
            field_label = field.label
            input_id = "%s_%s" % (field.tablename, field.name)
            if isinstance(field, FieldVirtual):
                value = None
            else:
                value = vars.get(
                    field.name,
                    field.default()
                    if callable(field.default) else field.default,
                )
            error = errors.get(field.name)
            field_class = "type-" + field.type.split()[0].replace(":", "-")
            placeholder = (field._placeholder
                           if "_placeholder" in field.__dict__ else None)

            title = field._title if "_title" in field.__dict__ else None
            field_disabled = False

            # only display field if readable or writable
            if not field.readable and not field.writable:
                continue

            # if this is a readonly field only show readable fields
            if readonly:
                if not field.readable:
                    continue

            # do not show the id if not desired
            if field.type == "id" and not show_id:
                continue

            #  if this is an create form (unkown id) then only show writable fields.
            #  Some if an edit form was made from a list of fields and noncreate=True
            elif not vars.get("id") and noncreate:
                if not field.writable:
                    continue

            # ignore blob fields
            if field.type == "blob":  # never display blobs (mistake?)
                continue

            # ignore fields of type id its value is equal to None
            if field.type == "id" and value is None:
                field.writable = False
                continue

            # if the form is readonly or this is an id type field, display it as readonly
            if (readonly or not field.writable or field.type == "id"
                    or isinstance(field, FieldVirtual)):
                # for boolean readonly we use a readonly checbox
                if field.type == "boolean":

                    control = CheckboxWidget().make(field,
                                                    value,
                                                    error,
                                                    title,
                                                    readonly=True)
                # for all othe readonly fields we use represent or a string
                else:
                    if isinstance(field, FieldVirtual):
                        field_value = field.f(vars)
                    else:
                        field_value = (field.represent
                                       and field.represent(value) or value
                                       or "")
                    field_type = "represent"
                    control = DIV(field_value)

                field_disabled = True

            # if we have a field.widget for the field use it but this logic is deprecated
            elif field.widget:
                control = field.widget(table, vars)
            # else we pick the right widget
            else:
                if field.name in self.widgets:
                    widget = self.widgets[field.name]
                elif field.type == "text":
                    widget = TextareaWidget()
                elif field.type == "datetime":
                    widget = DateTimeWidget()
                elif field.type == "boolean":
                    widget = CheckboxWidget()
                elif field.type == "upload":
                    widget = FileUploadWidget()
                    url = getattr(field, "download_url",
                                  lambda value: "#")(value)
                    # Set the download url.
                    field_attributes["_download_url"] = url
                    # Set the flag determining whether the file is an image.
                    field_attributes["_is_image"] = (
                        url != "#") and Form.is_image(value)
                    # do we need the variables below?
                    delete_field_attributes = dict()
                    delete_field_attributes["_label"] = "Remove"
                    delete_field_attributes["_value"] = "ON"
                    delete_field_attributes["_type"] = "checkbox"
                    delete_field_attributes["_name"] = "_delete_" + field.name
                    json_controls["form_fields"] += [delete_field_attributes]
                    json_controls["form_values"]["_delete_" +
                                                 field.name] = None
                elif get_options(field.requires) is not None:
                    widget = SelectWidget()
                elif field.type == "password":
                    widget = PasswordWidget()
                elif field.type.startswith("list:"):
                    widget = ListWidget()
                else:
                    widget = Widget()

                control = widget.make(field, value, error, title, placeholder)

            key = control.name.rstrip("/")

            if key == "input":
                key += "[type=%s]" % (control["_type"] or "text")

            control["_class"] = join_classes(control.attributes.get("_class"),
                                             self.classes.get(key))

            # Set the form controls.
            controls["labels"][field_name] = field_label
            controls["widgets"][field_name] = control
            controls["comments"][field_name] = field_comment
            controls["titles"][field_name] = title
            controls["placeholders"][field_name] = placeholder

            # Set the remain json field attributes.
            field_attributes["_title"] = title
            field_attributes["_label"] = field_label
            field_attributes["_comment"] = field_comment
            field_attributes["_id"] = to_id(field)
            field_attributes["_class"] = field_class
            field_attributes["_name"] = field.name
            field_attributes["_type"] = field.type
            field_attributes["_placeholder"] = placeholder
            field_attributes["_error"] = error
            field_attributes["_disabled"] = field_disabled

            # Add to the json controls.
            json_controls["form_fields"] += [field_attributes]
            json_controls["form_values"][field_name] = field_value

            if error:
                controls["errors"][field.name] = error

            if field.type == "boolean":
                controls.wrappers[field.name] = wrapped = SPAN(
                    control, _class=class_inner)
                form.append(
                    DIV(
                        wrapped,
                        LABEL(
                            " " + field.label,
                            _for=input_id,
                            _class=class_label,
                            _style="display: inline !important",
                        ),
                        P(error, _class=class_error) if error else "",
                        P(field.comment or "", _class=class_info),
                        _class=class_outer,
                    ))
            else:
                controls.wrappers[field.name] = wrapped = DIV(
                    control,
                    _class=self.class_inner_exceptions.get(
                        control.name, class_inner),
                )

                form.append(
                    DIV(
                        LABEL(field.label, _for=input_id, _class=class_label),
                        wrapped,
                        P(error, _class=class_error) if error else "",
                        P(field.comment or "", _class=class_info),
                        _class=class_outer,
                    ))

        if vars.get("id"):
            form.append(INPUT(_name="id", _value=vars["id"], _hidden=True))

        if deletable:

            deletable_record_attributes = dict()

            deletable_field_name = "_delete"
            deletable_field_type = "checkbox"

            # Set the deletable json field attributes.
            deletable_record_attributes["_label"] = " check to delete"
            deletable_record_attributes["_name"] = deletable_field_name
            deletable_record_attributes["_type"] = deletable_field_type
            deletable_record_attributes["_class"] = self.classes[
                "input[type=checkbox]"]
            deletable_record_attributes["_value"] = "ON"

            # Add to the json controls.
            json_controls["form_fields"] += [deletable_record_attributes]
            json_controls["form_values"][deletable_field_name] = None

            controls["delete"] = INPUT(
                _type=deletable_field_type,
                _value=deletable_record_attributes["_value"],
                _name=deletable_field_name,
                _class=self.classes["input[type=checkbox]"],
            )

            form.append(
                DIV(
                    SPAN(
                        controls["delete"],
                        _class=class_inner,
                        _stye="vertical-align: middle;",
                    ),
                    P(
                        deletable_record_attributes["_label"],
                        _class="help",
                        _style="display: inline !important",
                    ),
                    _class=class_outer,
                ))

        submit_button_attributes = dict()

        submit_button_field_type = "submit"

        # Set the deletable json field attributes.
        submit_button_attributes["_label"] = "Submit"
        submit_button_attributes["_type"] = submit_button_field_type
        submit_button_attributes["_class"] = self.classes["input[type=submit]"]

        # Add to the json controls.
        json_controls["form_buttons"] += [submit_button_attributes]

        controls["submit"] = INPUT(
            _type=submit_button_field_type,
            _value="Submit",
            _class=self.classes["input[type=submit]"],
        )

        submit = DIV(
            DIV(
                controls["submit"],
                _class=class_inner,
            ),
            _class=class_outer,
        )
        form.append(submit)

        return dict(form=form, controls=controls, json_controls=json_controls)
コード例 #14
0
    def produce(self, table, vars, errors, readonly, deletable, classes=None):
        self.classes.update(classes or {})
        form = FORM(_method="POST", _action=request.url, _enctype="multipart/form-data")
        controls = Param(
            labels=dict(),
            widgets=dict(),
            comments=dict(),
            hidden_widgets=dict(),
            placeholders=dict(),
            titles=dict(),
            errors=dict(),
            begin=XML(form.xml().split("</form>")[0]),
            submit="",
            delete="",
            end=XML("</form>"),
        )
        class_label = self.classes["label"]
        class_outer = self.classes["outer"]
        class_inner = self.classes["inner"]
        class_error = self.classes["error"]
        class_info = self.classes["info"]

        for field in table:

            input_id = "%s_%s" % (field.tablename, field.name)
            value = vars.get(field.name, field.default)
            error = errors.get(field.name)
            field_class = "type-" + field.type.split()[0].replace(":", "-")
            placeholder = (
                field._placeholder if "_placeholder" in field.__dict__ else None
            )
            title = field._title if "_title" in field.__dict__ else None
            # only diplay field if readable or writable
            if not field.readable and not field.writable:
                continue
            # if this is a reaonly field only show readable fields
            if readonly:
                if not field.readable:
                    continue
            # if this is an create form (unkown id) then only show writable fields
            elif not vars.get("id"):
                if not field.writable:
                    continue
            # ignore blob fields
            if field.type == "blob":  # never display blobs (mistake?)
                continue
            # ignore fields of type id its value is equal to None
            if field.type == "id" and value is None:
                field.writable = False
                continue
            # if the form is readonly or this is an id type field, display it as readonly
            if readonly or not field.writable or field.type == "id":
                if field.type == "boolean":
                    control = INPUT(
                        _type="checkbox",
                        _id=input_id,
                        _name=field.name,
                        _value="ON",
                        _disabled="",
                        _checked=value,
                        _title=title,
                    )
                else:
                    control = DIV(
                        field.represent and field.represent(value) or value or ""
                    )
            # if we have a widget for the field use it
            elif field.widget:
                control = field.widget(table, value)
            # else pick the proper default widget
            elif field.type == "text":
                control = TEXTAREA(
                    value or "",
                    _id=input_id,
                    _name=field.name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "date":
                control = INPUT(
                    _value=value,
                    _type="date",
                    _id=input_id,
                    _name=field.name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "datetime":
                if isinstance(value, str):
                    value = value.replace(" ", "T")
                control = INPUT(
                    _value=value,
                    _type="datetime-local",
                    _id=input_id,
                    _name=field.name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "time":
                control = INPUT(
                    _value=value,
                    _type="time",
                    _id=input_id,
                    _name=field.name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "boolean":
                control = INPUT(
                    _type="checkbox",
                    _id=input_id,
                    _name=field.name,
                    _value="ON",
                    _checked=value,
                    _title=title,
                )
            elif field.type == "upload":
                control = DIV()
                if value and field.download_url is not None and not error:
                    download_div = DIV()
                    download_div.append(
                        LABEL(
                            "Currently:  ",
                        )
                    )
                    download_div.append(
                        A(" download ", _href=field.download_url(value))
                    )
                    download_div.append(
                        INPUT(
                            _type="checkbox",
                            _value="ON",
                            _name="_delete_" + field.name,
                            _title=title,
                        )
                    )
                    download_div.append(" (check to remove)")
                    control.append(download_div)
                control.append(LABEL("Change: "))
                control.append(INPUT(_type="file", _id=input_id, _name=field.name))
            elif get_options(field.requires) is not None and field.writable == True:
                multiple = field.type.startswith("list:")
                value = list(map(str, value if isinstance(value, list) else [value]))
                option_tags = [
                    OPTION(v, _value=k, _selected=(not k is None and k in value))
                    for k, v in get_options(field.requires)
                ]
                control = SELECT(
                    *option_tags,
                    _id=input_id,
                    _name=field.name,
                    _multiple=multiple,
                    _title=title
                )
            else:
                field_type = "password" if field.type == "password" else "text"
                if field.type.startswith("list:"):
                    value = json.dumps(value or [])
                control = INPUT(
                    _type=field_type,
                    _id=input_id,
                    _name=field.name,
                    _value=None if field.type == "password" else value,
                    _class=field_class,
                    _placeholder=placeholder,
                    _title=title,
                    _autocomplete="off" if field_type == "password" else "on",
                )

            key = control.name.rstrip("/")
            if key == "input":
                key += "[type=%s]" % (control["_type"] or "text")
            control["_class"] = (
                control.attributes.get("_class", "") + " " + self.classes.get(key, "")
            ).strip()
            controls["labels"][field.name] = field.label
            controls["widgets"][field.name] = control
            controls["comments"][field.name] = field.comment if field.comment else ""
            controls["titles"][field.name] = title
            controls["placeholders"][field.name] = placeholder
            if error:
                controls["errors"][field.name] = error

            if field.type == "boolean":
                form.append(
                    DIV(
                        SPAN(control, _class=class_inner),
                        LABEL(
                            " " + field.label,
                            _for=input_id,
                            _class=class_label,
                            _style="display: inline !important",
                        ),
                        P(error, _class=class_error) if error else "",
                        P(field.comment or "", _class=class_info),
                        _class=class_outer,
                    )
                )
            else:
                form.append(
                    DIV(
                        LABEL(field.label, _for=input_id, _class=class_label),
                        DIV(control, _class=class_inner),
                        P(error, _class=class_error) if error else "",
                        P(field.comment or "", _class=class_info),
                        _class=class_outer,
                    )
                )

            if vars.get("id"):
                form.append(INPUT(_name="id", _value=vars["id"], _hidden=True))
        if deletable:
            controls["delete"] = INPUT(
                _type="checkbox",
                _value="ON",
                _name="_delete",
                _class=self.classes["input[type=checkbox]"],
            )
            form.append(
                DIV(
                    SPAN(
                        controls["delete"],
                        _class=class_inner,
                        _stye="vertical-align: middle;",
                    ),
                    P(
                        " check to delete",
                        _class="help",
                        _style="display: inline !important",
                    ),
                    _class=class_outer,
                )
            )
        controls["submit"] = INPUT(
            _type="submit",
            _value="Submit",
            _class=self.classes["input[type=submit]"],
        )
        submit = DIV(
            DIV(
                controls["submit"],
                _class=class_inner,
            ),
            _class=class_outer,
        )
        form.append(submit)
        return dict(form=form, controls=controls)
コード例 #15
0
 def large_text_renderer(key, value, rec):
     if isinstance(value, str) and len(value)>14:
         return SPAN(value[:10]+'...', _title=value)
コード例 #16
0
 def yfunc(xx, rr_id):
     xx = xx[:10]
     if rr_id % 2 == 0:
         return SPAN(xx, _style="color:red")
     else:
         return SPAN(xx, _style="color:green")
コード例 #17
0
 def zfunc(xx, rr_id):
     xx = xx[:10]
     if rr_id % 2 == 0:
         return SPAN(xx, _style="color:blue")
     else:
         return SPAN(xx, _style="color:brown")
コード例 #18
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
            ]),
        ),
    )
コード例 #19
0
    def produce(
        self,
        table,
        vars,
        errors,
        readonly,
        noncreate,
        deletable,
        classes=None,
        class_inner_exceptions=None,
        kwargs=None,
    ):
        self.classes.update(classes or {})
        self.class_inner_exceptions.update(class_inner_exceptions or {})
        kwargs = kwargs if kwargs else {}

        form_method = "POST"
        form_action = request.url
        form_enctype = "multipart/form-data"

        form = FORM(
            _method=form_method, _action=form_action, _enctype=form_enctype, **kwargs
        )

        controls = Param(
            labels=dict(),
            widgets=dict(),
            comments=dict(),
            hidden_widgets=dict(),
            placeholders=dict(),
            titles=dict(),
            errors=dict(),
            begin=XML(form.xml().split("</form>")[0]),
            submit="",
            delete="",
            end=XML("</form>"),
        )

        json_controls = dict(
            form_fields=[],
            form_values=dict(),
            form_buttons=[],
            form_method=form_method,
            form_action=form_action,
            form_enctype=form_enctype,
            **kwargs
        )

        class_label = self.classes["label"]
        class_outer = self.classes["outer"]
        class_inner = self.classes["inner"]
        class_error = self.classes["error"]
        class_info = self.classes["info"]

        for field in table:

            # Reset the json control fields.
            field_attributes = dict()
            field_value = None

            field_name = field.name
            field_type = field.type
            field_comment = field.comment if field.comment else ""
            field_label = field.label
            input_id = "%s_%s" % (field.tablename, field.name)
            value = vars.get(
                field.name,
                field.default() if callable(field.default) else field.default,
            )
            error = errors.get(field.name)
            field_class = "type-" + field.type.split()[0].replace(":", "-")
            placeholder = (
                field._placeholder if "_placeholder" in field.__dict__ else None
            )
            title = field._title if "_title" in field.__dict__ else None
            field_disabled = False

            # only diplay field if readable or writable
            if not field.readable and not field.writable:
                continue

            # if this is a reaonly field only show readable fields
            if readonly:
                if not field.readable:
                    continue

            # if this is an create form (unkown id) then only show writable fields. Some if an edit form was made from a list of fields and noncreate=True
            elif not vars.get("id") and noncreate:
                if not field.writable:
                    continue

            # ignore blob fields
            if field.type == "blob":  # never display blobs (mistake?)
                continue

            # ignore fields of type id its value is equal to None
            if field.type == "id" and value is None:
                field.writable = False
                continue

            # if the form is readonly or this is an id type field, display it as readonly
            if readonly or not field.writable or field.type == "id":
                if field.type == "boolean":

                    field_value = value
                    field_type = "checkbox"

                    control = INPUT(
                        _type=field_type,
                        _id=input_id,
                        _name=field_name,
                        _value="ON",
                        _disabled="",
                        _checked=value,
                        _title=title,
                    )
                else:

                    field_value = (
                        field.represent and field.represent(value) or value or ""
                    )
                    field_type = "represent"

                    control = DIV(field_value)

                field_disabled = True

            # if we have a widget for the field use it
            elif field.widget:
                control = field.widget(table, value)

                # Grab the custom widget attributes.
                field_attributes = control.attributes
                field_type = "widget"
                field_value = value

            # else pick the proper default widget
            elif field.type == "text":

                field_value = value or ""
                field_type = "text"

                control = TEXTAREA(
                    field_value,
                    _id=input_id,
                    _name=field_name,
                    _placeholder=placeholder,
                    _title=title,
                )

            elif field.type == "date":

                field_value = value
                field_type = "date"

                control = INPUT(
                    _value=field_value,
                    _type="date",
                    _id=input_id,
                    _name=field_name,
                    _placeholder=placeholder,
                    _title=title,
                )

            elif field.type == "datetime":
                helpervalue = str(value)
                helpervalue = helpervalue.replace(" ", "T")

                field_value = helpervalue
                field_type = "datetime-local"

                control = INPUT(
                    _value=helpervalue,
                    _type="datetime-local",
                    _id=input_id,
                    _name=field_name,
                    _placeholder=placeholder,
                    _title=title,
                )
            elif field.type == "time":

                field_value = value
                field_type = "time"

                control = INPUT(
                    _value=value,
                    _type="time",
                    _id=input_id,
                    _name=field_name,
                    _placeholder=placeholder,
                    _title=title,
                )

            elif field.type == "boolean":

                field_value = value
                field_type = "checkbox"
                field_attributes["_value"] = "ON"

                control = INPUT(
                    _type="checkbox",
                    _id=input_id,
                    _name=field_name,
                    _value=field_attributes["_value"],
                    _checked=value,
                    _title=title,
                )

            elif field.type == "upload":
                control = DIV()
                if value and not error:
                    download_div = DIV()

                    download_div.append(
                        LABEL(
                            "Currently:  ",
                        )
                    )
                    if getattr(field, "download_url", None):
                        url = field.download_url(value)
                    else:
                        url = "#"
                    download_div.append(A(" download ", _href=url))

                    # Set the download url.
                    field_attributes["_download_url"] = url

                    # Set the flag determining whether the file is an image.
                    field_attributes["_is_image"] = (url != "#") and Form.is_image(
                        value
                    )

                    delete_checkbox_name = "_delete_" + field_name

                    download_div.append(
                        INPUT(
                            _type="checkbox",
                            _value="ON",
                            _name=delete_checkbox_name,
                            _title=title,
                        )
                    )
                    download_div.append(" (check to remove)")

                    delete_field_attributes = dict()

                    delete_field_attributes["_label"] = "Remove"
                    delete_field_attributes["_value"] = "ON"
                    delete_field_attributes["_type"] = "checkbox"
                    delete_field_attributes["_name"] = delete_checkbox_name

                    json_controls["form_fields"] += [delete_field_attributes]
                    json_controls["form_values"][delete_checkbox_name] = None

                    control.append(download_div)

                control.append(LABEL("Change: "))
                control.append(INPUT(_type="file", _id=input_id, _name=field_name))

                field_value = None
                field_type = "file"

            elif get_options(field.requires) is not None and field.writable == True:
                multiple = field.type.startswith("list:")
                value = list(map(str, value if isinstance(value, list) else [value]))

                field_options = [
                    [k, v, (not k is None and k in value)]
                    for k, v in get_options(field.requires)
                ]
                option_tags = [
                    OPTION(v, _value=k, _selected=_selected)
                    for (k, v, _selected) in field_options
                ]

                control = SELECT(
                    *option_tags,
                    _id=input_id,
                    _name=field_name,
                    _multiple=multiple,
                    _title=title
                )

                field_value = value
                field_type = "options"
                field_attributes["_multiple"] = multiple
                field_attributes["_options"] = field_options

            else:

                field_type = "password" if field.type == "password" else "text"

                if field.type.startswith("list:"):
                    value = json.dumps(value or [])

                field_value = None if field.type == "password" else value
                field_autocomplete = "off" if field_type == "password" else "on"

                control = INPUT(
                    _type=field_type,
                    _id=input_id,
                    _name=field_name,
                    _value=field_value,
                    _class=field_class,
                    _placeholder=placeholder,
                    _title=title,
                    _autocomplete=field_autocomplete,
                )

                field_attributes["_autocomplete"] = field_autocomplete

            key = control.name.rstrip("/")

            if key == "input":
                key += "[type=%s]" % (control["_type"] or "text")

            control["_class"] = (
                control.attributes.get("_class", "") + " " + self.classes.get(key, "")
            ).strip()

            # Set the form controls.
            controls["labels"][field_name] = field_label
            controls["widgets"][field_name] = control
            controls["comments"][field_name] = field_comment
            controls["titles"][field_name] = title
            controls["placeholders"][field_name] = placeholder

            # Set the remain json field attributes.
            field_attributes["_title"] = title
            field_attributes["_label"] = field_label
            field_attributes["_comment"] = field_comment
            field_attributes["_id"] = input_id
            field_attributes["_class"] = field_class
            field_attributes["_name"] = field_name
            field_attributes["_type"] = field_type
            field_attributes["_placeholder"] = placeholder
            field_attributes["_error"] = error
            field_attributes["_disabled"] = field_disabled

            # Add to the json controls.
            json_controls["form_fields"] += [field_attributes]
            json_controls["form_values"][field_name] = field_value

            if error:
                controls["errors"][field.name] = error

            if field.type == "boolean":
                form.append(
                    DIV(
                        SPAN(control, _class=class_inner),
                        LABEL(
                            " " + field.label,
                            _for=input_id,
                            _class=class_label,
                            _style="display: inline !important",
                        ),
                        P(error, _class=class_error) if error else "",
                        P(field.comment or "", _class=class_info),
                        _class=class_outer,
                    )
                )
            else:
                form.append(
                    DIV(
                        LABEL(field.label, _for=input_id, _class=class_label),
                        DIV(
                            control,
                            _class=self.class_inner_exceptions.get(
                                control.name, class_inner
                            ),
                        ),
                        P(error, _class=class_error) if error else "",
                        P(field.comment or "", _class=class_info),
                        _class=class_outer,
                    )
                )

        if vars.get("id"):
            form.append(INPUT(_name="id", _value=vars["id"], _hidden=True))

        if deletable:

            deletable_record_attributes = dict()

            deletable_field_name = "_delete"
            deletable_field_type = "checkbox"

            # Set the deletable json field attributes.
            deletable_record_attributes["_label"] = " check to delete"
            deletable_record_attributes["_name"] = deletable_field_name
            deletable_record_attributes["_type"] = deletable_field_type
            deletable_record_attributes["_class"] = self.classes["input[type=checkbox]"]
            deletable_record_attributes["_value"] = "ON"

            # Add to the json controls.
            json_controls["form_fields"] += [deletable_record_attributes]
            json_controls["form_values"][deletable_field_name] = None

            controls["delete"] = INPUT(
                _type=deletable_field_type,
                _value=deletable_record_attributes["_value"],
                _name=deletable_field_name,
                _class=self.classes["input[type=checkbox]"],
            )

            form.append(
                DIV(
                    SPAN(
                        controls["delete"],
                        _class=class_inner,
                        _stye="vertical-align: middle;",
                    ),
                    P(
                        deletable_record_attributes["_label"],
                        _class="help",
                        _style="display: inline !important",
                    ),
                    _class=class_outer,
                )
            )

        submit_button_attributes = dict()

        submit_button_field_type = "submit"

        # Set the deletable json field attributes.
        submit_button_attributes["_label"] = "Submit"
        submit_button_attributes["_type"] = submit_button_field_type
        submit_button_attributes["_class"] = self.classes["input[type=submit]"]

        # Add to the json controls.
        json_controls["form_buttons"] += [submit_button_attributes]

        controls["submit"] = INPUT(
            _type=submit_button_field_type,
            _value="Submit",
            _class=self.classes["input[type=submit]"],
        )

        submit = DIV(
            DIV(
                controls["submit"],
                _class=class_inner,
            ),
            _class=class_outer,
        )
        form.append(submit)

        return dict(form=form, controls=controls, json_controls=json_controls)
コード例 #20
0
ファイル: upload_utils.py プロジェクト: ali96343/p4wtab
def p4wupload_file():

    t_id = dict(request.query).get("id_", "0")
    # if t_id != '0':
    #    flash.set(f"deleted id={t_id}", sanitize=True)

    if not os.path.isdir(UPLOAD_FOLDER):
        return f"bad upload path: {UPLOAD_FOLDER}"

    messages = []
    tbl = "uploaded_files"
    upload_field = "image"
    upload_form = Form(
        [
            Field(upload_field, "upload", label="", requires=IS_NOT_EMPTY(),),
            Field("remark", default="mycomment"),
        ],
        formstyle=FormStyleDefault,
    )

    if upload_form.accepted and hasattr(request, "files"):
        bottle_class = request.files.get(upload_field, None)
        if bottle_class:
            orig_fnm = bottle_class.raw_filename
            orig_fnm_content = bottle_class.file.read()
            uniq_file_name = get_unique_name(orig_fnm,)

            data2file(orig_fnm_content, os.path.join(UPLOAD_FOLDER, uniq_file_name))
            row = dict(
                orig_file_name=orig_fnm,
                uniq_file_name=uniq_file_name,
                remark=upload_form.vars["remark"],
            )
            if db[tbl].insert(**db[tbl]._filter_fields(row)):
                db.commit()

    elif upload_form.errors:
        messages.append(f"upload_form has errors: {upload_form.errors}")

    hlinks = ["save", "del"]

    links = [
        lambda tx, r_id: A(
            f"save:[{r_id}]",
            _title="save file to disk",
            _href=URL(f"p4wdownload_file", vars=dict(t_=tx, id_=r_id)),
        ),
        lambda tx, r_id: A(
            f"del:[{r_id}]",
            _title="run p4wdelete_file",
            _href=URL(f"p4wdelete_file", vars=dict(t_=tx, id_=r_id)),
        ),
    ]

    fld_links = {
        #  'id': lambda tx, xx, r_id: A(
        #      f'save[{r_id}]',
        #      _title='save file to disk',
        #      _href=URL(f"p4wdownload_file", vars=dict(t_=tx, x_=xx, id_=r_id)),
        #  ),
        "time": lambda tx, xx, r_id: SPAN(xx.strftime(DATE_FORMAT), _style="color:red"),
    }

    mygrid = sql2table(
        tbl,
        db,
        links=links,
        hlinks=hlinks,
        fld_links=fld_links,
        rows_on_page=2,
        caller="p4wupload_file",
        page_d=dict(request.query),
    )
    return dict(messages=messages, upload_form=upload_form, mygrid=mygrid)