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
Esempio n. 2
0
    def render_default_form(self):

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

        # we do not need classes for these elements
        tr = TR()
        if len(options) > 1:
            tr.append(TD(select))
        tr.append(TD(input))
        tr.append(TD(submit, clear))
        form.append(TABLE(tr))
        div.append(form)
        return div
Esempio n. 3
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)
Esempio n. 4
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 = 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
Esempio n. 5
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
Esempio n. 6
0
 def make(self, field, value, error, title, placeholder="", readonly=False):
     control = DIV()
     field_id = to_id(field)
     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) if k != ""]
     for k, v, selected in field_options:
         control.append(
             INPUT(
                 v,
                 _id=field_id,
                 _value=k,
                 _label=v,
                 _name=field.name,
                 _type="radio",
                 _checked=selected,
             ))
         control.append(LABEL(v, _for=field_id))
     return control
Esempio n. 7
0
    def render_search_form(self):
        # TODO: Do we need this?
        div = DIV(_id="grid-search", **self.param.grid_class_style.get("grid-search"))
        div.append(self.param.search_form.custom["begin"])
        tr = TR(**self.param.grid_class_style.get("search_form_tr"))
        for field in self.param.search_form.table:
            td = TD(**self.param.grid_class_style.get("search_form_td"))
            if field.type == "boolean":
                td.append(self.param.search_form.custom["widgets"][field.name])
                td.append(field.label)
            else:
                td.append(self.param.search_form.custom["widgets"][field.name])
            if (
                field.name in self.param.search_form.custom["errors"]
                and self.param.search_form.custom["errors"][field.name]
            ):
                td.append(
                    DIV(
                        self.param.search_form.custom["errors"][field.name],
                        _style="color:#ff0000",
                    )
                )
            tr.append(td)
        if self.param.search_button_text:
            tr.append(
                TD(
                    INPUT(
                        _class="button",
                        _type="submit",
                        _value=self.param.search_button_text,
                    ),
                    **self.param.grid_class_style.get("search_form_td"),
                )
            )
        else:
            tr.append(
                TD(
                    self.param.search_form.custom["submit"],
                    **self.param.grid_class_style.get("search_form_td"),
                )
            )
        div.append(TABLE(tr, **self.param.grid_class_style.get("search_form_table")))
        for hidden_widget in self.param.search_form.custom["hidden_widgets"].keys():
            div.append(self.param.search_form.custom["hidden_widgets"][hidden_widget])

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

        return div
Esempio n. 8
0
def radio_widget(field, values_dict):
    control = DIV()
    if "_table" in dir(field):
        tablename = field._table
    else:
        tablename = "no_table"
    for k, v in get_options(field.requires)[1:]:
        attrs = {}
        if values_dict and str(values_dict["order_type"]) == k:
            attrs["_checked"] = "ON"
        control.append(
            INPUT(
                v,
                _id="%s_%s" % (tablename, k),
                _value=k,
                _label=v,
                _name=field.name,
                _type="radio",
                **attrs,
            ))
        control.append(LABEL(v, _for="%s_%s" % (tablename, k)))

    return control
Esempio n. 9
0
 def header(self, id, message=""):
     """generates the header"""
     T = self.T
     div = DIV(_class="py4web-grid-header")
     if message:
         div.append(DIV(message, _class="py4web-grid-message"))
     if self.create and id is None:
         div.append(
             A(
                 T("Create Record"),
                 _class="button",
                 _href=request.url.split("?")[0] + "?id=0",
             )
         )
     elif (self.create and id == 0) or (self.editable and id and id > 0):
         query = dict(request.query)
         query.pop("id", None)
         url = request.url.split("?")[0] + "?" + urllib.parse.urlencode(query)
         div.append(A(T("Back"), _class="button", _href=url))
         div.append(T("New Record") if id == 0 else T("Edit Record"))
     return div
Esempio n. 10
0
    def render_table_pager(self):
        _pager = DIV(_class='is-pulled-right')
        for page_number in self.iter_pages():
            if page_number:
                pager_query_parms = dict(self.query_parms)
                pager_query_parms['page'] = page_number
                pager_query_parms['user_signature'] = self.user_signature
                if self.current_page_number == page_number:
                    _pager.append(A(page_number, _class='button is-primary is-small',
                                    _href=URL(self.endpoint, vars=pager_query_parms)))
                else:
                    _pager.append(A(page_number, _class='button is-small',
                                    _href=URL(self.endpoint, vars=pager_query_parms)))
            else:
                _pager.append('...')

        return _pager
