Add support for aligment classes from HandsOnTable

pull/4755/head
Samuel Mendes 2018-11-15 17:16:19 +01:00 zatwierdzone przez Matt Westcott
rodzic 31d010cfc6
commit 7402210f35
6 zmienionych plików z 112 dodań i 11 usunięć

Wyświetl plik

@ -99,6 +99,13 @@ class TableBlock(FieldBlock):
'html_renderer': self.is_html_renderer(),
'data': value['data'][1:] if table_header else value.get('data', [])
})
if value.get('cell'):
new_context['classnames'] = {}
for meta in value['cell']:
if 'className' in meta:
new_context['classnames'][(meta['row'], meta['col'])] = meta['className']
return render_to_string(template, new_context)
else:
return self.render_basic(value, context=context)

Wyświetl plik

@ -10,10 +10,14 @@ function initTable(id, tableOptions) {
var hot;
var defaultOptions;
var finalOptions = {};
var getCellsClassnames;
var persist;
var cellEvent;
var metaEvent;
var initEvent;
var structureEvent;
var dataForForm = null;
var isInitialized = false;
var getWidth = function() {
return $('.widget-table_input').closest('.sequence-member-inner').width();
};
@ -64,9 +68,26 @@ function initTable(id, tableOptions) {
});
}
getCellsClassnames = function() {
var meta = hot.getCellsMeta();
var cellsClassnames = []
for (var i = 0; i < meta.length; i++) {
if (meta[i].hasOwnProperty('className')) {
cellsClassnames.push({
row: meta[i].row,
col: meta[i].col,
className: meta[i].className
});
}
}
console.log(cellsClassnames);
return cellsClassnames;
};
persist = function() {
hiddenStreamInput.val(JSON.stringify({
data: hot.getData(),
cell: getCellsClassnames(),
first_row_is_table_header: tableHeaderCheckbox.prop('checked'),
first_col_is_header: colHeaderCheckbox.prop('checked')
}));
@ -80,6 +101,16 @@ function initTable(id, tableOptions) {
persist();
};
metaEvent = function(row, column, key, value) {
if (isInitialized && key === 'className') {
persist();
}
};
initEvent = function() {
isInitialized = true;
};
structureEvent = function(index, amount) {
resizeHeight(getHeight());
persist();
@ -99,12 +130,19 @@ function initTable(id, tableOptions) {
afterCreateRow: structureEvent,
afterRemoveCol: structureEvent,
afterRemoveRow: structureEvent,
afterSetCellMeta: metaEvent,
afterInit: initEvent,
// contextMenu set via init, from server defaults
};
if (dataForForm !== null && dataForForm.hasOwnProperty('data')) {
if (dataForForm !== null) {
// Overrides default value from tableOptions (if given) with value from database
defaultOptions.data = dataForForm.data;
if (dataForForm.hasOwnProperty('data')) {
defaultOptions.data = dataForForm.data;
}
if (dataForForm.hasOwnProperty('cell')) {
defaultOptions.cell = dataForForm.cell;
}
}
Object.keys(defaultOptions).forEach(function (key) {

Wyświetl plik

@ -1,9 +1,12 @@
{% load table_block_tags %}
<table>
{% if table_header %}
<thead>
<tr>
{% for column in table_header %}
<th>
{% with forloop.counter0 as col_index %}
<th {% cell_classname 0 col_index %}>
{% if column.strip %}
{% if html_renderer %}
{{ column.strip|safe|linebreaksbr }}
@ -12,16 +15,19 @@
{% endif %}
{% endif %}
</th>
{% endwith %}
{% endfor %}
</tr>
</thead>
{% endif %}
<tbody>
{% for row in data %}
{% with forloop.counter0 as row_index %}
<tr>
{% for column in row %}
{% with forloop.counter0 as col_index %}
{% if first_col_is_header and forloop.first %}
<th>
<th {% cell_classname row_index col_index table_header %}>
{% if column.strip %}
{% if html_renderer %}
{{ column.strip|safe|linebreaksbr }}
@ -31,7 +37,7 @@
{% endif %}
</th>
{% else %}
<td>
<td {% cell_classname row_index col_index table_header %}>
{% if column.strip %}
{% if html_renderer %}
{{ column.strip|safe|linebreaksbr }}
@ -41,8 +47,10 @@
{% endif %}
</td>
{% endif %}
{% endwith %}
{% endfor %}
</tr>
{% endwith %}
{% endfor %}
</tbody>
</table>

Wyświetl plik

@ -0,0 +1,17 @@
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.simple_tag(takes_context=True)
def cell_classname(context, row_index, col_index, table_header=None):
classnames = context.get('classnames')
if classnames:
if table_header is not None:
row_index += 1
index = (row_index, col_index)
cell_class = classnames.get(index)
if cell_class:
return mark_safe('class="{}"'.format(cell_class))
return ''

Wyświetl plik

@ -11,6 +11,19 @@ from wagtail.tests.testapp.models import TableBlockStreamPage
from wagtail.tests.utils import WagtailTestUtils
def get_cell_classname(cells_meta, row_index, col_index):
"""
Helper function used in building a test html
table. Provides a cell's class attribute if
one is specified in the meta.
"""
if cells_meta:
for meta in cells_meta:
if meta.get('row') == row_index and meta.get('col') == col_index:
return ' class="%s"' % meta.get('className')
return ''
def tiny_escape(val):
"""
Helper function used in building a test html
@ -26,22 +39,24 @@ def get_test_html_from_value(value):
that's what we expect from the TableBlock.
"""
data = list(value['data']) # Make a copy
meta = value.get('cell')
table = '<table>'
if value['first_row_is_table_header']:
row_header = data.pop(0)
table += '<thead><tr>'
for th in row_header:
table += '<th>%s</th>' % tiny_escape(th)
for col_idx, th in enumerate(row_header):
table += '<th%s>%s</th>' % (get_cell_classname(meta, 0, col_idx), tiny_escape(th))
table += '</tr></thead>'
table += '<tbody>'
for row in data:
row_idx_start = 1 if value['first_row_is_table_header'] else 0
for row_idx, row in enumerate(data, row_idx_start):
table += '<tr>'
first = True
for col in row:
for col_idx, col in enumerate(row):
if value['first_col_is_header'] and first:
table += '<th>%s</th>' % tiny_escape(col)
table += '<th%s>%s</th>' % (get_cell_classname(meta, row_idx, col_idx), tiny_escape(col))
else:
table += '<td>%s</td>' % tiny_escape(col)
table += '<td%s>%s</td>' % (get_cell_classname(meta, row_idx, col_idx), tiny_escape(col))
first = False
table += '</tr>'
table += '</tbody></table>'
@ -89,6 +104,22 @@ class TestTableBlock(TestTableBlockRenderingBase):
self.assertHTMLEqual(result, expected)
self.assertIn('Test 2', result)
def test_table_block_aligment_render(self):
"""
Test a generic render with some cells aligned.
"""
value = {'first_row_is_table_header': True, 'first_col_is_header': False,
'cell': [{'row': 0, 'col': 1, 'className': 'htLeft'},
{'row': 1, 'col': 1, 'className': 'htRight'}],
'data': [['Test 1', 'Test 2', 'Test 3'], [None, None, None],
[None, None, None]]}
block = TableBlock()
result = block.render(value)
expected = get_test_html_from_value(value)
self.assertHTMLEqual(result, expected)
self.assertIn('Test 2', result)
def test_render_empty_table(self):
"""
An empty table should render okay.