0

I want to add buttons to a table, like the "Edit" and "Delete" buttons in the image below.

enter image description here

I currently have this:

enter image description here

server_table.py

@app.route('/')
def index():
    return render_template('server_table.html', title='Recipes')


@app.route('/api/data')
def data():
    query = Recipe.query

    # search filter
    search = request.args.get('search[value]')
    if search:
        query = query.filter(db.or_(
            Recipe.name.like(f'%{search}%'),
            Recipe.ingredients_str.like(f'%{search}%')
        ))
    total_filtered = query.count()

    # sorting
    order = []
    i = 0
    while True:
        col_index = request.args.get(f'order[{i}][column]')
        if col_index is None:
            break
        col_name = request.args.get(f'columns[{col_index}][data]')
        if col_name not in ['name', 'ingredients_str', 'cook_time']:
            col_name = 'name'
        descending = request.args.get(f'order[{i}][dir]') == 'desc'
        col = getattr(Recipe, col_name)
        if descending:
            col = col.desc()
        order.append(col)
        i += 1
    if order:
        query = query.order_by(*order)

    # pagination
    start = request.args.get('start', type=int)
    length = request.args.get('length', type=int)
    query = query.offset(start).limit(length)

    # response
    return {
        'data': [recipe.to_dict() for recipe in query],
        'recordsFiltered': total_filtered,
        'recordsTotal': Recipe.query.count(),
        'draw': request.args.get('draw', type=int),
    }

and server_table.html:

{% extends "base.html" %}

{% block content %}
  <table id="data" class="table table-striped">
    <thead>
      <tr>
        <th>Recipe Name</th>
        <th>Ingredients</th>
        <th>Cook Time (Mins)</th>
        <th> </th>
      </tr>
    </thead>
    <tbody>
    </tbody>
  </table>
{% endblock %}

{% block scripts %}
  <script>
    $(document).ready(function () {
      $('#data').DataTable({
        ajax: '/api/data',
        serverSide: true,
        columns: [
          {data: 'name'},
          {data: 'ingredients_str', orderable: false},
          {data: 'cook_time', orderable: false}
        ],
      });
    });
  </script>
{% endblock %}

I'm a total newbie to Flask etc, so I just don't even know where to start. There are a couple similar questions on this site but I couldn't find any for Flask in particular. Most of my code is copied from this tutorial.

AWhite
  • 75
  • 7
  • 1
    Does this answer your question? [How do I add button on each row in datatable?](https://stackoverflow.com/questions/22471862/how-do-i-add-button-on-each-row-in-datatable) – andrewJames Aug 07 '22 at 21:22
  • As well as the proposed duplicate question, you can take a look at [more examples](https://www.google.com/search?q=datatables+add+a+button+to+a+column) for different solutions - but using the [`columns.render`](https://datatables.net/reference/option/columns.render) function `"render": function ( data, type, row, meta ) { ... }` is a good start. – andrewJames Aug 07 '22 at 21:26

1 Answers1

1

One possibility is to do this:

<script>
    $(document).ready(function () {
      $('#data').DataTable({
        ajax: '/api/data',
        serverSide: true,
        columns: [
          {data: 'name'},
          {data: 'ingredients_str', orderable: false},
          {data: 'cook_time', orderable: false},
          {
           "orderable": false,
           "data": null,
           "defaultContent": '<a class="btn btn-primary edit"> Edit </a>'+
                             '<br/>'+
                             '<a class="btn btn-danger delete"> Delete </a>'
           },
        ],
      });
    });
  </script>
Tobin
  • 2,029
  • 2
  • 11
  • 19
  • This works great, thanks! Now though I'm wondering how to add onclick events to these buttons; do I need to put them in a form as in [this question](https://stackoverflow.com/questions/42601478/flask-calling-python-function-on-button-onclick-event)? – AWhite Aug 08 '22 at 15:22
  • Not necessarily. you can use AJAX as suggested by @Gihan Gamage in his answer – Tobin Aug 09 '22 at 10:36