Home > Back-end >  Broken modal in flask
Broken modal in flask

Time:11-19

on my page I do cms for individual chapters that I have in the menu and on the page and I want new ones to be added and those that already exist so that they can be edited. I'm just doing it via jquery and bootstrap modal dialog but it doesn't want to work every time I click edit so my modal dialog doesn't appear and I get a 404 error. When adding chapters, nothing appears there at all, no error, no message or nothing in debug mode. I need help with that. Thank you in advance for your help. PS: Deleting chapters works for me

HTML Code (updated):

{% extends "base.html" %} {% block content %}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-/bQdsTh/da6pkI1MST/rWKFNjaCP5gBSY4sEBT38Q/9RBh9AH40zEOg7Hlq2THRZ" crossorigin="anonymous"></script>

{%if session["group"] == "Admin"%}
<div class="container">
    <div class="row">
        <div class="col md-12">
            <h2>Kapitoly</h2>
                <button type="button" class="btn btn-success  pull-right" data-toggle="modal" data-target="#myModal">Přidat kapitolu</button> 
                <br>
                <br>
                {%with messages = get_flashed_messages()%}
                {%if messages%}
                {% for message in messages %}
                <div class="alert alert-success alert-dismissable" role="alert">
                    <button type="button" class="close" data-dismiss="alert" aria-label ="close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                    {{message}}
                </div>
                {%endfor%}
                {%endif%}
                {%endwith%}
                
                        <table class="table table-striped">
                        <tr>
                            <th>ID</th>
                            <th>Ročník</th>
                            <th>Název</th>
                            <th>Akce</th>
                        </tr>
                        {% for row in chapters %}
                        <tr>
                            <td>{{row.0}}</td>
                            <td>{{row.1}}</td>
                            <td>{{row.2}}</td>
                            <td>
                                <a type="button" class="btn btn-primary" data-toggle="modal" data-target="#modaledit{{row.0}}">Upravit</a>
                                <a href="/delete_chapter/{{ row.0 }}" class="btn btn-danger btn-xs" onclick="return confirm('Are You Sure For Delete?')">Smazat</a>
                            </td>
                        </tr>
                <div id="modaledit{{row.0}}" class="modal fade" role="dialog">
                <div class="modal-dialog">
                    <div class="modal-content">
                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal">&times;</button>
                            <h4 class="modal-title">Upravit kapitolu</h4>
                        </div>
                        <div class="modal-body">
                            <form action="{{ url_for('update') }}" method="POST">
                            <div class="form-group">
                                <label>Ročník:</label>
                                <input type="hidden"  name="id" value="{{row.0}}">
                                <input type="text" class="form-control" name="year" value="{{row.1}}">
                            </div>
                            <div class="form-group">
                                <label>Název:</label>
                                <input type="text" class="form-control" name="title" value="{{row.2}}">
                            </div>
                            <div class="form-group">
                                <button class="btn btn-primary" type="sbumit">Upravit</button>
                            </div>
                            </form>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                        </div>
                        <div class="back">
                            <a href="manager_chapter" type="button" class="btn btn-default" data-dismiss="modal">Vrátit se zpátky.</a>
                        </div>
                    </div>
                </div>
            </div>
            {% endfor  %}
            </table>
        </div>
    </div>
<!-- Modal -->
<div id="mymodal" class="modal fade" role="dialog">
   <div class="modal-dialog">
      <div class="modal-content">
         <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal">&times;</button>
            <h4 class="modal-title">Vytvořit kapitolu</h4>
         </div>
         <div class="modal-body">
            <form action = "/add_chapter" method="POST">
                <div class="form-group">
                  <label>Ročník:</label>
                  <input type="text" class="form-control" name="year" required="1">
                </div>
                <div class="form-group">
                  <label>Název:</label>
                  <input type="text" class="form-control" name="title" required="1">
                </div>
                <div class="form-group">
                  <button class="btn btn-primary" type="submit">Vytvořit</button>
               </div>
            </form>
         </div>
         <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
         </div>
      </div>
   </div>
</div>
{%endif%}

Flask code (updated):

@app.route("/manager_chapter")
@isLoggedIn
def manager_chapter():
    cur = mysql.connection.cursor()
    cur.execute("SELECT  * FROM chapters")
    data = cur.fetchall()
    cur.close()
    return render_template('manager_chapter.html', chapters=data, id_data=id)

@app.route("/add_chapter", methods=["POST"])
@isLoggedIn 
def add_chapter():
    if request.method == "POST":
        flash("Kapitola je uspěšně přidaná.")
        year = request.form['name']
        title = request.form['email']
        cur = mysql.connection.cursor()
        cur.execute("INSERT INTO chapters (year, title) VALUES (%s, %s)", (year, title))
        mysql.connection.commit()
        return render_template('manager_chapter.html')

@app.route('/update_chapter/<string:id_data>', methods=['POST','GET'])
@isLoggedIn
def update(id_data):
    if request.method == 'POST':
        id_data = request.form['id']
        year = request.form['year']
        title = request.form['title']
        cur = mysql.connection.cursor()
        cur.execute("""
               UPDATE chapters
               SET year=%s, title=%s
               WHERE id=%s
            """, (year, title, id_data))
        flash("Kapitola je uspěšně upravená.")
        mysql.connection.commit()
        return redirect(url_for('manager_chapter'))

@app.route('/delete_chapter/<string:id_data>', methods=['GET'])
def delete(id_data):
    flash("Kapitola je uspěšně smazána.")
    cur = mysql.connection.cursor()
    cur.execute("DELETE FROM `chapters` WHERE id=%s", (id_data,))
    mysql.connection.commit()
    return render_template('manager_chapter.html')

Example 404 error after clicking edit in one of the chapters: enter image description here

CodePudding user response:

  1. Next time, please translate your source code before posting it, if you are posting to English speakers. Based on your comments, I'm going to assume your edit button is this one
    <a href="/update_chapter/{{row.0}}" type="button" class="btn btn-primary" data-toggle="modal" data-target="#modaledit{{row.0}}">Upravit</a>

You have both an href and data-target attribute. The latter is for the modal dialog. I don't believe you can have both and have them point to different urls. According to [bootstrap][1] documentation, you should use the href link and its value should be the id of your modal target. So I think your code should be

    <a href="#modaledit{{row.0}}" type="button" class="btn btn-primary" data-toggle="modal">Upravit</a>

or

    <a type="button" class="btn btn-primary" data-toggle="modal" data-target="#modaledit{{row.0}}">Upravit</a>
  1. If we assume your modal is not being triggered because it is being seen as a straight hyperlink and so the url in the href is being triggered, it opens up a second problem. Your flask route for that url has code only for a POST. You need to add code for the GET bit. In addition, your route has a variable for id_data but that variable is not part of your route i.e. you should have
    @app.route('/update_chapter/<string:id_data>', methods=['POST','GET'])
    @isLoggedIn
    def update(id_data):

UPDATES - Based on comments by OP

  1. Your button code now calls the modal.
  2. The modal has a form and the form has a hidden field for the chapter id. Based on this, your route should now be
    @app.route('/update_chapter', methods=['POST'])
    @isLoggedIn
    def update():
       if request.method == 'POST':
           id_data = request.values.get("id", None) 
           # I prefer to use request.values.get so that I don't 
           # have to worry about if my method is a POST or GET

  [1]: https://getbootstrap.com/docs/4.1/components/modal/
  • Related