Sum table column with JQuery - javascript

I have a table of All Sales, with the Client's Name, the date and the Sale Price.
I have a script for allowing a User to search through the table, but I would also like a script that returns a total for all the Sale Prices visible in the table.
e.g. If a User searches for T.Toe, then the script returns the sum of all Sale Prices for T.Toe.
code:
<table class="well table table-condensed small" id="academy">
<tr>
<td colspan="3">
<input type="text" id="search_academy" placeholder=" quick search" autocomplete="off">
</td>
<td><input type='text' style="width: 30px;" id='sum'></td>
</tr>
{% for sale in academy|sort(attribute="sale_date", reverse=True) %}
{% if sale.price > 0 %}
<tr class="success">
{% else %}
<tr class="danger">
{% endif %}
<th>{{ sale.sale_date.strftime('%d-%m-%Y') }}</th>
{% if sale.client %}
<th>{{ sale.client }}</th>
{% else %}
<th>{{ sale.concept }}</th>
{% endif %}
<th>{{ sale.club }}</th>
<th class="prices">{{ sale.price }}</th>
</tr>
{% endfor %}
</table>
JQuery for live search over the table and returning a sum of the searched cells:
EDIT:
Thanks to #pointy and #user4621032 the script currently is:
<script>$("#search_academy").keyup(function () {
var value = this.value.toLowerCase().trim();
$("#academy").find("tr").each(function (index) {
if (!index) return;
var id = $(this).find("th").text().toLowerCase().trim();
$(this).toggle(id.indexOf(value) !== -1);
});
var sum = 0;
$('.prices').each(function () {
sum += parseFloat($(this).text());
});
$('#sum').val(sum);
});
</script>
I changed the parseInt to parseFloat to keep 1 decimal place.
This does return a sum of the all cells in the column with the .prices class. However I am looking for the script to return the sum of only the .prices cells returned via the User search in #search_academy.
Thanks!

replace
sum += parseInt(this.innerHTML);
ro
sum += parseInt($(this).text());

Related

How to sum up Total Income and Total Indirect Income Using Jquery

