Skip to content

Commit

Permalink
Added custom_actions functionality to render_table macro (#134)
Browse files Browse the repository at this point in the history
* Added custom_actions functionality

Requires import of the `render_icon` macro, so the conditional import logic was added before the table data loop.

* Added custom_actions to macro docs

* Added custom_actions test

Checks for the presence of the title of the anchor tag, the "bootstrap-reboot" icon, and the link.

* Outlined new render_table custom_actions parameter

* Fixed formatting of inline list

* Added the missing test route

* Fix test for render_table

* Removed date from 1.6.1 release notes

* Adjusted for flake8

* Reduced line-length to satisfy flake8

Co-authored-by: Grey Li <[email protected]>
  • Loading branch information
caffeinatedMike and greyli authored Jun 3, 2021
1 parent 2456e94 commit 3ca1aa9
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Release date: -

Release date: -

- Add a ``custom_actions`` parameter for the ``render_table`` macro. When passing a list of tuples ``[(title, bootstrap icon, link)]`` to the ``custom_actions`` parameter, the ``render_table`` macro will create an icon (link) on the action header for each tuple in the list. The title text (first index of each tuple) will show when hovering over each ``custom_actions`` button.


1.6.0
-----
Expand Down
4 changes: 4 additions & 0 deletions docs/macros.rst
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ API
responsive_class='table-responsive',\
show_actions=False,\
actions_title='Actions',\
custom_actions=None,\
view_url=None,\
edit_url=None,\
delete_url=None,\
Expand All @@ -451,6 +452,9 @@ API
:param responsive_class: The responsive class to apply to the table. Default is ``'table-responsive'``.
:param show_actions: Whether to display the actions column. Default is ``False``.
:param actions_title: Title for the actions column header. Default is ``'Actions'``.
:param custom_actions: A list of tuples for creating custom action buttons, where each tuple contains
('Title Text displayed on hover', 'bootstrap icon name', 'url_for()')
(e.g.``[('Run', 'play-fill', url_for('run_report', report_id=':primary_key'))]``).
:param view_url: URL to use for the view action.
:param edit_url: URL to use for the edit action.
:param delete_url: URL to use for the delete action.
Expand Down
12 changes: 12 additions & 0 deletions flask_bootstrap/templates/bootstrap/table.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
responsive_class='table-responsive',
show_actions=False,
actions_title='Actions',
custom_actions=None,
view_url=None,
edit_url=None,
delete_url=None,
Expand Down Expand Up @@ -37,6 +38,9 @@
</tr>
</thead>
<tbody>
{% if custom_actions %}
{% from 'bootstrap/utils.html' import render_icon %}
{% endif %}
{% for row in data %}
<tr>
{% for title in titles %}
Expand All @@ -48,6 +52,14 @@
{% endfor %}
{% if show_actions %}
<td>
{% if custom_actions %}
{% for (action_name, action_icon, action_url) in custom_actions %}
<a style="font-size: 18px;"
class="text-dark text-decoration-none"
href="{{ action_url | replace(action_pk_placeholder, row[primary_key]) }}"
title="{{ action_name }}">{{ render_icon(action_icon) }}</a>
{% endfor %}
{% endif %}
{% if view_url %}
<a href="{{ view_url | replace(action_pk_placeholder, row[primary_key]) }}"><img src="{{ url_for('bootstrap.static', filename='img/view.svg') }}" alt="View"></a>
{% endif %}
Expand Down
20 changes: 15 additions & 5 deletions tests/test_render_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ class Message(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.Text)

@app.route('/table/<message_id>/resend')
def test_resend_message(message_id):
return 'Re-sending {}'.format(message_id)

@app.route('/table/<message_id>/view')
def test_view_message(message_id):
return 'Viewing {}'.format(message_id)
Expand All @@ -169,14 +173,20 @@ def test():
messages = pagination.items
titles = [('id', '#'), ('text', 'Message')]
return render_template_string('''
{% from 'bootstrap/table.html' import render_table %}
{{ render_table(messages, titles, show_actions=True,
view_url=url_for('test_view_message', message_id=':primary_key'),
new_url=url_for('test_create_message')) }}
''', titles=titles, messages=messages)
{% from 'bootstrap/table.html' import render_table %}
{{ render_table(messages, titles, show_actions=True,
custom_actions=[
('Resend', 'bootstrap-reboot', url_for('test_resend_message', message_id=':primary_key'))
],
view_url=url_for('test_view_message', message_id=':primary_key'),
new_url=url_for('test_create_message')) }}
''', titles=titles, messages=messages)

response = client.get('/table')
data = response.get_data(as_text=True)
assert 'icons/bootstrap-icons.svg#bootstrap-reboot' in data
assert 'href="/table/1/resend"' in data
assert 'title="Resend">' in data
assert '<a href="/table/1/view">' in data
assert '<a href="/table/new-message">' in data
assert '<img src="/bootstrap/static/img/new.svg" alt="New">' in data

0 comments on commit 3ca1aa9

Please sign in to comment.