Pārlūkot izejas kodu

Add caption field to TableBlock

* Create caption field added to table block widget

Caption allows for users users with screen readers to be
able to understand the contents of a table.

* Fixed bugs in javascript and typos

* Updated documentation and change log

* Fixed table caption bug and requested pr edits

* Fixed table caption bug and request pr edits

* Removed changes in changelog.txt

* Fixed bug and requested PR edits
rjpruitt16 5 gadi atpakaļ
vecāks
revīzija
f7ff6d39c4

BIN
docs/_static/images/screen40_table_block.png


+ 2 - 2
docs/reference/contrib/table_block.rst

@@ -2,7 +2,7 @@
 TableBlock
 ==========
 
-The TableBlock module provides an HTML table block type for StreamField. This module uses `handsontable 6.2.2 <https://handsontable.com/>`_ to provide users with the ability to create and edit HTML tables in Wagtail.
+The TableBlock module provides an HTML table block type for StreamField. This module uses `handsontable 6.2.2 <https://handsontable.com/>`_ to provide users with the ability to create and edit HTML tables in Wagtail. Table blocks provides a caption field for accessibility.
 
 .. image:: ../../_static/images/screen40_table_block.png
 
@@ -83,7 +83,7 @@ Every key in the ``table_options`` dictionary maps to a `handsontable <https://h
 * `startCols <https://handsontable.com/docs/6.2.2/Options.html#startCols>`_ - The default number of columns for new tables.
 * `colHeaders <https://handsontable.com/docs/6.2.2/Options.html#colHeaders>`_ - Can be set to ``True`` or ``False``. This setting designates if new tables should be created with column headers. **Note:** this only sets the behaviour for newly created tables. Page editors can override this by checking the the “Column header” checkbox in the table editor in the Wagtail admin.
 * `rowHeaders <https://handsontable.com/docs/6.2.2/Options.html#rowHeaders>`_ - Operates the same as ``colHeaders`` to designate if new tables should be created with the first column as a row header. Just like ``colHeaders`` this option can be overridden by the page editor in the Wagtail admin.
