I want to add specific inputs from my HTML template and add them using javascript. I have reached the part where I can add all the inputs with ('[type="number"].form-control') but I want to be able to specifiy the inputs by ID so that I can have different subtotals.
here is a print screen of what I want to acheive:
I want to add Item 1 and Item 2 and get a subtotal. Add Item 3 and 4 and 5 and get subtotal. Then add the 2 subtotals together.
<!-- language: lang-js -->
<script>
const q=(e,n=document)=>n.querySelector(e);
const qa=(e,n=document)=>n.querySelectorAll(e);
const results={};
qa('[type="number"].form-control').forEach(input=>input.addEventListener('keyup',function(e){
/* add the value against the id to the object described above */
results[ this.name ]=Number( this.value );
if( Object.keys( results ).length==2 ){
q('th#Total').textContent=[ ...Object.values( results ) ].reduce((a,v)=>a+v);
}
}));
</script>
<!-- language: lang-html -->
<table class="table table-hover text-nowrap table-borderless">
<tbody>
<tr>
<td>
<input
placeholder="Type in the Equipment and assets"
autocomplete="off"
type="text"
class="form-control"
name="item_1"
id="item_1"
{% if form.is_bound %}value="{{ form.item_1.value }}"{% endif %}/>
{% for err in form.item_1.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
<td>
<h6 style="float:left; margin-right:5px; margin-top:7px">$</h6>
<input
autocomplete="off"
type="number"
class="form-control w-25"
name="item_1_amount"
id="item_1_amount"
style="float:left"
{% if form.is_bound %}value="{{ form.item_1_amount.value }}"{% endif %}/>
{% for err in form.item_1_amount.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
</tr>
<tr>
<td>
<input
placeholder="Type in the Equipment and assets"
autocomplete="off"
type="text"
class="form-control"
name="item_2"
id="item_2"
{% if form.is_bound %}value="{{ form.item_2.value }}"{% endif %}/>
{% for err in form.item_2.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
<td>
<h6 style="float:left; margin-right:5px; margin-top:7px">$</h6>
<input
autocomplete="off"
type="number"
class="form-control w-25"
name="item_2_amount"
id="item_2_amount"
style="float:left"
{% if form.is_bound %}value="{{ form.item_2_amount.value }}"{% endif %}/>
{% for err in form.item_2_amount.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
</tr>
<thead class="table-light">
<tr>
<th scope="col">subtotal</th>
<th scope="col" id="Total"></th>
</tr>
</thead>
<tr>
<td>
<input
placeholder="Type in the Equipment and assets"
autocomplete="off"
type="text"
class="form-control"
name="item_3"
id="item_3"
{% if form.is_bound %}value="{{ form.item_3.value }}"{% endif %}/>
{% for err in form.item_3.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
<td>
<h6 style="float:left; margin-right:5px; margin-top:7px">$</h6>
<input
autocomplete="off"
type="number"
class="form-control w-25"
name="item_3_amount"
id="item_3_amount"
style="float:left"
{% if form.is_bound %}value="{{ form.item_3_amount.value }}"{% endif %}/>
{% for err in form.item_3_amount.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
</tr>
<tr>
<td>
<input
placeholder="Type in the Equipment and assets"
autocomplete="off"
type="text"
class="form-control"
name="item_4"
id="item_4"
{% if form.is_bound %}value="{{ form.item_4.value }}"{% endif %}/>
{% for err in form.item_4.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
<td>
<h6 style="float:left; margin-right:5px; margin-top:7px">$</h6>
<input
autocomplete="off"
type="number"
class="form-control w-25"
name="item_4_amount"
id="item_4_amount"
style="float:left"
{% if form.is_bound %}value="{{ form.item_4_amount.value }}"{% endif %}/>
{% for err in form.item_4_amount.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
</tr>
<tr>
<td>
<input
placeholder="Type in the Equipment and assets"
autocomplete="off"
type="text"
class="form-control"
name="item_5"
id="item_5"
{% if form.is_bound %}value="{{ form.item_5.value }}"{% endif %}/>
{% for err in form.item_5.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
<td>
<h6 style="float:left; margin-right:5px; margin-top:7px">$</h6>
<input
autocomplete="off"
type="number"
class="form-control w-25"
name="item_5_amount"
id="item_5_amount"
style="float:left"
{% if form.is_bound %}value="{{ form.item_5_amount.value }}"{% endif %}/>
{% for err in form.item_5_amount.errors %}
<small class="text-danger mb-2 ml-2">{{ err }}</small>
{% endfor %}
</td>
</tr>
<thead class="table-light">
<tr>
<th scope="col">subtotal</th>
<th scope="col" id="Total2"></th>
</tr>
</thead>
<thead class="table-light">
<tr>
<th scope="col">Grand Total</th>
<th scope="col" id="Grandtotal"></th>
</tr>
</thead>
</tbody>
</table>
<div class="text-center">
<button
class="btn btn-primary mt-5"
onclick="stepper1.previous()"
>
Previous
</button>
<button type="submit" class="btn btn-success mt-5">
Submit
</button>
</div>
My question:
How to add Item 1 and 2 together to get Subtotal 1 then add 3 and 4 together to get subtotal 2 and then add the 2 subtotals to get the grand total.
I've spun a codepen of the code I'm about to explain here (with comments in the JS as well): https://codepen.io/marcusparsons/pen/vYZrVpy?editors=1010
The best way to achieve that kind of functionality is to group your inputs together with a couple more binding classes. What I did was add an extra primary class and then a subset class for targeting groups so that way individual groups can be calculated dynamically (meaning you could have any amount of inputs in a group and each value will be taken into account without extra code). And also, they each have a primary class because we're also getting a Grand Total.
For example, you want to add item 1 and item 2 together for Subtotal 1. Well, you could do that manually, but I always ask the question, "What if I have 1,000 inputs I want to equal Subtotal 1?" In this case, classes come in super handy, like so (I stripped some of your server side code to be able to work with just the HTML and JS needed):
<input
autocomplete="off"
type="number"
<!-- Added subtotal-group and subtotal-group-2 class -->
class="form-control w-25 subtotal-group subtotal-group-2"
name="item_4_amount"
id="item_4_amount"
style="float:left">
Basically, item 1 and item 2 got the subtotal-group and subtotal-group-1 classes. And then items 3, 4, and 5 got the subtotal-group and subtotal-group-2 classes.
And then, in the JavaScript, I target each of the groupings and apply them to the target elements you want. I also changed the event keyword to input from keyup because if you only target keyup on a type="number" input, you will miss the events that occur when up and down arrows are clicked/touched and you'll miss copy/paste events from user. When in doubt, I go with input over keyup for the event to listen to.
//Gather totals for subtotal-group-1 which is item 1 and item 2
//you could expand this ad infinitum by adding input type=number elements to the class subtotal-group and subtotal-group-1
//Keeping these elements grouped together with these classes allow us to be flexible and group things together
//Classes are powerful!!!
const resultGroupSet1 = [...qa('.subtotal-group-1')]
.map(s => Number(s.value))
.reduce((a,v) => a+v);
q('th#Total').textContent = resultGroupSet1;
And then rinse and repeat for each subsequent group:
const resultGroupSet2 = [...qa('.subtotal-group-2')]
.map(s => Number(s.value))
.reduce((a,v) => a+v);
q('th#Total2').textContent = resultGroupSet2;
And to get the final group total, just target the primary .subtotal-group class:
const resultGroupSetGrandTotal = [...qa('.subtotal-group')]
.map(s => Number(s.value))
.reduce((a,v) => a+v);
q('th#Grandtotal').textContent = resultGroupSetGrandTotal;
Related
This works for only the first of my entries however, in the rest of my entries, the error doesn't show. How do I ensure if the entries don't match on the rest, the error message appears too? I'm using Python/Flask and Html/Js
<script>
function compare_input() {
var f_input = document.querySelector(".credit").value;
var s_input = document.querySelector(".debit").value;
if (f_input !== s_input) {
alert('Debit and Credit must be equal');
}
}
</script>
Inputs
For Credit
{% for number in range(1, 6) %}
<tr>
<td>
<select name="credit_{{ number }}_account">
{% for account in accounts %}
<option value="{{ account['acct_num'] }}">{{ account['acct_num'] }} - {{ account['acct_name'] }}</option>
{% endfor %}
</select>
</td>
<td style="padding-bottom: 1px">
<input style="border: none" class="credit" name="credit_{{ number }}_value" type="text" datatype="currency" placeholder="$0" id="credit_{{ number }}_value">
</td>
</tr>
{% endfor %}
For Debit
{% for number in range(1, 6) %}
<tr>
<td>
<select name="debit_{{ number }}_account">
{% for account in accounts %}
<option value="{{ account['acct_num'] }}">{{ account['acct_num'] }} - {{ account['acct_name'] }}</option>
{% endfor %}
</select>
</td>
<td style="padding-bottom: 1px">
<input style ="border: none" class="debit" name="debit_{{ number }}_value" type="text" datatype="currency" placeholder="$0" id="debit_{{ number }}_value">
Top entries are credit then debit. All the entries that need to read the same error when credit doesn't equal debit
I don't really know much Js either, just learning
I have a page that allows a doctor to create a prescription. This page as a form that allows you to add as many rows as you want to add elements to your prescription. I will share with you the view and html template.
I replicated the exam same thing for creating another type of prescription (lab analysis).
This time, the button does not want to add more rows, even though I used the exact same code, and I will tell you exactly what breaks it, but I do not know how to fix it.
Here is the code for the first one (the one that works):
view:
#login_required
def createPrescription(request):
[...] # ommited because unrelated
drugs = Drug.objects.all()
return render[...] # ommited because unrelated
HTML:
<!-- PAGE-HEADER END -->
<form method="POST" id="presForm">
{% csrf_token %}
[...] # ommited because unrelated
<div class="card">
<div class="card-header">
<div class="card-title">Eléments de l'ordonnance</div>
</div>
<div class="card-body">
<table id="myTable" class="table order-list">
<thead>
<tr>
<td>Médicament</td>
<td>Dosage</td>
<td>Posologie</td>
<td>Durée</td>
<td></td>
</tr>
</thead>
<tbody>
<tr>
<td class="col-5">
<div class="row">
<div class="col-6">
<input class="form-control mb-4" placeholder="Nom du médicament" type="text" name="medicament0">
</div>
<div class="col-6">
<div class="form-group">
<select class="form-control select2-show-search form-select" id="medicament-id0" name="listemedicament0">
<option value="0">Ou choisir de la liste</option>
{% for d in drugs %}
<option value="{{ d.id }}">{{ d }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</td>
<td>
<input class="form-control mb-4" placeholder="20mg" type="text" name="dosage0">
</td>
<td>
<input class="form-control mb-4" placeholder="2 / j avant repas" type="text" name="posologie0">
</td>
<td>
<input class="form-control mb-4" placeholder="7 jours" type="text" name="duree0">
</td>
<td><a class="deleteRow"></a>
<input type="button" class="btn btn-lg btn-secondary " id="addrow" value="Ajouter élément" />
</td>
</tr>
</tbody>
</table>
</div>
<div class="btn-list ms-auto my-auto">
Annuler
<button id="presBtn" type="submit" class="btn btn-primary btn-space mb-0">Soumettre</button>
</div>
</div>
</div>
</form>
<!--/Row-->
Now here is the code of the second one (the one that doesn't work):
view:
#login_required
def createLabRequest(request):
exams = _ex.objects.all()
return render[...] # ommited because unrelated
HTML:
<!-- PAGE-HEADER END -->
<form method="POST" id="presForm">
{% csrf_token %}
[...] # ommited because unrelated
<div class="card">
<div class="card-header">
<div class="card-title">Eléments d'analyses</div>
</div>
<div class="card-body">
<table id="myTable" class="table order-list">
<thead>
<tr>
<td>Analyse</td>
<td></td>
</tr>
</thead>
<tbody>
<tr>
<td class="col-5">
<div class="row">
<div class="col-6">
<input class="form-control mb-4" placeholder="Analyse" type="text" name="exam0">
</div>
<div class="col-6">
<div class="form-group">
<select class="form-control select2-show-search form-select" id="exam-id0" name="examlist0">
<option value="0">Ou choisir de la liste</option>
{% for e in exams %}
<option value="{{ e.id }}">{{ e }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
</td>
<td><a class="deleteRow"></a>
<input type="button" class="btn btn-lg btn-secondary " id="addrow" value="Ajouter élément" />
</td>
</tr>
</tbody>
</table>
</div>
<div class="btn-list ms-auto my-auto">
Annuler
<button id="presBtn" type="submit" class="btn btn-primary btn-space mb-0">Soumettre</button>
</div>
</div>
</div>
</form>
<!--/Row-->
Now the problem is this:
When I copied the code and renamed {% for d in drugs %} <option value="{{ d.id }}">{{ d }}</option> to {% for e in exams %} <option value="{{ e.id }}">{{ e }}</option> The button to add a new row stopped working.
Here is the problem: the list contains some data that interferes with the loading of the JavaScript, to solve this, we need to make the following changes:
Add the following function to the MedicalExam model:
def examDisplay(self):
display = ''.join(e for e in self.name if e.isalnum or e == ' ' or e == '-' or e == '/')
return display
And in the HTML, we put:
{% for e in exams %} <option value="{{ e.id }}">{{ e.examDisplay }}</option>
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
}
});
});
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.
I have two drop down list inputs ,both of them comes from datalist , i want that base on the input that the user choose, to filter the other input to show only relevant results .
I am rendering the data from python back to HTML page
The data contains company name and bank account number,
So i want base on the company that user choose to show only the relevant account to the selected company
<form id="the_form" method="POST">
{% csrf_token %}
From:
<input name="start_date" class="datepicker" type="date" value={{start_date}}/>
To:
<input name="end_date" class="datepicker" type="date" value={{end_date}}/>
<input type="text" list='List_of_Companies' data-search-in="Company" id="Input1" name="Companyname" placeholder="Choose a Company" value="{{ Company}}"/>
<input type="text" list='List_of_Accounts' data-search-in="Account" id="Input2" name="Accountname" placeholder="Choose an Account ID" value="{{ Account_Id}}"/>
<br> <br>
<button name="action" type="submit" id="showccounts" value="show">Show</button>
<button name="action" type="submit" value="download">Download</button>
<datalist id="List_of_Companies">
<select id="filenamelist" size="5" class="select">
{% for Company in info_list %}
<option value="{{ Company.3 }}">{{ Company.3 }}</option>
{% endfor %}
</select>
</datalist>
<datalist id="List_of_Accounts">
<select id="filenamelist" size="5" class="select">
{% for Company in info_list %}
<option value="{{ Company.0 }}">{{ Company.3 }}</option>
{% endfor %}
</select>
</datalist>
</form>
{% load staticfiles %}
<div id="loading" style="width:300px;height:300px;display:table-cell; vertical-align:middle; text-align:center">
<img src="{% static "app/images/Loading_icon.gif" %}" style="margin:auto">
</div>
<table id="theTable" hidden>
<thead>
<tr>
{% for c in columns %}
<th>{{ c }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for r in rows %}
<tr>
{% for c in r %}
<td>{{ c }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% block scripts %}
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.15/js/jquery.dataTables.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>
I'm getting many data and i'm looping into them in html so there are many inputs with the same name
My html code :
{% for Permission in Permissions %}
<tr>
<td style="text-align:center;"> {{Permission.perm_label}} </td>
<td style="text-align:center;"> <input type="checkbox" class="permUsersClass" id="permUsers" name="permUsers" value="permUsers" {% if Permission.perm_users != 0 %} checked {% endif %}> <input type="text" id="permUsersText" name="Users" value="{{Permission.perm_users }}" > </td>
<td style="text-align:center;"> <input type="checkbox" id="permProfile" name="permProfile" value="permProfile" {% if Permission.perm_profile != 0 %} checked {% endif %} > <input type="text" id="permProfileText" name="Profile" value="{{Permission.perm_profile }}"></td>
<td style="text-align:center;"> <input type="checkbox" id="permSchedule" name="permSchedule" value="permSchedule" {% if Permission.perm_schedule != 0 %} checked {% endif %}> <input type="text" id="permScheduleText" name="Schedule" value="{{Permission.perm_schedule }}"> </td>
<td style="text-align:center;"> <input type="checkbox" id="permAccount" name="permAccount" value="permAccount" {% if Permission.perm_accounting != 0 %} checked {% endif %}> <input type="text" name="Accounting" value="{{Permission.perm_accounting}}"> </td>
</tr>
{% endfor %}
My javascript functiom
$('.permUsersClass').change(function () {
$('input[name=Users')[0].disabled = !this.checked;
}).change();
In javascript how to disable specific text box and not just the first one