简体   繁体   中英

How to pass checkbox values to modal bootstrap for Python Flask remove data from mysql table?

Environment:

Python 3.7.7 Flask 1.1.2 Werkzeug 1.0.1

Introduction:

I am making a Flask application for my saas dashboard. I have a page "categories.html" which displays a list of categories in a table. Each category has a checkbox if the user wants to delete several categories by checking the categories and clicking on the "DELETE" button. See screenshot below: 在此处输入图片说明

So users will be able to select multiple categories and remove them by clicking on the "DELETE" button. But before to delete the rows in Mysql table categories, a confirmation popup is showing up. This popup is done by Bootstrap modal.

Problem:

I don't how to pass the list of checkbox values selected by the user to the modal popup.

What did I try:

I tried to fix this issue with some javascript code, but it doesn't work.

My code:

My template categories.html (I removed unecessary code):

<form>
<table id="categories" class="table dataTable no-footer" role="grid">
                                  <thead>
                                    <tr role="row">
                                        <th tabindex="0" rowspan="1" colspan="1" style="white-space: nowrap"></th>
                                        
                                    </tr>
                                  </thead>
                                  <tbody>
                                    {% for category in categories %}
                                        <tr role="row" >
                                            <td  style="white-space: nowrap">
                                                    <input name="category_id" value="{{ category.ID }}" type="checkbox" class="form-check-input" style="float: left;  margin: 0 auto;">
                                            </td>
                                            <td><a href="{{ url_for('edit_category', category_id=category.ID)}}">{{ category.name }}</a></td>
                                            <td style="white-space: nowrap">
                                                {% if category.icon %}
                                                    {% if category.icon.find('<i class')!=-1 %}
                                                       {{ category.icon|safe }}
                                                    {% else %}
                                                        <img src="{{ url_for('static', filename='images/<category.icon>') }}">
                                                    {% endif %}
                                                {% else %}
                                                    na
                                                {% endif %}
                                            </td>
                                             
                                        </tr>
                                    {% endfor %}

                                    </tr></tbody>
                                </table>
</form>


    <!-- Modal -->
    <div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel" aria-hidden="true">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title" id="deleteModalLabel">Delete Category</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            Are you sure you want to delete these categories?
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
            <form action="{{ url_for('delete_category')}}" method="POST">
                <input name="category_id" type="hidden" value="pass_checkedvalue" id="hidden_checkedinput">

                <input class="btn btn-danger" type="submit" value="delete"/>
            </form>
          </div>
        </div>
      </div>
    </div>
            <script>
           $('#deleteModal').on('show.bs.modal', function(e) {
              var checkedValues = $('.record:checked').map(function(){ return this.value; }).get();
              //put the ids in the hidden input as a comma separated string
              $('#hidden_checkedinput').val(checkedValues.join(','));
            });
    </script>

My route.py:

@app.route('/delete_category', methods=['GET', 'POST'])
@login_required
def delete_category():

    if request.method == "POST":
        if request.form["category_id"]:
            print(request.form["category_id"])

            Category.query.filter(Category.ID.in_(request.form["category_id"])).delete()
            db_mysql.session.commit()
            flash('The categories have been deleted', 'success')
            return redirect(url_for('categories'))

My models.py:

class Category(db_mysql.Model):
    __tablename__ = "W551je5v_pb_categories"
    ID = db_mysql.Column('ID', db_mysql.Integer, primary_key=True)
    name = db_mysql.Column('name', db_mysql.Unicode)
    icon = db_mysql.Column('icon', db_mysql.Unicode)
    icon_blue_img = db_mysql.Column('icon_blue_img', db_mysql.Unicode)
    icon_white_img = db_mysql.Column('icon_white_img', db_mysql.Unicode)
    icon_black_img = db_mysql.Column('icon_black_img', db_mysql.Unicode)
    platforms = db_mysql.relationship('Platform', backref='W551je5v_pb_categories', lazy=True)

    def __repr__(self):
        return f"Category('{self.ID}','{self.name}','{self.icon}','{self.icon_blue_img}','{self.icon_white_img}','{self.icon_black_img}')"

OUTPUT:

When I execute this code, I get this error message:

sqlalchemy.exc.InvalidRequestError
sqlalchemy.exc.InvalidRequestError: Could not evaluate current criteria in Python: "Cannot evaluate clauselist with operator <function comma_op at 0x0000026EB4542558>". Specify 'fetch' or False for the synchronize_session parameter.

And the print(request.form["category_id"]) showed in console:

pass_checkedvalue

Which is the value of my hidden field.

I have no idea what am I doing wrong. Can anyone help me, please?

I don't how to pass the list of checkbox values selected by the user to the modal popup.

I don't think that's the right approach.
Actually, I don't think you need to pass ANY data to the modal popup.
What I would instead do is add an on-click for the modal button that would run a javascript function.
That function needs to simply iterate over the <tr> tags and find the checked rows.
After you have a list containing the checked rows' IDs, you can send that to your backend via some HTTP request (you can use Javascript's FETCH API for that).
Your code would like something like that (please treat this as a schema since I don't actually know how your HTML looks like):

let checked_arr = [];
let tr_lst = document.getElementsByTagName('tr'); // probably better to be done with getElementsByClassName
for (let i=0; i<tr_lst.length; i++) {
    let checkbox_td = tr_lst[i].children[0]; // assuming first <td> is the checkbox 
    let checkbox_element = checkbox_td.children[0]; // assuming your HTML looks like <td><input type="checkbox"...></td>
    if (checkbox_element.checked) {
        checked_arr.push(tr_lst[i].id);
    }
}
let response = await fetch('/your_api_endpoint', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  },
  body: JSON.stringify({"data": checked_arr})
});

Also, here is a nice tutorial on how to use FETCH API: https://javascript.info/fetch

Hope that's helpful :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM