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(' ')) else: _td = TD(field_value if row and field and field_value else '') return _td
def FormStyleDefault(table, vars, errors, readonly, deletable): form = FORM(TABLE(),_method='POST',_action='#',_enctype='multipart/form-data') for field in table: input_id = '%s_%s' % (field.tablename, field.name) value = field.formatter(vars.get(field.name)) error = errors.get(field.name) field_class = field.type.split()[0].replace(':','-') if field.type == 'blob': # never display blobs (mistake?) continue elif readonly or field.type=='id': if not field.readable: continue else: control = field.represent and field.represent(value) or value or '' elif not field.writable: continue elif field.widget: control = field.widget(table, value) elif field.type == 'text': control = TEXTAREA(value or '', _id=input_id,_name=field.name) elif field.type == 'boolean': control = INPUT(_type='checkbox', _id=input_id, _name=field.name, _value='ON', _checked = value) elif field.type == 'upload': control = DIV(INPUT(_type='file', _id=input_id, _name=field.name)) if value: control.append(A('download', _href=donwload_url(value))) control.append(INPUT(_type='checkbox',_value='ON', _name='_delete_'+field.name)) control.append('(check to remove)') elif hasattr(field.requires, 'options'): multiple = field.type.startswith('list:') value = value if isinstance(value, list) else [value] options = [OPTION(v,_value=k,_selected=(k in value)) for k,v in field.requires.options()] control = SELECT(*options, _id=input_id, _name=field.name, _multiple=multiple) else: field_type = 'password' if field.type == 'password' else 'text' control = INPUT(_type=field_type, _id=input_id, _name=field.name, _value=value, _class=field_class) form[0].append(TR(TD(LABEL(field.label,_for=input_id)), TD(control,DIV(error,_class='error') if error else ''), TD(field.comment or ''))) td = TD(INPUT(_type='submit',_value='Submit')) if deletable: td.append(INPUT(_type='checkbox',_value='ON',_name='_delete')) td.append('(check to delete)') form[0].append(TR(TD(),td,TD())) return form
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
def render_search_form(self): # TODO: Do we need this? div = DIV(_id="grid-search", **self.param.grid_class_style.get("grid-search")) div.append(self.param.search_form.custom["begin"]) tr = TR(**self.param.grid_class_style.get("search_form_tr")) for field in self.param.search_form.table: td = TD(**self.param.grid_class_style.get("search_form_td")) if field.type == "boolean": sb = DIV(**self.param.grid_class_style.get("search_boolean")) sb.append(self.param.search_form.custom["widgets"][field.name]) sb.append(field.label) td.append(sb) else: td.append(self.param.search_form.custom["widgets"][field.name]) td.append(self.param.search_form.custom["wrapped_widgets"][field.name]) if ( field.name in self.param.search_form.custom["errors"] and self.param.search_form.custom["errors"][field.name] ): td.append( DIV( self.param.search_form.custom["errors"][field.name], _style="color:#ff0000", ) ) tr.append(td) if self.param.search_button_text: tr.append( TD( INPUT( _class="button", _type="submit", _value=self.param.search_button_text, ), **self.param.grid_class_style.get("search_form_td"), ) ) else: tr.append( TD( self.param.search_form.custom["submit"], **self.param.grid_class_style.get("search_form_td"), ) ) div.append(TABLE(tr, **self.param.grid_class_style.get("search_form_table"))) for hidden_widget in self.param.search_form.custom["hidden_widgets"].keys(): div.append(self.param.search_form.custom["hidden_widgets"][hidden_widget]) div.append(self.param.search_form.custom["end"]) return div
def render_table_body(self): tbody = TBODY() for row in self.rows: # find the row id - there may be nested tables.... if self.use_tablename and self.tablename in row and "id" not in row: row_id = row[self.tablename]["id"] else: row_id = row["id"] self.use_tablename = False tr = TR( _role="row", _class=self.param.grid_class_style.classes.get("grid-tr"), _style=self.param.grid_class_style.styles.get("grid-tr"), ) # add all the fields to the row for index, field in enumerate(self.param.fields): if field.readable and (field.type != "id" or self.param.show_id): tr.append(self.render_field(row, field, index)) td = None # add the action buttons if ((self.param.details and self.param.details != "") or (self.param.editable and self.param.editable != "") or (self.param.deletable and self.param.deletable != "") or (self.param.post_action_buttons or self.param.pre_action_buttons)): classes = ( self.param.grid_class_style.classes.get("grid-td", "") + " " + self.param.grid_class_style.classes.get( "grid-td-action-button")).strip() styles = ( self.param.grid_class_style.styles.get("grid-td", "") + " " + self.param.grid_class_style.styles.get( "grid-td-action-button")).strip() td = TD(_class=classes, _style=styles) if self.param.pre_action_buttons: for btn in self.param.pre_action_buttons: if btn.onclick: btn.url = None td.append( self.render_action_button( btn.url, btn.text, btn.icon, _onclick=btn.onclick, additional_classes=btn.additional_classes, message=btn.message, row_id=row_id if btn.append_id else None, row=row, )) if self.param.details and self.param.details != "": if isinstance(self.param.details, str): details_url = self.param.details else: details_url = self.endpoint + "/details" details_url += "/%s?%s" % (row_id, self.referrer) td.append( self.render_action_button( details_url, self.param.details_action_button_text, "fa-id-card", name="grid-details-button", )) if self.param.editable and self.param.editable != "": if isinstance(self.param.editable, str): edit_url = self.param.editable else: edit_url = self.endpoint + "/edit" edit_url += "/%s?%s" % (row_id, self.referrer) td.append( self.render_action_button( edit_url, self.param.edit_action_button_text, "fa-edit", name="grid-edit-button", )) if self.param.deletable and self.param.deletable != "": if isinstance(self.param.deletable, str): delete_url = self.param.deletable else: delete_url = self.endpoint + "/delete" delete_url += "/%s?%s" % (row_id, self.referrer) td.append( self.render_action_button( delete_url, self.param.delete_action_button_text, "fa-trash", additional_classes="confirmation", message="Delete record", name="grid-delete-button", _onclick= "if(!confirm('sure you want to delete')) return false;", )) if self.param.post_action_buttons: for btn in self.param.post_action_buttons: if btn.onclick: btn.url = None td.append( self.render_action_button( btn.url, btn.text, btn.icon, _onclick=btn.onclick, additional_classes=btn.additional_classes, message=btn.message, row_id=row_id if btn.append_id else None, row=row, )) tr.append(td) tbody.append(tr) return tbody
def render_table_body(self): tbody = TBODY() for row in self.rows: # find the row id - there may be nested tables.... if self.use_tablename and self.tablename in row and "id" not in row: row_id = row[self.tablename]["id"] else: row_id = row["id"] self.use_tablename = False tr = TR( _role="row", _class=self.param.grid_class_style.classes.get("grid-tr"), _style=self.param.grid_class_style.styles.get("grid-tr"), ) # add all the fields to the row for index, field in enumerate(self.param.fields): if field.readable and (field.type != "id" or self.param.show_id): tr.append(self.render_field(row, field, index)) td = None # add the action buttons if ( (self.param.details and self.param.details != "") or (self.param.editable and self.param.editable != "") or (self.param.deletable and self.param.deletable != "") or (self.param.post_action_buttons or self.param.pre_action_buttons) ): classes = ( self.param.grid_class_style.classes.get("grid-td", "") + " " + self.param.grid_class_style.classes.get("grid-td-action-button") ).strip() styles = ( self.param.grid_class_style.styles.get("grid-td", "") + " " + self.param.grid_class_style.styles.get("grid-td-action-button") ).strip() td = TD(_class=classes, _style=styles) if self.param.pre_action_buttons: for btn in self.param.pre_action_buttons: if callable(btn): # a button can be a callable, to indicate whether or not a button should # be displayed. call the function with the row object btn = btn(row) if btn is None: # if None was returned, no button is available for this row: ignore this value in the # list continue if btn.onclick: btn.url = None td.append( self.render_action_button( btn.url, btn.text, btn.icon, _onclick=btn.onclick, additional_classes=btn.additional_classes, message=btn.message, row_id=row_id if btn.append_id else None, row=row, ) ) if self.param.details and self.param.details != "": if isinstance(self.param.details, str): details_url = self.param.details else: details_url = self.endpoint + "/details" details_url += "/%s?%s" % (row_id, self.referrer) td.append( self.render_action_button( url=details_url, button_text=self.param.details_action_button_text, icon="fa-id-card", name="grid-details-button", ) ) if self.param.editable and self.param.editable != "": if isinstance(self.param.editable, str): edit_url = self.param.editable else: edit_url = self.endpoint + "/edit" edit_url += "/%s?%s" % (row_id, self.referrer) td.append( self.render_action_button( url=edit_url, button_text=self.param.edit_action_button_text, icon="fa-edit", name="grid-edit-button", ) ) if self.param.deletable and self.param.deletable != "": if isinstance(self.param.deletable, str): delete_url = self.param.deletable else: delete_url = self.endpoint + "/delete" delete_url += "/%s?%s" % (row_id, self.referrer) attrs = self.attributes_plugin.confirm( message="Are you sure you want to delete?" ) td.append( self.render_action_button( url=delete_url, button_text=self.param.delete_action_button_text, icon="fa-trash", additional_classes="confirmation", message="Delete record", name="grid-delete-button", **attrs, ) ) if self.param.post_action_buttons: for btn in self.param.post_action_buttons: if callable(btn): # a button can be a callable, to indicate whether or not a button should # be displayed. call the function with the row object btn = btn(row) if btn is None: # if None was returned, no button is available for this row: ignore this value in the # list continue if btn.onclick: btn.url = None td.append( self.render_action_button( btn.url, btn.text, btn.icon, _onclick=btn.onclick, additional_classes=btn.additional_classes, message=btn.message, row_id=row_id if btn.append_id else None, row=row, ) ) tr.append(td) tbody.append(tr) return tbody
def FormStyleDefault(table, vars, errors, readonly, deletable): form = FORM(TABLE(), _method='POST', _action='#', _enctype='multipart/form-data') for field in table: input_id = '%s_%s' % (field.tablename, field.name) value = field.formatter(vars.get(field.name)) error = errors.get(field.name) field_class = field.type.split()[0].replace(':', '-') if field.type == 'blob': # never display blobs (mistake?) continue elif readonly or field.type == 'id': if not field.readable: continue else: control = field.represent and field.represent( value) or value or '' elif not field.writable: continue elif field.widget: control = field.widget(table, value) elif field.type == 'text': control = TEXTAREA(value or '', _id=input_id, _name=field.name) elif field.type == 'boolean': control = INPUT(_type='checkbox', _id=input_id, _name=field.name, _value='ON', _checked=value) elif field.type == 'upload': control = DIV(INPUT(_type='file', _id=input_id, _name=field.name)) if value: control.append(A('download', _href=donwload_url(value))) control.append( INPUT(_type='checkbox', _value='ON', _name='_delete_' + field.name)) control.append('(check to remove)') elif hasattr(field.requires, 'options'): multiple = field.type.startswith('list:') value = value if isinstance(value, list) else [value] options = [ OPTION(v, _value=k, _selected=(k in value)) for k, v in field.requires.options() ] control = SELECT(*options, _id=input_id, _name=field.name, _multiple=multiple) else: field_type = 'password' if field.type == 'password' else 'text' control = INPUT(_type=field_type, _id=input_id, _name=field.name, _value=value, _class=field_class) form[0].append( TR(TD(LABEL(field.label, _for=input_id)), TD(control, DIV(error, _class='error') if error else ''), TD(field.comment or ''))) td = TD(INPUT(_type='submit', _value='Submit')) if deletable: td.append(INPUT(_type='checkbox', _value='ON', _name='_delete')) td.append('(check to delete)') form[0].append(TR(TD(), td, TD())) return form
def render_table_body(self): _tbody = TBODY() for row in self.rows: # find the row id - there may be nested tables.... if self.use_tablename: row_id = row[self.tablename]['id'] else: row_id = row['id'] _tr = TR() # add all the fields to the row for field in self.fields: if field.name not in [x.name for x in self.hidden_fields] and \ (field.name != 'id' or (field.name == 'id' and self.show_id)): _tr.append(self.render_field(row, field)) _td = None # add the action buttons if (self.details and self.details != '') or \ (self.editable and self.editable != '') or \ (self.deletable and self.deletable != ''): _td = TD(_class='center', _style='text-align: center; white-space: nowrap;') if self.pre_action_buttons: for btn in self.pre_action_buttons: _td.append(self.render_action_button(btn.url, btn.text, btn.icon, row_id=row_id if btn.append_id else None, user_signature=self.user_signature if btn.append_signature else None, page=self.current_page_number if btn.append_page else None)) if self.details and self.details != '': if isinstance(self.details, str): details_url = self.details else: details_url = URL(self.endpoint) + '/details/%s' % self.tablename details_url += '/%s?user_signature=%s&page=%s' % (row_id, self.user_signature, self.current_page_number) _td.append(self.render_action_button(details_url, 'Details', 'fa-id-card')) if self.editable and self.editable != '': if isinstance(self.editable, str): edit_url = self.editable else: edit_url = URL(self.endpoint) + '/edit/%s' % self.tablename _td.append(self.render_action_button(edit_url, 'Edit', 'fa-edit', row_id=row_id, user_signature=self.user_signature, page=self.current_page_number)) if self.deletable and self.deletable != '': if isinstance(self.deletable, str): delete_url = self.deletable else: delete_url = URL(self.endpoint) + '/delete/%s' % self.tablename delete_url += '/%s?user_signature=%s' % (row_id, self.user_signature) _td.append(self.render_action_button(delete_url, 'Delete', 'fa-trash')) if self.post_action_buttons: for btn in self.post_action_buttons: _td.append(self.render_action_button(btn.url, btn.text, btn.icon, row_id=row_id if btn.append_id else None, user_signature=self.user_signature if btn.append_signature else None, page=self.current_page_number if btn.append_page else None)) _tr.append(_td) _tbody.append(_tr) return _tbody