Esempio n. 11
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 = dict(
            widgets=dict(),
            hidden_widgets=dict(),
            errors=dict(),
            begin=XML(form.xml().split("</form>")[0]),
            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 = field.type.split()[0].replace(":", "-")

            if not field.readable and not field.writable:
                continue
            if not readonly and not field.writable:
                continue
            if field.type == "blob":  # never display blobs (mistake?)
                continue
            if field.type == "id" and value is None:
                field.writable = False
                continue
            if readonly or field.type == "id":
                control = DIV(field.represent and field.represent(value) or value or "")
            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 == "date":
                control = INPUT(
                    _value=value, _type="date", _id=input_id, _name=field.name
                )
            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
                )
            elif field.type == "time":
                control = INPUT(
                    _value=value, _type="time", _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=field.download_url(value)))
                    control.append(
                        INPUT(
                            _type="checkbox", _value="ON", _name="_delete_" + field.name
                        )
                    )
                    control.append("(check to remove)")
            elif get_options(field.requires) is not None:
                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
                     )
            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,
                )

            key = control.name.rstrip("/")
            if key == "input":
                key += "[type=%s]" % (control["_type"] or "text")
            control["_class"] = self.classes.get(key, "")

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

            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 'id' in vars:
                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(
                    DIV(controls["delete"], _class=class_inner,),
                    P("check to delete", _class="help"),
                    _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)
Esempio n. 12
0
    def make(self, field, value, error, title, placeholder="", readonly=False):
        field_id = to_id(field)
        control = DIV()
        if value and not error:
            download_div = DIV()

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

            if not readonly:
                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=field_id, _name=field.name))
        return control
Esempio n. 13
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)
Esempio n. 14
0
def FormStyleDefault(table, vars, errors, readonly, deletable, classes=None):
    form = FORM(_method='POST',_action='#',_enctype='multipart/form-data')

    classes = classes or {}
    class_label = classes.get('label', '')
    class_outer = classes.get('outer', '')
    class_inner = classes.get('inner', '')
    class_error = classes.get('error', '')
    class_info = classes.get('info', '')

    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 = DIV(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 = list(map(str, 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)
        
        key = control.name.rstrip('/')
        if key == 'input':
            key += '[type=%s]' % (control['_type'] or 'text')
        control['_class'] = classes.get(key, '')

        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 deletable:
        form.append(DIV(DIV(INPUT(_type='checkbox',_value='ON',_name='_delete',
                                  _class=classes.get('input[type=checkbox]')),
                            _class=class_inner),
                        P('check to delete',_class="help"),
                        _class=class_outer))
    submit = DIV(DIV(INPUT(_type='submit',_value='Submit',
                           _class=classes.get('input[type=submit]')),
                     _class=class_inner),
                 _class=class_outer)
    form.append(submit)
    return form
Esempio n. 15
0
def FormStyleDefault(table, vars, errors, readonly, deletable, classes=None):
    form = FORM(_method="POST",
                _action=request.path,
                _enctype="multipart/form-data")

    classes = classes or {}
    class_label = classes.get("label", "")
    class_outer = classes.get("outer", "")
    class_inner = classes.get("inner", "")
    class_error = classes.get("error", "")
    class_info = classes.get("info", "")

    for field in table:

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

        if not field.readable:
            continue
        if not readonly and not field.writable:
            continue
        if field.type == "blob":  # never display blobs (mistake?)
            continue
        if field.type == "id" and value is None:
            continue
        if readonly or field.type == "id":
            control = DIV(field.represent and field.represent(value) or value
                          or "")
        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=field.download_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 = list(
                map(str, value if isinstance(value, list) else [value]))
            options = [
                OPTION(v, _value=k, _selected=(not k is None and 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,
            )

        key = control.name.rstrip("/")
        if key == "input":
            key += "[type=%s]" % (control["_type"] or "text")
        control["_class"] = classes.get(key, "")

        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 deletable:
        form.append(
            DIV(
                DIV(
                    INPUT(
                        _type="checkbox",
                        _value="ON",
                        _name="_delete",
                        _class=classes.get("input[type=checkbox]"),
                    ),
                    _class=class_inner,
                ),
                P("check to delete", _class="help"),
                _class=class_outer,
            ))
    submit = DIV(
        DIV(
            INPUT(
                _type="submit",
                _value="Submit",
                _class=classes.get("input[type=submit]"),
            ),
            _class=class_inner,
        ),
        _class=class_outer,
    )
    form.append(submit)
    return form
    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)
Esempio n. 17
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)
Esempio n. 18
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)