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(),
|
'html_renderer': self.is_html_renderer(),
|
||||||
'data': value['data'][1:] if table_header else value.get('data', [])
|
'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)
|
return render_to_string(template, new_context)
|
||||||
else:
|
else:
|
||||||
return self.render_basic(value, context=context)
|
return self.render_basic(value, context=context)
|
||||||
|
|
|
@ -10,10 +10,14 @@ function initTable(id, tableOptions) {
|
||||||
var hot;
|
var hot;
|
||||||
var defaultOptions;
|
var defaultOptions;
|
||||||
var finalOptions = {};
|
var finalOptions = {};
|
||||||
|
var getCellsClassnames;
|
||||||
var persist;
|
var persist;
|
||||||
var cellEvent;
|
var cellEvent;
|
||||||
|
var metaEvent;
|
||||||
|
var initEvent;
|
||||||
var structureEvent;
|
var structureEvent;
|
||||||
var dataForForm = null;
|
var dataForForm = null;
|
||||||
|
var isInitialized = false;
|
||||||
var getWidth = function() {
|
var getWidth = function() {
|
||||||
return $('.widget-table_input').closest('.sequence-member-inner').width();
|
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() {
|
persist = function() {
|
||||||
hiddenStreamInput.val(JSON.stringify({
|
hiddenStreamInput.val(JSON.stringify({
|
||||||
data: hot.getData(),
|
data: hot.getData(),
|
||||||
|
cell: getCellsClassnames(),
|
||||||
first_row_is_table_header: tableHeaderCheckbox.prop('checked'),
|
first_row_is_table_header: tableHeaderCheckbox.prop('checked'),
|
||||||
first_col_is_header: colHeaderCheckbox.prop('checked')
|
first_col_is_header: colHeaderCheckbox.prop('checked')
|
||||||
}));
|
}));
|
||||||
|
@ -80,6 +101,16 @@ function initTable(id, tableOptions) {
|
||||||
persist();
|
persist();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
metaEvent = function(row, column, key, value) {
|
||||||
|
if (isInitialized && key === 'className') {
|
||||||
|
persist();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
initEvent = function() {
|
||||||
|
isInitialized = true;
|
||||||
|
};
|
||||||
|
|
||||||
structureEvent = function(index, amount) {
|
structureEvent = function(index, amount) {
|
||||||
resizeHeight(getHeight());
|
resizeHeight(getHeight());
|
||||||
persist();
|
persist();
|
||||||
|
@ -99,12 +130,19 @@ function initTable(id, tableOptions) {
|
||||||
afterCreateRow: structureEvent,
|
afterCreateRow: structureEvent,
|
||||||
afterRemoveCol: structureEvent,
|
afterRemoveCol: structureEvent,
|
||||||
afterRemoveRow: structureEvent,
|
afterRemoveRow: structureEvent,
|
||||||
|
afterSetCellMeta: metaEvent,
|
||||||
|
afterInit: initEvent,
|
||||||
// contextMenu set via init, from server defaults
|
// 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
|
// 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) {
|
Object.keys(defaultOptions).forEach(function (key) {
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
{% load table_block_tags %}
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
{% if table_header %}
|
{% if table_header %}
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{% for column in table_header %}
|
{% for column in table_header %}
|
||||||
<th>
|
{% with forloop.counter0 as col_index %}
|
||||||
|
<th {% cell_classname 0 col_index %}>
|
||||||
{% if column.strip %}
|
{% if column.strip %}
|
||||||
{% if html_renderer %}
|
{% if html_renderer %}
|
||||||
{{ column.strip|safe|linebreaksbr }}
|
{{ column.strip|safe|linebreaksbr }}
|
||||||
|
@ -12,16 +15,19 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</th>
|
</th>
|
||||||
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for row in data %}
|
{% for row in data %}
|
||||||
|
{% with forloop.counter0 as row_index %}
|
||||||
<tr>
|
<tr>
|
||||||
{% for column in row %}
|
{% for column in row %}
|
||||||
|
{% with forloop.counter0 as col_index %}
|
||||||
{% if first_col_is_header and forloop.first %}
|
{% if first_col_is_header and forloop.first %}
|
||||||
<th>
|
<th {% cell_classname row_index col_index table_header %}>
|
||||||
{% if column.strip %}
|
{% if column.strip %}
|
||||||
{% if html_renderer %}
|
{% if html_renderer %}
|
||||||
{{ column.strip|safe|linebreaksbr }}
|
{{ column.strip|safe|linebreaksbr }}
|
||||||
|
@ -31,7 +37,7 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</th>
|
</th>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td>
|
<td {% cell_classname row_index col_index table_header %}>
|
||||||
{% if column.strip %}
|
{% if column.strip %}
|
||||||
{% if html_renderer %}
|
{% if html_renderer %}
|
||||||
{{ column.strip|safe|linebreaksbr }}
|
{{ column.strip|safe|linebreaksbr }}
|
||||||
|
@ -41,8 +47,10 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
|
{% endwith %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</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
|
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):
|
def tiny_escape(val):
|
||||||
"""
|
"""
|
||||||
Helper function used in building a test html
|
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.
|
that's what we expect from the TableBlock.
|
||||||
"""
|
"""
|
||||||
data = list(value['data']) # Make a copy
|
data = list(value['data']) # Make a copy
|
||||||
|
meta = value.get('cell')
|
||||||
table = '<table>'
|
table = '<table>'
|
||||||
if value['first_row_is_table_header']:
|
if value['first_row_is_table_header']:
|
||||||
row_header = data.pop(0)
|
row_header = data.pop(0)
|
||||||
table += '<thead><tr>'
|
table += '<thead><tr>'
|
||||||
for th in row_header:
|
for col_idx, th in enumerate(row_header):
|
||||||
table += '<th>%s</th>' % tiny_escape(th)
|
table += '<th%s>%s</th>' % (get_cell_classname(meta, 0, col_idx), tiny_escape(th))
|
||||||
table += '</tr></thead>'
|
table += '</tr></thead>'
|
||||||
table += '<tbody>'
|
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>'
|
table += '<tr>'
|
||||||
first = True
|
first = True
|
||||||
for col in row:
|
for col_idx, col in enumerate(row):
|
||||||
if value['first_col_is_header'] and first:
|
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:
|
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
|
first = False
|
||||||
table += '</tr>'
|
table += '</tr>'
|
||||||
table += '</tbody></table>'
|
table += '</tbody></table>'
|
||||||
|
@ -89,6 +104,22 @@ class TestTableBlock(TestTableBlockRenderingBase):
|
||||||
self.assertHTMLEqual(result, expected)
|
self.assertHTMLEqual(result, expected)
|
||||||
self.assertIn('Test 2', result)
|
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):
|
def test_render_empty_table(self):
|
||||||
"""
|
"""
|
||||||
An empty table should render okay.
|
An empty table should render okay.
|
||||||
|
|
Ładowanie…
Reference in New Issue