def new_instance(self, grid): cls = self.__class__ column = cls(self.label, self.key, None, self.can_sort, _dont_assign=True) column.grid = grid column.expr = self.expr if self.filter: column.filter = self.filter.new_instance(dialect=grid.manager.db.engine.dialect) column.head = BlankObject() column.head.hah = HTMLAttributes(self.kwargs) column.body = BlankObject() column.body.hah = HTMLAttributes(self.kwargs) if xlwt is not None: column.xlwt_stymat = self.xlwt_stymat_init() else: column.xlwt_stymat = None # try to be smart about which attributes should get copied to the # new instance by looking for attributes on the class that have the # same name as arguments to the classes __init__ method args = (inspect.getargspec(self.__init__).args if six.PY2 else inspect.getfullargspec(self.__init__).args) for argname in args: if argname != 'self' and hasattr(self, argname) and \ argname not in ('label', 'key', 'filter', 'can_sort'): setattr(column, argname, getattr(self, argname)) return column
def table_td(self, col, record): col_hah = HTMLAttributes(col.body.hah) # allow column stylers to set attributes for styler, cname in self.grid._colstylers: for_column = self.grid.column(cname) if col.key == for_column.key: styler(self.grid, col_hah, record) # extract the value from the record for this column and prep col_value = col.render('html', record, col_hah) # turn empty values into a non-breaking space so table cells don't # collapse if col_value is None: styled_value = Markup(' ') elif isinstance(col_value, six.string_types) and col_value.strip() == '': styled_value = Markup(' ') else: styled_value = col_value return self._render_jinja('<td{{attrs|wg_attributes}}>{{value}}</td>', attrs=col_hah, value=styled_value)
def new_instance(self, grid): cls = self.__class__ column = cls(self.label, self.key, None, self.can_sort, group=self.group, _dont_assign=True) column.grid = grid column.expr = self.expr if self.filter: column.filter = self.filter.new_instance( dialect=grid.manager.db.engine.dialect) column.head = BlankObject() column.head.hah = HTMLAttributes(self.kwargs) column.body = BlankObject() column.body.hah = HTMLAttributes(self.kwargs) if xlwt is not None: column.xlwt_stymat = self.xlwt_stymat_init() else: column.xlwt_stymat = None # try to be smart about which attributes should get copied to the # new instance by looking for attributes on the class that have the # same name as arguments to the classes __init__ method args = (inspect.getargspec(self.__init__).args if six.PY2 else inspect.getfullargspec(self.__init__).args) for argname in args: if argname != 'self' and argname not in ('label', 'key', 'filter', 'can_sort', 'render_in', 'visible') and hasattr( self, argname): setattr(column, argname, getattr(self, argname)) # Copy underlying value of render_in and visible, in case they are # lambdas that should be called per grid instance. column.render_in = self._render_in column.visible = self._visible return column
def table_tr_styler(self, rownum, record): # handle row styling row_hah = HTMLAttributes() # add odd/even classes to the rows if (rownum + 1) % 2 == 1: row_hah.class_ += 'odd' else: row_hah.class_ += 'even' for styler in self.grid._rowstylers: styler(self.grid, rownum, row_hah, record) return row_hah
def __init__(self, ident=None, per_page=_None, on_page=_None, qs_prefix='', class_='datagrid', **kwargs): self._ident = ident self.hah = HTMLAttributes(kwargs) self.hah.id = self.ident self.hah.class_ += class_ self.filtered_cols = OrderedDict() self.subtotal_cols = OrderedDict() self.order_by = [] self.qs_prefix = qs_prefix self.user_warnings = [] self.search_value = None self._record_count = None self._records = None self._page_totals = None self._grand_totals = None if self.hide_excel_link is True: warnings.warn( "Hide excel link is deprecated, you should just override allowed_export_targets instead", # noqa DeprecationWarning) if self.allowed_export_targets is None: self.allowed_export_targets = {} # If the grid doesn't define any export targets # lets setup the export targets for xls and xlsx if we have the requirement if xlwt is not None: self.allowed_export_targets['xls'] = XLS if xlsxwriter is not None: self.allowed_export_targets['xlsx'] = XLSX self.set_renderers() self.export_to = None # when session feature is enabled, key is the unique string # used to distinguish grids. Initially set to a random # string, but will be set to the session key in args self.session_key = randchars(12) # at times, different grids may be made to share a session self.foreign_session_loaded = False self.per_page = per_page if per_page is not _None else self.__class__.per_page self.on_page = on_page if on_page is not _None else self.__class__.on_page self.columns = [] self.key_column_map = {} self._init_columns() self.post_init()
def test_number_formatting(self): class TG(Grid): NumericColumn('C1', Person.numericcol, places=1) g = TG() c = g.columns[0] record = {'numericcol': D('1234.16')} eq_(c.render_html(record, None), '1,234.2') c.format_as = 'accounting' eq_(c.render_html(record, None), '$1,234.16') # accounting with negative value record = {'numericcol': D('-1234.16')} hah = HTMLAttributes() eq_(c.render_html(record, hah), '($1,234.16)') assert hah['class'] == 'negative' record = {'numericcol': D('.1673')} c.format_as = 'percent' eq_(c.render_html(record, None), '16.7%')
def __init__(self, ident=None, per_page=_None, on_page=_None, qs_prefix='', class_='datagrid', **kwargs): self._ident = ident self.hah = HTMLAttributes(kwargs) self.hah.id = self.ident self.hah.class_ += class_ self.filtered_cols = OrderedDict() self.subtotal_cols = OrderedDict() self.order_by = [] self.qs_prefix = qs_prefix self.user_warnings = [] self._record_count = None self._records = None self._page_totals = None self._grand_totals = None if self.hide_excel_link is True: warnings.warn( "Hide excel link is deprecated, you should just override allowed_export_targets instead", # noqa DeprecationWarning ) if self.allowed_export_targets is None: self.allowed_export_targets = {} # If the grid doesn't define any export targets # lets setup the export targets for xls and xlsx if we have the requirement if xlwt is not None: self.allowed_export_targets['xls'] = XLS if xlsxwriter is not None: self.allowed_export_targets['xlsx'] = XLSX self.set_renderers() self.export_to = None # when session feature is enabled, key is the unique string # used to distinguish grids. Initially set to a random # string, but will be set to the session key in args self.session_key = randchars(12) # at times, different grids may be made to share a session self.foreign_session_loaded = False self.per_page = per_page if per_page is not _None else self.__class__.per_page self.on_page = on_page if on_page is not _None else self.__class__.on_page self.columns = [] self.key_column_map = {} def subtotal_function_map(v): # subtotals default to the simplest expression (sum). avg is also an option, or you # can assign a string or expression (string using column labels would probably # work best at this stage) if v is True or v == 'sum': return sum_ elif v == 'avg': return avg_ return v for col in self.__cls_cols__: new_col = col.new_instance(self) self.columns.append(new_col) self.key_column_map[new_col.key] = new_col if new_col.filter is not None: self.filtered_cols[new_col.key] = new_col if new_col.has_subtotal is not False and new_col.has_subtotal is not None: self.subtotal_cols[new_col.key] = ( subtotal_function_map(new_col.has_subtotal), new_col ) self.post_init()
def test_init_from_dict(self): at = HTMLAttributes({'name': 'foo', 'class_': 'bar baz'}) self.check_eq({'class': 'bar baz', 'name': 'foo'}, **at)
def test_key_access_starting_with_unicode(self): at = HTMLAttributes() at['class_'] = 'foo' at['class_'] += 'bar' self.check_eq({'class': 'foo bar'}, **at)
def test_underscore_key_access(self): at = HTMLAttributes() at['class_'] = 'foo' self.check_eq({'class': 'foo'}, **at)
def test_key_access(self): at = HTMLAttributes() at['name'] = 'foo' self.check_eq({'name': 'foo'}, **at)
def test_add_attribute_access_staring_with_unicode(self): at = HTMLAttributes() at.class_ = 'foo' at.class_ += 'bar' self.check_eq({'class': 'foo bar'}, **at)
def test_underscore_attribute_access(self): at = HTMLAttributes() at.class_ = 'foo' self.check_eq({'class': 'foo'}, **at)
def test_attribute_access(self): at = HTMLAttributes() at.name = 'foo' self.check_eq({'name': 'foo'}, **at)
def test_init_from_kwargs(self): at = HTMLAttributes(name='foo', class_='bar baz') self.check_eq({'class': 'bar baz', 'name': 'foo'}, **at)