3
0
Fork 0

fix: keep original value along with rendered, in grid vue context

this change was made for sake of sorting, when the backend is not
responsible for that.  in particular datetime values must be
"rendered" somehow when passing to frontend, but depending on various
factors the rendering may not preserve the "sensible" sort order
behavior, e.g. if "weekday name" begins the rendered string.

so in all cases now, rendered values will be given a distinct key in
the record dict, while the original value stays in its original
place.  this should let grid sorting work off the original value, and
hopefully all is well..fingers crossed
This commit is contained in:
Lance Edgar 2026-03-14 16:24:58 -05:00
parent d08ba5fe51
commit 16131cd256
3 changed files with 23 additions and 12 deletions

View file

@ -2501,11 +2501,10 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
# loop thru data # loop thru data
data = [] data = []
row_classes = {} row_classes = {}
for i, record in enumerate(original_data, 1): for i, original_record in enumerate(original_data, 1):
original_record = record
# convert record to new dict # convert record to new dict
record = self.object_to_dict(record) record = self.object_to_dict(original_record)
# discard non-declared fields # discard non-declared fields
record = {field: record[field] for field in record if field in self.columns} record = {field: record[field] for field in record if field in self.columns}
@ -2518,19 +2517,17 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
# nb. no need to render if column not included # nb. no need to render if column not included
if key in self.columns: if key in self.columns:
value = record.get(key, None) value = record.get(key, None)
record[key] = renderer(original_record, key, value) record[f"_rendered_{key}"] = renderer(original_record, key, value)
# add action urls to each record # add action urls to each record
for action in self.actions: for action in self.actions:
key = f"_action_url_{action.key}" key = f"_action_url_{action.key}"
if key not in record: if key not in record:
url = action.get_url(original_record, i) if url := action.get_url(original_record, i):
if url:
record[key] = url record[key] = url
# set row css class if applicable # set row css class if applicable
css_class = self.get_row_class(original_record, record, i) if css_class := self.get_row_class(original_record, record, i):
if css_class:
# nb. use *string* zero-based index, for js compat # nb. use *string* zero-based index, for js compat
row_classes[str(i - 1)] = css_class row_classes[str(i - 1)] = css_class

View file

@ -177,9 +177,9 @@
cell-class="c_${column['field']}"> cell-class="c_${column['field']}">
% if grid.is_linked(column['field']): % if grid.is_linked(column['field']):
<a :href="props.row._action_url_view" <a :href="props.row._action_url_view"
v-html="props.row.${column['field']}" /> v-html="props.row?._rendered_${column['field']} === undefined ? props.row.${column['field']} : props.row._rendered_${column['field']}" />
% else: % else:
<span v-html="props.row.${column['field']}"></span> <span v-html="props.row?._rendered_${column['field']} === undefined ? props.row.${column['field']} : props.row._rendered_${column['field']}"></span>
% endif % endif
</${b}-table-column> </${b}-table-column>
% endif % endif

View file

@ -2025,7 +2025,12 @@ class TestGrid(WebTestCase):
context, context,
{ {
"data": [ "data": [
{"foo": "blah blah", "baz": "zoo", "_action_url_view": "/blarg"} {
"foo": "bar",
"_rendered_foo": "blah blah",
"baz": "zoo",
"_action_url_view": "/blarg",
}
], ],
"row_classes": {}, "row_classes": {},
}, },
@ -2080,7 +2085,16 @@ class TestGrid(WebTestCase):
# can override value rendering # can override value rendering
grid.set_renderer("foo", lambda record, key, value: "blah blah") grid.set_renderer("foo", lambda record, key, value: "blah blah")
data = grid.get_vue_data() data = grid.get_vue_data()
self.assertEqual(data, [{"foo": "blah blah", "_action_url_view": "/blarg"}]) self.assertEqual(
data,
[
{
"foo": "bar",
"_rendered_foo": "blah blah",
"_action_url_view": "/blarg",
}
],
)
def test_get_row_class(self): def test_get_row_class(self):
model = self.app.model model = self.app.model