'How to get row data on form submission when the cell is not an input field

I am working on problem set 9 (Finance) and trying to add my personal touch (allow users to buy more shares or sell shares of a stock they already own via index itself, without having to type stocks' symbols manually). That being said, I have the following HTML:

{% extends "layout.html" %}

{% block title %}
    Portfolio
{% endblock %}

{% block main %}
        <table class="table table-striped center">
            <thead>
                <tr>
                    <th class="text-start">Symbol</th>
                    <th class="text-start">Name</th>
                    <th class="text-end">Shares</th>
                    <th class="text-end">Price</th>
                    <th class="text-end">TOTAL</th>
                    <th class="text-middle">Buy/Sell</th>
                </tr>
            </thead>
            <tbody>
                {% for stock in stocks %}
                <form action="/" method="post">
                    <tr id="stock_{{ loop.index }}">
                        <td class="text-start" name="symbol" id="symbol">{{ stock["symbol"] }}</td>
                        <td class="text-start">{{ stock["name"] }}</td>
                        <td class="text-end">{{ stock["shares"] }}</td>
                        <td class="text-end">{{ stock["price"] | usd }}</td>
                        <td class="text-end">{{ ((stock["price"]) * (stock["shares"])) | usd }}</td>
                        <td class="text-middle">
                            <input type="number" min="1" name="shares" placeholder="shares" style="width:80px">
                            <button type="submit" name="action" value="sell" class="btn btn-primary button">Sell</button>
                            <button type="submit" name="action" value="buy" class="btn btn-primary button">Buy</button>
                        </td>
                    </tr>
                </form>
                {% endfor %}
            </tbody>
            <tfoot>
                <tr>
                    <td colspan="4" class="text-end"><b>Cash</b></td>
                    <td class="text-end">{{ cash[0]["cash"] | usd }}</td>
                </tr>
                <tr>
                    <td colspan="4" class="text-end"><b>TOTAL</b></td>
                    <td class="text-end">{{ total | usd }}</td>
                </tr>
            </tfoot>
        </table>
        <script>
            document.querySelector("form")addEventListener("submit", function() }
                let value = getElementById("#symbol");
                console.log(value);
                alert(value);
            )};
        </script>
{% endblock %}

That will create the following webpage: enter image description here

My tables are dynamically generated via a list of dictionaries called stocks that is passed in from my app.py controller. I feel it was easiest to put a form submission on each table row and not the table as a whole so I can know which row was actually submitted when the buy or sell button was clicked. I do not know how to pass the data from a cell that is not an input field, in this case <td class="text-start" name="symbol" id="symbol">{{ stock["symbol"] }}</td> so that I can use that information on the server-side to be able to get all other relevant information about the stock. I get a TypeError: quote_from_bytes() expected bytes from my code here for the line request.form.get("symbol"):

@app.route("/", methods=["POST", "GET"])
@login_required
def index():
    """Show portfolio of stocks"""

    # Get users cash balance
    cash = db.execute("SELECT cash FROM users WHERE id = ?", session["user_id"])
    total = cash[0]["cash"]

    # Make sure stocks table exists (will only be applicable until first stock purchase on site)
    if (db.execute("SELECT name FROM sqlite_master WHERE type = ? AND name = ?", "table", "stocks")):

        if request.method == "POST":
            # Run checks on input
            if not request.form.get("shares"):
                return apology("Missing shares")
            if int(request.form.get("shares")) < 1:
                return apology("Please input positive shares")

            # Look up stocks current price
            shares = float(request.form.get("shares"))
            print(shares)
            stock = lookup(request.form.get("symbol"))
            print(stock)
            price = float(stock["price"])
            print(price)

I believe grabbing request.form.get("symbol") doesn't make sense since its not part of the form data? Is there anyway to get the value in that cell to pass to my server-side? And yes the JavaScript at the end was an attempt to try and grab that data to maybe modify a value upon submission that I could then use, but I am not sure.



Solution 1:[1]

Thank you to the comments I have figured this out. I realize this wasnt the best asked question. I have implemented another readonly field and adjusted the form to be for the single cell as follows:

   <tbody>
        {% for stock in stocks %}
            <tr id="stock_{{ loop.index }}">
                <td class="text-start">{{ stock["symbol"] }}</td>
                <td class="text-start">{{ stock["name"] }}</td>
                <td class="text-end">{{ stock["shares"] }}</td>
                <td class="text-end">{{ stock["price"] | usd }}</td>
                <td class="text-end">{{ ((stock["price"]) * (stock["shares"])) | usd }}</td>
                <td class="text-middle">
                    <form action="/" method="post">
                    <input type="number" min="1" name="shares" placeholder="shares" style="width:80px">
                    <input type="text" readonly name="symbol" value="{{ stock['symbol'] }}" style="width:80px">
                    <button type="submit" name="action" value="sell" class="btn btn-primary button">Sell</button>
                    <button type="submit" name="action" value="buy" class="btn btn-primary button">Buy</button>
                    </form>
                </td>
            </tr>
        {% endfor %}
    </tbody>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Duke3e33