'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:

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 |