-* `contextMenu <https://handsontable.com/docs/6.2.2/Options.html#contextMenu>`_ - Enables or disables the Handsontable right-click menu. By default this is set to ``True``. Alternatively you can provide a list or a dictionary with [specific options](https://handsontable.com/docs/6.2.2/demo-context-menu.html#page-specific). 
+* `contextMenu <https://handsontable.com/docs/6.2.2/Options.html#contextMenu>`_ - Enables or disables the Handsontable right-click menu. By default this is set to ``True``. Alternatively you can provide a list or a dictionary with [specific options](https://handsontable.com/docs/6.2.2/demo-context-menu.html#page-specific).
 * `editor <https://handsontable.com/docs/6.2.2/Options.html#editor>`_ - Defines the editor used for table cells. The default setting is text.
 * `stretchH <https://handsontable.com/docs/6.2.2/Options.html#stretchH>`_ - Sets the default horizontal resizing of tables. Options include, 'none', 'last', and 'all'. By default TableBlock uses 'all' for the even resizing of columns.
 * `height <https://handsontable.com/docs/6.2.2/Options.html#height>`_ - The default height of the grid. By default TableBlock sets the height to ``108`` for the optimal appearance of new tables in the editor. This is optimized for tables with ``startRows`` set to ``3``. If you change the number of ``startRows`` in the configuration, you might need to change the ``height`` setting to improve the default appearance in the editor.

+ 7 - 0
wagtail/contrib/table_block/blocks.py

@@ -43,7 +43,12 @@ class TableInput(forms.HiddenInput):
 
     def get_context(self, name, value, attrs=None):
         context = super().get_context(name, value, attrs)
+        table_caption = ''
+        if value and value != 'null':
+            table_caption = json.loads(value).get('table_caption', '')
         context['widget']['table_options_json'] = json.dumps(self.table_options)
+        context['widget']['table_caption'] = table_caption
+
         return context
 
 
@@ -59,6 +64,7 @@ class TableBlock(FieldBlock):
         """
         self.table_options = self.get_table_options(table_options=table_options)
         self.field_options = {'required': required, 'help_text': help_text}
+
         super().__init__(**kwargs)
 
     @cached_property
@@ -97,6 +103,7 @@ class TableBlock(FieldBlock):
                 'table_header': table_header,
                 'first_col_is_header': first_col_is_header,
                 'html_renderer': self.is_html_renderer(),
+                'table_caption': value.get('table_caption'),
                 'data': value['data'][1:] if table_header else value.get('data', [])
             })
 

+ 12 - 1
wagtail/contrib/table_block/static/table_block/js/table.js

@@ -4,9 +4,11 @@ function initTable(id, tableOptions) {
     var containerId = id + '-handsontable-container';
     var tableHeaderCheckboxId = id + '-handsontable-header';
     var colHeaderCheckboxId = id + '-handsontable-col-header';
+    var tableCaptionId = id + '-handsontable-col-caption';
     var hiddenStreamInput = $('#' + id);
     var tableHeaderCheckbox = $('#' + tableHeaderCheckboxId);
     var colHeaderCheckbox = $('#' + colHeaderCheckboxId);
+    var tableCaption = $('#' + tableCaptionId);
     var hot;
     var defaultOptions;
     var finalOptions = {};
@@ -18,6 +20,7 @@ function initTable(id, tableOptions) {
     var structureEvent;
     var dataForForm = null;
     var isInitialized = false;
+
     var getWidth = function() {
         return $('.widget-table_input').closest('.sequence-member-inner').width();
     };
@@ -55,6 +58,9 @@ function initTable(id, tableOptions) {
         if (dataForForm.hasOwnProperty('first_col_is_header')) {
             colHeaderCheckbox.prop('checked', dataForForm.first_col_is_header);
         }
+        if (dataForForm.hasOwnProperty('table_caption')) {
+            tableCaption.prop('value', dataForForm.table_caption);
+        }
     }
 
     if (!tableOptions.hasOwnProperty('width') || !tableOptions.hasOwnProperty('height')) {
@@ -88,7 +94,8 @@ function initTable(id, tableOptions) {
             data: hot.getData(),
             cell: getCellsClassnames(),
             first_row_is_table_header: tableHeaderCheckbox.prop('checked'),
-            first_col_is_header: colHeaderCheckbox.prop('checked')
+            first_col_is_header: colHeaderCheckbox.prop('checked'),
+            table_caption: tableCaption.val()
         }));
     };
 
@@ -123,6 +130,10 @@ function initTable(id, tableOptions) {
         persist();
     });
 
+    tableCaption.on('change', function() {
+        persist();
+    });
+
     defaultOptions = {
         afterChange: cellEvent,
         afterCreateCol: structureEvent,

+ 3 - 0
wagtail/contrib/table_block/templates/table_block/blocks/table.html

@@ -1,6 +1,9 @@
 {% load table_block_tags %}
 
 <table>
+    {% if table_caption %}
+       <caption>{{ table_caption }}</caption>
+    {% endif %}
     {% if table_header %}
         <thead>
         <tr>

+ 10 - 0
wagtail/contrib/table_block/templates/table_block/widgets/table.html

@@ -19,6 +19,16 @@
     </div>
 </div>
 <br/>
+<div class="field">
+    <label for="{{ widget.attrs.id }}-handsontable-col-caption">{% trans 'Table caption' %}</label>
+    <div class="field-content">
+        <div class="input">
+          <input type="text" id="{{ widget.attrs.id }}-handsontable-col-caption" name="handsontable-col-caption" value="{{ widget.table_caption }}"/>
+        </div>
+        <p class="help">{% trans 'A heading that identifies the overall topic of the table, and is useful for screen reader users' %}</p>
+    </div>
+</div>
+<br/>
 <div id="{{ widget.attrs.id }}-handsontable-container"></div>
 {% include 'django/forms/widgets/hidden.html' %}
 <script>initTable("{{ widget.attrs.id|escapejs }}", {{ widget.table_options_json|safe }});</script>

+ 24 - 0
wagtail/contrib/table_block/tests.py

@@ -241,6 +241,30 @@ class TestTableBlock(TestCase):
         self.assertIn("<div>A fascinating table.</div>", result)
 
 
+    def test_table_block_caption_render(self):
+        """
+        Test a generic render with caption.
+        """
+        value = {'table_caption': 'caption', 'first_row_is_table_header': False,
+                 'first_col_is_header': False,
+                 'data': [['Test 1', 'Test 2', 'Test 3'], [None, None, None],
+                          [None, None, None]]}
+        block = TableBlock()
+        result = block.render(value)
+        expected = """
+            <table>
+                <caption>caption</caption>
+                <tbody>
+                    <tr><td>Test 1</td><td>Test 2</td><td>Test 3</td></tr>
+                    <tr><td></td><td></td><td></td></tr>
+                    <tr><td></td><td></td><td></td></tr>
+                </tbody>
+            </table>
+        """
+        self.assertHTMLEqual(result, expected)
+        self.assertIn('Test 2', result)
+
+
 class TestTableBlockForm(WagtailTestUtils, SimpleTestCase):
 
     def setUp(self):