Search code examples
pythonhtmlflaskbootstrap-5popover

Popover on Table Cell Depending on the Value


I am currently developing a website (with Flask) that features a data table containing abbreviated codes for some values. My goal is to have a popover on these cells to have the full meaning in the popover. EG. The EXT10 cell in the HTML Table (Pic1) will have a popover on hover which contains the related value (10 min extra time) from the SQL Database (Pic2), along with the rest of the table.

HTML Table

SQL Table with code meanings

Currently, I have tried to solve this issue with the JetBrains AI, which provided this for the HTML with little success:

<tbody>
            {% for student in allstudents %}
                <tr>
                    {% for key, value in student.items() %}
                        <td>
                        {% if key in ['Adjustment1', 'Adjustment2', 'Adjustment3'] and value in adj_ref %}
                            <div data-toggle="popover" data-trigger="hover" data-content="{{ adj_ref[value] }}">
                                {{ value }}
                            </div>
                            {% else %}
                                {{ value }}
                            {% endif %}
                        </td>
                    {% endfor %}
                </tr>
            {% endfor %}
            </tbody>

I will also attach the relevant Python functions used to get the data and the relevant app.routes in my App.py

def students():
    con, c = establishcon()
    c.execute('''
    SELECT * FROM jimboombass_studentadjustments.students
    ''')
    data = c.fetchall()
    con.close()
    return [dict(zip([column[0] for column in c.description], row)) for row in data]

def adjustment_reference():
    con, c = establishcon()
    c.execute('''
        SELECT * FROM jimboombass_studentadjustments.adjustment_reference
        ''')
    data = c.fetchall()
    return dict(data)
@app.route('/students', methods=['GET', 'POST'])
def students():
    username = session.get('user_data').get("username")
    profile_pic = session.get('user_data').get("profile_pic")
    if request.method == 'POST':
        StudentID = request.form.get('StudentIDInput')
        FirstName = request.form.get('FirstNameInput')
        LastName = request.form.get('LastNameInput')
        Email = request.form.get('EmailInput')
        Homeroom = request.form.get('HomeroomInput')
        Adjustments = request.form.getlist('adjustment_select')

        data = DB_Functions.student_search(StudentID, FirstName, LastName, Email, Homeroom, Adjustments)

    else:
        data = DB_Functions.students()

    adjustment_reference = DB_Functions.adjustment_reference()

    return render_template('students.html', allstudents=data, username=username, profilepic=profile_pic, adj_ref=adjustment_reference)

Unfortunately, the AI has provided me with few working solutions, which is why I have turned to here. And before anyone asks, the required Bootstrap links and JS for the popovers are included on my base.html which is extended with Jinja codeblocks.

Any solutions or potential ideas would be greatly appreciated. Thanks


Solution

  • You need to replace data attribute with data-bs, and popovers must be initialized manually, with JavaScript (BS script must be loaded before the initializing code is used).

    Try this:

      <tbody>
      {% for student in allstudents %}
          <tr>
              {% for key, value in student.items() %}
                  <td>
                  {% if key in ['Adjustment1', 'Adjustment2', 'Adjustment3'] and value in adj_ref %}
                      <div data-bs-toggle="popover" data-bs-trigger="hover" data-bs-content="{{ adj_ref[value] }}">
                          {{ value }}
                      </div>
                      {% else %}
                          {{ value }}
                      {% endif %}
                  </td>
              {% endfor %}
          </tr>
      {% endfor %}
      </tbody>
    
      <script>
        const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]')
        const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl));
    </script>
    

    see: BS5 Popovers