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)
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)
def make(self): """makes the grid, must be called inside an action""" T, db, table, query = self.T, self.db, self.table, self.query # bypass rest API if it is a form id = safeint(request.query.get("id") or request.forms.get("id")) if id is not None: if (id == 0 and not self.create) or (id > 0 and not self.editable): raise HTTP(404) record = db(query)(table.id == id).select().first() if id else None form = Form(table, record, deletable=self.deletable, **self.form_attributes) form.action = (request.url.split("?")[0] + "?" + urllib.parse.urlencode(request.query)) del request.query["id"] if form.deleted: message = T("Record deleted") elif form.accepted: message = T("Record created") if not id else T("Record Saved") else: return DIV(self.header(id), form, _class="py4web-grid") else: message = "" if self.denormalize: lookup = [] for k, fs in self.denormalize.items(): lookup.append("%s!:%s[%s]" % (k, k, ",".join(fs))) request.query["@lookup"] = ",".join(lookup) offset = safeint(request.query.get("@offset", 0)) request.query["@count"] = "true" request.query["@limit"] = offset + self.limit id = None data = self.restapi("GET", self.table._tablename, None, request.query) items = data.get("items", []) count = data.get("count", 0) table = TABLE(_class="table") fields = (items[0].keys() if items else [f.rsplit(".", 1)[0] for f in request.query if f[:1] != "@"]) table.append(TR(*[TH(self.sortlink(key)) for key in fields])) table.append(TR(*[TH(self.filterlink(key)) for key in fields])) for item in items: table.append( TR(*[ TD(self.render(key, value)) for key, value in item.items() ])) header = self.header(id, message) footer = self.footer(count, offset, len(items)) return DIV(header, table, footer, _class="py4web-grid")
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)