kopia lustrzana https://github.com/wagtail/wagtail
Add support for aligment classes from HandsOnTable
rodzic
31d010cfc6
commit
7402210f35
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 ''
|
|
@ -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.
|
||||
|
|
Ładowanie…
Reference in New Issue