I want to sum up total income and total indirect income. This total values in html table comes using jQuery by providing a class. But now I want to sum up two table total values in a single variable and put in a new html table.
The new html table looks like we have a column total (income+indirect income) = variable. Click to see the HTML table
How can I do that using jQuery. Click this link and see that the values of total amount column are sum up and lies in the footer on every table. But now I want to sum up two table values in a single variable and that new variable I want to put in a new html table on a same page.
$(document).ready(function() {
var total_1 = 0;
$('.income-amount').each(function(i, obj) {
total_1 += parseInt($(obj).text());
});
$('#income-total').text(total_1.toFixed(1));
});
I use this jQuery in the Html table for total amount column sum up.
Below is the html table.
<table id="example" class="table table-striped table-bordered table-responsive-xl">
<caption style="caption-side:top; text-align: center;"><h3>Income</h3></caption>
<thead class="thead-dark">
<tr>
{# <th>S No.</th>#}
<th>Particulars</th>
<th>Description</th>
<th>Total Amount</th>
</tr>
</thead>
<tbody>
{% for item in all_profit %}
{% if item.category.under == "Income" %}
<tr>
{# <td>{{ }} </td>#}
<td>{{item.category}}</td>
<td>{{item.category.desc}}</td>
<td class='income-amount'>{{ item.balance }} </td>
</tr>
{% endif %}
{% endfor %}
</tbody>
<tfoot>
<tr class="totalColumn">
<td style="visibility:hidden;"></td>
<td style="visibility:hidden;"></td>
<td id='income-total'>Total:</td>
</tr>
</tfoot>
</table>

pagination for table rows with fixed tablehead

On my website I created a "dynamic" table. I want to include a pagination, to only show 10 rows at a time. The table head shall be displayed above the rows on every page.
But with my pagination function, all the content within is put under "Ref.". If I uncomment the commented part, the pagination does not work at all.
What needs to changed in my code to display the table correct on each page? (all ref{{i}} under "Ref." / "score{{i}} under "Score" /...)
Table:
{% if empty == False %}
<table style="float: left; width: 100%" class="table table-hover">
<thead id="header">
<tr >
<th>Ref.</th>
<th>Score</th>
<th>Title</th>
</tr>
</thead>
<tbody>
{% for i in range (0,numofresults) %}
<tr id="cardmb3n{{i}}">
<td id="ref{{i}}"> </td>
<td id="score{{i}}" "> </td>
<td>
<div>
<a id="header{{i}}" href=""></a><br>
<a id="hyperlink{{i}}" href="" ></a>
</div>
</td>
</tr>
</tbody>
{% endfor %}
</table>
Pagination:
{% if empty == False %}
function paginate(page){
var val = parseInt(document.getElementById("currentpage").innerHTML);
if(page=='Next'){
page = val + 1;
} else if(page=='Previous'){
page = val - 1;
} else{
page = parseInt(page);
}
if(val!=page){
for(var j = 0; j<ergebnisliste.length; j++){
if(j>=(page-1)*10 && j<10*page){
// document.geElementById("header").style = "display:table";
document.getElementById("cardmb3n" + j).style = "display:block";
}else{
// document.geElementById("header").style = "display:none";
document.getElementById("cardmb3n" + j).style = "display:none";
}
}
........some code.........
}
}
{% endif %}
found a solution: document.getElementById("cardmb3n" + j).style = "display:table-row";

Javascript does not work in the second page of a data table

Actually I'm working with the following datatable:
Data Table code:
<table aria-describedby="dataTable_info" cellspacing="0" class="table table-hover dataTable" id="dataTable" role="grid" style="width:100%;" width="100%">
<thead>
<tr>
<th>{{'fsaGeneralPlan.table.Auditors'|trans({}, 'FSABundle')}}</th>
<th>{{'fsaGeneralPlan.table.Audits'|trans({}, 'FSABundle')}}</th>
<th>{{'fsaGeneralPlan.table.Areas'|trans({}, 'FSABundle')}}</th>
</tr>
</thead>
<tbody>
{% for audit in auditsByArea %}
{% set myArray = audit.Audits|split(',') %}
{% set AuditsStatus = audit.AuditsStatus|split(',') %}
<tr>
<td>{{ audit.Auditor }}</td>
<td>
{# {% set long = numberOfAudits|length + 2 %} #}
{# <h1>{{ long }}</h1> #}
{% for i in 0..3 %}
{% set e = i + 1 %}
<a title="{{ AuditsStatus[i] }}" class="btn btn-outline-primary btn-sm auditButton {{ AuditsStatus[i] }}" data-id="Audit{{ myArray[i] }}" data-area="{{ audit.area_name }}" data-status="{{ AuditsStatus[i] }}" id="auditButton{{ myArray[i] }}" name="auditButton">{{'w' ~ e }}</a>
{# <input class ="auditButton {{ AuditsStatus[i] }} mx-2" value="{{'W' ~ i }}" href="" data-id="Audit{{ myArray[i] }}" data-area="{{ audit.area_name }}" data-status="{{ AuditsStatus[i] }}" id="auditButton{{ myArray[i] }}" name="auditButton" type='text' readonly ></input> #}
{% endfor %}
</td>
<td>{{ audit.area_name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
And I have this Javascript to change the class of the buttons in the datatable once that the page is loaded:
<script type="text/javascript">
$(document).ready(function(){
$(".auditButton.Submitted").removeClass('btn-outline-primary');
$(".auditButton.Submitted").addClass('btn-outline-success');
$(".auditButton.Expired").addClass('btn-outline-danger');
$(".auditButton.Capturable").addClass('btn-outline-warning');
});
It works correctly but just in the first page of the datatable, it does not work in the other pages.
Any idea or subject of how to fix it or what is wrong?
You need to listen to the draw event for your table.
Why?
Your current setup works fine for the first page, because those elements are all rendered when $(document).ready() fires. However, the other pages are rendered after the document is ready.
Try:
const table = $('#dataTable').DataTable();
// Event listener for DT 1.10+
table.on('draw', function() {
$(".auditButton.Submitted").removeClass('btn-outline-primary');
$(".auditButton.Submitted").addClass('btn-outline-success');
$(".auditButton.Expired").addClass('btn-outline-danger');
$(".auditButton.Capturable").addClass('btn-outline-warning');
});
Doing this, you can also remove the same block of code from `$(document).
You can also place all this inside the draw callback for your datatable if you'd prefer:
const table = $('#dataTable').DataTable({
drawCallback: function(settings) {
// changes in here
}
});

Flask does not return db query when I use the JS hide/unhide. Works if I comment out JS

I am trying to retrieve data from the database based on a users search results. The results, in a table format, should only be shown after the user hits the search button.
Query executes fine when javascript is cancelled out and the table "list" display is changed to block. However, when I enable the javascript I get no results.
<div style="text-align: center;">
{% from "_formhelpers.html" import render_field %}
<form method=post action="/">
<dl style="display: inline-block; text:white;" >{{render_field(form.search)}} </dl>
<button id="searchbutton" type="submit" style="display: inline-block;" class="btn btn-outline-success my-2 my-sm-0" onclick="fetchlist(); return false;">Search</button>
<br>
{% if error %}
<p class = "error"><strong>Error:</strong>{{error}}</p>
{% endif %}
</form>
</div>
<div style="text-align:center;">
<table id="list" style="display:none;" class = "table table-hover" >
<thead>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Rating</th>
<th scope="col">Review</th>
</thead>
<tbody>
{% for row in data %}
<tr>
{% for d in row %}
<td>{{ d }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
<script>
function fetchlist() {
if (document.getElementById('searchbutton').onclick) {
document.getElementById('list').style.display = 'inline';
}
else document.getElementById('list').style.display = 'inline';
}
</script>
{% endblock %}
</html>
#app.route('/', methods=['GET', 'POST'])
def homepage():
try:
form=SearchForm(request.form)
global d1
d1 =""
if request.method == "POST" and form.validate():
search = form.search.data
a = search.split(" ",1)
firstname, lastname = (a[0], a[1])
c,conn = connection()
qry = "SELECT FirstName, LastName FROM posts WHERE FirstName LIKE (%s) AND LastName like (%s)"
c.execute(qry, ((thwart(firstname)), (thwart(lastname))))
d1 = c.fetchall()
c.close()
conn.close()
else: print('error')
return render_template("index.html", data=d1, form = form)
except Exception as e:
return(str(e))
As you already know the problem is caused by your JS. This is because the JS is waiting for the search button to be clicked before it changes the style of the list to inline.
This all seems fine, but the problem comes in the fact that the JS is executed when the button is clicked. But then the request is posted to the server and a new page is sent to the browser with the search results. However, this new page the search button has never been clicked.
You can fix writing the method to display the results into your template. For instance you could wrap the table in an if statement like this...
{% if data|length %}
<div style="text-align:center;">
<table id="list" style="display:none;" class = "table table-hover" >
<thead>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Rating</th>
<th scope="col">Review</th>
</thead>
<tbody>
{% for row in data %}
<tr>
{% for d in row %}
<td>{{ d }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table
</div>
{% endif %}
The |length filter makes sure data is not an empty string. Otherwise I believe it may always be true. You could try {% if data %} to double check. It may work.
There are a lot more options....
You could wrap you <script> in the if statement. You should modify it a little. So it does not wait of the search button to be clicked.
You could wrap the inline style in the if statement. Of course you could use CSS classes instead of inline styling. This would be cleaner.

How do I code a count for double nested for loop?

I'm trying to pass just the piece number to my html. This will be used to update the content of a selected tag with javascript. All of my tags are created by a double nested for loop in django. But from what I've tried I've had no success.
Here is the javascript code:
$('td#'+new_data['piece_number']).html(new_data['img']);
Here is the double nested for loop in question:
<table id="table" bgcolor="{{puzzle.color_hash}}">
<tbody>
{% for x in n_rows %}
<tr id='r{{x}}'>
{% for y in n_cols %}
<td id='{{count}}' height='{{puzzle.piece_res_height}}' width='{{puzzle.piece_res_width}}'>
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
I want the total iteration count in {{count}} but from my understanding django doesn't let you have variable manipulation in the renderer
I'm looking for a result such as a row by column table...
1 2 3
4 5 6
7 8 9
Where there are 3 rows and 3 columns. 9 pieces. each with a td id of the piece number
i.e. row 2 column 2 has a td id of 5
You can send two wariables instead one count to html file and change ida of id naming.
<td id='r{{x}}d{{y}}' height='{{puzzle.piece_res_height}}' width='{{puzzle.piece_res_width}}'>
Edit - right solution
Ok, I have two solutions for you.
Both use custom template filters.
File app/templatetags/default_filters.py
from django import template
register = template.Library()
#first way
def mod(value, arg):
return value % arg == 0
#second way
#register.filter(name='multiply')
def multiply(value, arg):
return value*arg
register.filter('mod', mod)
Context send to template
class MainSiteView(TemplateView):
template_name = "main_page.html"
def get_context_data(self, **kwargs):
context = super(MainSiteView, self).get_context_data(**kwargs)
n_rows = n_cols = 2
context['max_nums'] = n_rows * n_cols
context['n_rows'] = [0, 1]
context['n_cols'] = [0, 1]
context['number_of_columns'] = 2
context['range'] = [x for x in range(n_cols * n_rows)]
return context
And template
{% load default_filters %}
<table id="_table" bgcolor="{{puzzle.color_hash}}">
<tbody>
{% for x in range %}
{% if not forloop.counter|mod:number_of_columns %}
<tr id='_r{{x}}'>
{% endif %}
<td id='_{{forloop.counter0}}' height='{{puzzle.piece_res_height}}' width='{{puzzle.piece_res_width}}'>
({{forloop.counter0}})
</td>
{% if forloop.counter|mod:number_of_columns %}
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<table id="table" bgcolor="{{puzzle.color_hash}}">
<tbody>
{% for x in n_rows %}
<tr id='r{{x}}'>
{% for y in n_cols %}
<td id='{{x|multiply:number_of_columns|add:y}}' height='{{puzzle.piece_res_height}}' width='{{puzzle.piece_res_width}}'>
[{{x|multiply:number_of_columns|add:y}}]
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>

Categories

Resources