Reputation: 25
So, I have a html table in which I have some rows. Additional rows are added each time user buys something. For each row, there is a corresponding input form followed by Buy and Sell buttons.
What I want to achieve is that, if user wants to buy or sell something once again he can type in the desired quantity and perform his/her action by simply clicking on the buy or sell button from the index page. However, there are also Buy and Sell pages from where user also can perform his/her desired actions. I am using the form actions I used at Buy and Sell pages inside the index page.
Currently, it works only for the first row in the table. If user fills any other row than the first one and clicks buy or sell input form value returns null.
The questions I already looked into:
Multiple rows have multiple submit buttons, should I make a form for each button?
How do I implement Multiple Submit Buttons for a multi-row form?
Multiple submit buttons in an HTML form
This is how my site looks like: Index Page
This is my index.html:
{% extends "layout.html" %}
{% block title %}
Summary
{% endblock %}
{% block main %}
<div id="alertId" class="alert alert-warning alert-dismissible fade show" role="alert" style="display:none">
<p id="alertContentId"></p>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">Symbol</th>
<th scope="col">Shares</th>
<th scope="col">Price</th>
<th scope="col">Total</th>
<th></th>
</tr>
</thead>
<tbody>
{% for stock in ownings %}
<tr>
<td>{{ stock["symbol"].upper() }}</td>
<td>{{ stock["share_amount"] }}</td>
<td>{{ stock["price"] | usd }}</td>
<td>{{ stock["stock_total"] | usd }}</td>
<td>
<form id="action_form" method="post">
<span class="form-group">
<input id="share_quantity" autocomplete="off" autofocus class="form-control" name="shares" placeholder="Shares" type="number" min="1">
<input value="{{ stock["symbol"] }}" type="hidden" name="symbol">
</span>
<button id="btn_buy" class="btn btn-primary" type="submit" data-action="buy">Buy</button>
<button id="btn_sell" class="btn btn-primary" type="submit" data-action="sell">Sell</button>
</form>
</td>
</tr>
{% endfor %}
<tr>
<td>CASH</td>
<td></td>
<td></td>
<td>{{ cash | usd }}</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td><strong>{{ grand_total | usd}}</strong></td>
<td></td>
</tr>
</tbody>
</table>
</div>
<script src="{{url_for('static', filename='button.js')}}"></script>
{% endblock %}
This is my buy.html:
{% extends "layout.html" %}
{% block title %}
Buy
{% endblock %}
{% block main %}
<form action="/buy" method="post">
<div class="form-group">
<input autocomplete="off" autofocus class="form-control" name="symbol" placeholder="Symbol" type="text">
</div>
<div class="form-group">
<input autocomplete="off" autofocus class="form-control" name="shares" placeholder="Shares" type="number" min="1">
</div>
<button class="btn btn-primary" type="submit">Buy</button>
</form>
{% endblock %}
This is my sell.html:
{% extends "layout.html" %}
{% block title %}
Sell
{% endblock %}
{% block main %}
<form action="/sell" method="post">
<div class="form-group">
<select class="form-control" name="symbol">
<option disabled selected value="">Symbol</option>
{% for symbol in available_symbols %}
<option value="{{ symbol["symbol"] }}">{{ symbol["symbol"].upper() }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<input autocomplete="off" class="form-control" min="0" name="shares" placeholder="Shares" type="number">
</div>
<button class="btn btn-primary" type="submit">Sell</button>
</form>
{% endblock %}
This is my button.js where I try to perform the action of the user depending on the button he/she clicks, for example if user clicks buy button then I add "/buy" action to form.
$(document).ready(function() {
$("button").click(function() {
var action = $(this).data('action'); // get button's action
// var share_quantity = document.getElementById("share_quantity").value;
if (document.getElementById("share_quantity").value == "") {
alert("enter a valid value");
}
if (action == "sell") {
document.getElementById("action_form").action = "/sell"; // change form's action to sell
// document.getElementById("alertId").style.display = "block";
// document.getElementById("alertContentId").innerHTML = "You sold " +share_quantity + " amount of shares!";
} else if (action == "buy") {
document.getElementById("action_form").action = "/buy"; // change form's action to buy
}
});
});
Upvotes: 1
Views: 565
Reputation: 226
The problem is that all inputs, forms etc have the same ID's; the DOM doesn't like this. Because getElementById
finds multiple values but can only return one, it just takes the first one (which is incorrect for all but the first rows).
I recommend putting some unique ID (stock["id"]
?) and either adding a data-id
attribute with that value and selecting the correct objects based on that, or extracting that value from the name itself (you have access to the button and thus to the button ID). You would need to slightly change your code (not quite sure what the jQuery selector for startswith is, but it does exist) but that shouldn't be hard.
Alternatively (though I discourage it) you could use the data from the event to find the parent form of the button clicked and extract values from there. This is a lot harder to debug and maintain.
Upvotes: 1