0

I am new to Flask and html, but I am trying to build a project for golf stats. I am at the very beginning, and I have been searching a lot for this but have not found anything that works. Pretty sure it is something simple but again I am very new to html stuff.

I ask the user what course he has played, how many holes (18 holes, front nine, back nine, other) and display the scorecard accordingly. (I apologize in advance, some variables are named in French, others in English, I did not change them manually not to forget any. Hope you get it anyways.)

Here is my home.html file where I request information

<form action="{{ url_for("partie") }}" method="POST">
    <table>
        <tr>
            <td align="right">Parcours : </td>
            <td align="left"><input type="text" name="terrain" required /></td>
        </tr>
        <tr>
            <td align="right">Jalons : </td>
            <td align="right"><input type="text" name="jalon" required /></td>
        </tr>
    </table>

    <input type="radio" name="nbTrous" value="18">18 trous 
    <input type="radio" name="nbTrous" value="9f">Premier 9 trous
    <input type="radio" name="nbTrous" value="9s">Deuxième 9 trous
    <input type="radio" name="nbTrous" value="Autre">Autre 

    <br> 

    <button id="showCard" class="float-left submit-button"> 
        Entrer 
    </button> 

    <br>  

    <script type="text/javascript"> 
        document.getElementById("showCard").onclick = function(){
            location.href = "carte.html"
        } 
    </script> 
</form>

I pass all this information to a function called "partie" which goes like this

@app.route("/carte", methods=["GET", "POST"])
def partie():
    if request.method == "POST":
        terrain = request.form["terrain"]
        jalon = request.form["jalon"]

        par = allCourses[terrain]["par"]
        dist = allCourses[terrain][jalon]

        Trous = request.form["nbTrous"]
        nbTrous = int(sub(r"\D", "", Trous))

        rowTrou = "<th> Trou </th>,"
        rowDist = "<th> Distance </th>,"
        rowPar = "<th> Normale </th>,"
        rowScore = "<th> Score </th>,"

        couleur = ""
        if jalon == "black":
            couleur = "table-active"
        elif jalon == "blue":
            couleur = "table-primary"
        elif jalon == "white":
            couleur = "table-dark"
        elif jalon == "gold":
            couleur = "table-warning"

        if nbTrous == 18:
            for i in range(9):
                rowTrou += "<th> {} </th>,".format(i+1)

            rowTrou += "<th>   </th>,"
            for i in range(9,18):
                rowTrou += "<th> {} </th>,".format(i+1)
            rowTrou += "<th>    </th>,"
            rowTrou += "<th>    </th>,"

            for longueur in dist:
                rowDist += "<th> {} </th>,".format(longueur)
            for normale in par:
                rowPar += "<th> {} </th>,".format(normale)
                rowScore += "<th>  </th>,"

        else:
            if nbTrous == 9:
                if Trous == "9f":
                    for i in range(9):
                        rowTrou += "<th> {} </th>".format(i+1)
                    rowTrou += "<th>   </th>"

                    for longueur in dist[:10]:
                        rowDist += "<th> {} </th>".format(longueur)
                    for normale in par[:10]:
                        rowPar += "<th> {} </th>".format(normale)
                        rowScore += "<th>   </th>"

                elif Trous == "9s":
                    for i in range(9):
                        rowTrou += "<th> {} </th>".format(i+10)
                    rowTrou += "<th>   </th>"

                    for longueur in dist[10:-1]:
                        rowDist += "<th> {} </th>".format(longueur)
                    for normale in par[10:-1]:
                        rowPar += "<th> {} </th>".format(normale)
                        rowScore += "<th>   </th>"

            #else:
                #faire autre chose, gérer exception

        rowTrou=rowTrou.split(",")
        rowDist=rowDist.split(",")
        rowPar=rowPar.split(",")
        rowScore=rowScore.split(",")
        longList=len(rowTrou)


        return render_template("carte.html", terrain=terrain, couleur=couleur, rowTrou=rowTrou, rowDist=rowDist, rowPar=rowPar, rowScore=rowScore, nbTrous=nbTrous, longList=longList)

And I render the table in my carte.html file

<head>
    <table class="table table-bordered" id="carte">
        Carte parcours {{ terrain }}
        <thead>
            <tr>
                {% for i in range(longList) %}
                    {{ rowTrou[i]|safe }}
                {% endfor %}
            </tr>
        </thead>
        <tbody>
            <tr class={{couleur}}>
                {% for i in range(longList) %}
                    {{ rowDist[i]|safe }}
                {% endfor %}
            </tr>
            <tr>
                {% for i in range(longList) %}
                    {{ rowPar[i]|safe }}
                {% endfor %}
            </tr>
            <tr>
                {% for i in range(longList) %}
                    {{ rowScore[i]|safe }}
                {% endfor%}
            </tr>
        </tbody>
    </table>
</head>
<body>
    <form action="{{ url_for("trou") }}" method="GET">
        <button id="startGame" class="float-left submit-button"> 
            Commencer 
        </button> 
    </form>
</body>

Which would render, for example, the scorecard description for the course selection Royal on the black tee for an 18 hole round.

So far so good, but now I would like to save the scorecard as a variable and reuse it in other html files, such as /carte/hole_i and loop over all 18 holes (in this case) asking information to the user on every hole played. How can I pass the scorecard between html files? I have tried includes, extends, but it didn't work. Perhaps the best way would be to request the table by its Id, carte, and pass it to my other function asking information hole by hole. That way I would have the scorecard on top of the page, and below forms handling shot by shot informations. Being new to this, I am confused as to how to do it. Javascript function, directly in html,...

Any help is appreciated! Thank you!

Anthony
  • 53
  • 5

1 Answers1

1

I have to say that I'm not 100% sure I've got your question, but I'll do my best.

First of all, my suggestion is to not produce html code in the python router, but instead to use the templates.

That is, your template would have loops like the one below and no mixed html strings in the python file. You will be able to reuse or easily adapt the function if it just retrieves the data and passes it as parameter to the template engine.

{% for i in range(longList) %}
        <th>{{ rowTrou[i]|safe }}</th>
{% endfor %}

Reaching your question, there are many ways to implement it.

  • The first way, is to simply expose the data via an API and then build the table via javascript
  • The second way, is to copy the code for the table in a separate file and include it in your new page (see SO jinja include file. You will still have to pass the data to the template, but it's a simple and modular way of achieving your goal. Below an example of how your code would become

partie file

@app.route("/carte", methods=["GET", "POST"])
def partie():
    ...
    return render_template("my_scoreboard.html", terrain=terrain, couleur=couleur, rowTrou=rowTrou, rowDist=rowDist, rowPar=rowPar, rowScore=rowScore, nbTrous=nbTrous, longList=longList)

my_scoreboard.html

{% include "carte.html" %}
<form>
Ask here for each single score
</form>
lsabi
  • 3,641
  • 1
  • 14
  • 26
  • Thank you it works fine! I didn't think of including it without rendering it first. That way, in the 'my_scoreboard.html' I can go through the forms upon button click, iterate through 18 holes and verify information before asking for the next hole? – Anthony Jun 09 '20 at 23:59
  • Yes, just change the action of the form. See https://www.w3schools.com/js/js_validation.asp – lsabi Jun 10 '20 at 07:00