JQuery - Table Calculation - javascript

I have a table generated from database. And each field hidden until selected from select dropdown list. Also need calculate visible rows. I have this code, but it calculates all rows, even visibly. Could you advice how I can fix the code to calculate only visibly rows.
TABLE:
<table width="100%" border="0" id="sum_table">
<tr style="color:white;background:gray;">
<td>Name</td>
<td>Column 1</td>
<td>Column 2</td>
<td>Column 3</td>
<td>Column 4</td>
</tr>
<tr id="one">
<td>Service 1</td>
<td>12</td>
<td>45</td>
<td>45</td>
<td>54</td>
</tr>
<tr id="two">
<td>Service 2</td>
<td>8</td>
<td>42</td>
<td>35</td>
<td>23</td>
</tr>
<tr id="three">
<td>Service 3</td>
<td>6</td>
<td>65</td>
<td>16</td>
<td>26</td>
</tr>
<tr id="result" style="background:silver;">
<td>TOTAL:</td>
<td id="total1">0</td>
<td>0</td>
<td></td>
<td></td>
</tr>
</table>
<br>ADD LINE:
<select id="select_stud">
<option>-- Select --</option>
<option>one</option>
<option>two</option>
<option>three</option>
</select>
JS:
$(document).ready(function () {
$('#one').hide();
$('#two').hide();
$('#three').hide();
$('#select_stud').change(function () {
$('#'+$(this).val()).show();
})
});
$("#sum_table tr:last td:not(:first,:last)").text(function(i){
var t = 0;
$(this).parent().prevAll().find("td:nth-child("+(i+2)+")").each(function(){
t += parseInt( $(this).text(), 10 ) || 0;
});
return "= " + t;
});
Also I need to calculate only 2 columns.
Here is full code: http://jsfiddle.net/stanencendo/u7a27vth/9/
Thanks.

Here's an example of what you are trying to do: http://jsfiddle.net/u7a27vth/10/
To only look at visible rows when calculating your sum, you can add a condition like this:
if ( $(this).parent().css('display') != 'none' )
You'll also want to update the sums every time you add a new column. You can do that by wrapping your sum calculation in a function (in this case, updateSums) and call it within your change function for the select element:
$('#select_stud').change(function () {
$('#'+$(this).val()).show();
updateSums();
})
That said, your approach probably isn't the best way to handle this. Typically, you want your view to be derived from your data, not the other way around.
Edit: As pointed out in the comments, if you want the last column to be calculated as well, you need to change $("#sum_table tr:last td:not(:first,:last)") to $("#sum_table tr:last td:not(:first)")
It wasn't clear to me whether or not this was you intention.

$("#sum_table tr:last td:not(:first,:last)").text(function(i){
var t = 0;
$(this).parent().prevAll().find("td:nth-child("+(i+2)+")").filter(":visible").each(function(){
t += parseInt( $(this).text(), 10 ) || 0;
});
return "= " + t;
});

Related

Hide elements without knowing complete id

I have a table like below
<table id="categoriesTable">
<tr id=row_id1_dynamicdata>
<td>...</td>
<td>..</td>
</tr>
<tr id=row_id2_dynamicdata>
<td>...</td>
<td>..</td>
</tr>
<tr id=row_id3_dynamicdata>
<td>...</td>
<td>..</td>
</tr>
<tr id=row_id4_dynamicdata>
<td>...</td>
<td>..</td>
</tr>
</table>
I want to hide all rows except row whose id contains id4. I won't have full id.
I came up with below jQuery code, but as I don't have full id, it doesn't work.
var idValue = document.getElementById(someElement);
$('#categoreisTable').find('tr').not($('#row_' +idValue)).hide();
How to filter with only half the id?
You can use the "Attribute starts with" selector to find the rows which don't match the one with the specified idValue. For example:
$('#someElement').on('change', function() {
var idValue = this.value;
$('#categoriesTable')
.find('tr')
.show() // not needed if you only want to hide
.not('[id^="row_id' + idValue + '_"]')
.hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="categoriesTable">
<tr id=row_id1_dynamicdata>
<td>.1..</td>
<td>..</td>
</tr>
<tr id=row_id2_dynamicdata>
<td>.2..</td>
<td>..</td>
</tr>
<tr id=row_id3_dynamicdata>
<td>.3..</td>
<td>..</td>
</tr>
<tr id=row_id4_dynamicdata>
<td>.4..</td>
<td>..</td>
</tr>
</table>
<input type="text" id="someElement" />
You can use querySelectorall on the tr element and then run a loop to only show rows that include id4 in their id.
Run the snippet below:
var idValue = document.querySelectorAll('tr');
for (i = 0; i < idValue.length; i++) {
if (idValue[i].id.includes("id4")) {
idValue[i].style.display = "block";
} else {
idValue[i].style.display = "none"
}
}
<table id="categoriesTable">
<tr id=row_id1_dynamicdata>
<td>row1</td>
<td>..</td>
</tr>
<tr id=row_id2_dynamicdata>
<td>row2</td>
<td>..</td>
</tr>
<tr id=row_id3_dynamicdata>
<td>row3</td>
<td>..</td>
</tr>
<tr id=row_id4_dynamicdata>
<td>row 4</td>
<td>..</td>
</tr>
<tr id=anotherrow_id4_dynamicdata>
<td>another row with id4</td>
<td>..</td>
</tr>
</table>
You can use document.getElementsByTagName to get all id contain id4.
Then, just to hide them.
let ElementArray = Array.prototype.filter.call(document.getElementsByTagName('tr'), element => element.id.match('id4'));
let idArray = ElementArray.forEach(element => document.getElementById(element.id).style.display="none");
You can simply use:
$('#categoriesTable tr').not('[id^="row_id4_"]').hide();

Filter table in jQuery? or angularJS

I want to be able to filter my table, the table is like this
name | date | agencyID
test 2016-03-17 91282774
test 2016-03-18 27496321
I want to be able to have a dropdown with all the 'agencyID' and when I select it only show the table rows with this agencyID in. I have a similar thing where you can search for anything in a input type text.
This is how that part works, is there any similar way I can do this with a select dropdown?
(function ($) {
$('#filter').keyup(function () {
var rex = new RegExp($(this).val(), 'i');
$('.searchable tr').hide();
$('.searchable tr').filter(function () {
return rex.test($(this).text());
}).show();
})
}(jQuery));
I am open to implementing angularJS if this is a better alternative
you can do an on change handler on the select drop down.
html:
<script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
<select id="filter">
<option value="">Choose a filter</option>
<option value="1231423424">1231423424</option>
<option value="456456e54">456456e54</option>
<option value="123488745">123488745</option>
</select>
<table id="searchable">
<tr>
<th>name</th>
<th>date</th>
<th>agencyID</th>
</tr>
<tr>
<td>test 1</td>
<td>date 1</td>
<td>1231423424</td>
</tr>
<tr>
<td>test 2</td>
<td>date 2</td>
<td>456456e54</td>
</tr>
<tr>
<td>test 3</td>
<td>date 3</td>
<td>456456e54</td>
</tr>
<tr>
<td>test 4</td>
<td>date 4</td>
<td>123488745</td>
</tr>
<tr>
<td>test 5</td>
<td>date 5</td>
<td>123488745</td>
</tr>
</table>
Javascript:
$(document).ready(function(){
$('#filter').change(function(){
var filterValue = $(this).val();
if(filterValue==""){
$("#searchable tr").show();
} else{
$("#searchable tr").hide();
$("#searchable td:nth-child(3)").each(function(){
if( $(this).text() == filterValue){
$(this).parent().show();
}
});
}
});
});
See it in fiddle
Here is another implementation using :contains() selector
$select.on('change', function(){
$('.highlight').removeClass('highlight');
var id = $(this).val();
$('table').find("tr:contains('"+id+"')").addClass('highlight');
});
Fiddle here
you can add to tr an id that is the agency
<select id="select">
<option value=""></option>
<option value="91282774">91282774</option>
<option value="27496321">27496321</option>
</select>
<table id="mytable">
<tr><th>name</th><th>data</th><th>agency</th></tr>
<tr id="91282774"><td>test</td><td>2016-03-17</td><td>91282774</td></tr>
<tr id="27496321"><td>test</td><td>2016-03-18</td><td>27496321</td></tr>
</table>
and search the id when change the selection
$(document).ready(function(){
$("#select").change(function(){
var value = $(this).val();
if(value == "")
$("#mytable tr").show();
else{
$("#mytable tr[id=" + value + "]").show();
$("#mytable tr[id][id!=" + value + "]").hide();
}
});
});
fiddle

How to move/reorder an html table row

The idea is to move a particular table row to a different location
HTML
<table id="grid1" class="table table-zebra">
<tbody>
<tr>
<td>Cont 1 tr 1</td>
</tr>
<tr>
<td>Cont 2 tr 2</td>
</tr>
<tr>
<td>Cont 3 tr 3</td>
</tr>
<tr>
<td>Cont 4 tr 4</td>
</tr>
<tr>
<td>Cont 5 tr 5</td>
</tr>
<tr>
<td>Cont 6 tr 6</td>
</tr>
<tr>
<td>Cont 6 tr 6</td>
</tr>
<tr>
<td>Cont 7 tr 7</td>
</tr>
<tr>
<td>Cont 8 tr 8</td>
</tr>
<tr>
<td>Cont 9 tr 9</td>
</tr>
<tr>
<td>Cont 10 tr 10</td>
</tr>
<tr>
<td>Cont 11 tr 11</td>
</tr>
<tr>
<td>Cont 12 tr 12</td>
</tr>
<tr>
<td>Cont 13 tr 13</td>
</tr>
<tr>
<td>Cont 14 tr 14</td>
</tr>
</tbody>
</table>
That is the basic table, now, how do I can I move the TR 11 in a away that it will be under TR 4, I'm sorry that I don't post any JS but I have no idea how to do it... I was looking at this JSbin which is nice but can't use it..
Move the 11th tr to under the 4th:
$("tbody tr:nth-child(11)").insertAfter("tbody tr:nth-child(4)");
Working demo
If you prefer vanilla, you need the selectors the other way around.
document.querySelector("tbody tr:nth-child(4)").insertAdjacentElement("afterend", document.querySelector("tbody tr:nth-child(11)"));
In the context of an HTML table with rows that look like this:
<tr class="form-grid-view-row">
<td>
<a class="up" href="#">⇑</a>
</td>
<td>
<a class="down" href="#">⇓</a>
</td>
<td>
<span id="index1" class="form-label">1</span>
</td>
<td>
<span id="span1" class="form-label">Value 1</span>
</td>
</tr>
And this script:
$('.up,.down').click(function () {
var row = $(this).parents('tr:first');
if ($(this).is('.up')) {
row.insertBefore(row.prev());
} else {
row.insertAfter(row.next());
}
});
$('.up,.down').click(function () {
This is selecting every DOM element with the class "up" and every element with the class "down", e.g. $('.up,.down').click(function () {. The function sets up a click handler for each element.
var row = $(this).parents('tr:first');
$(this) refers to the DOM element which is the target of the click handler (one of the "up" or "down" elements which was selected above). .parents() looks for tr:first, the first <tr> element starting with <a> and travelling up the DOM. It'll end up selecting the entire row.
if ($(this).is('.up')) {
This is checking to see whether or not the element selected has the class "up" or not.
row.insertBefore(row.prev());
This takes the row that was clicked, and moves it right above the upper-most sibling of the row that was clicked.
The jQuery methods used (insertBefore, prev, is, parents, etc.) are described in greater detail in the jQuery documentation.
You can do it by using JQuery Library.
// selecting tbody is bad instead you need to give an id or class to this tag and select according to this
var fourth = $( "tbody tr:nth-child(4)" ),
eleventh = $( "tbody tr:nth-child(11)" );
$( "tbody tr:nth-child(11)" ).insertAfter(fourth);
In order to move dynamically your elements you can add an event to all tbody children. What I basically do is select one element on first click then I move it after second element clicked.
$(document).on("ready", function () {
var $tbody = $("#grid");
var selected = null;
$tbody.children().on("click", function () {
if (selected == null)
selected = this;
else
{
$(selected).insertAfter(this);
selected = null;
}
});
});
It move after an element but is just an idea, you can customize it.
Your html should be like this.
<table>
<tbody id="grid">
<tr> <td> 1 </td> </tr>
<tr> <td> 2 </td> </tr>
<tr> <td> 3 </td> </tr>
<tr> <td> 4 </td> </tr>
</tbody>
</table>

filtering with combobox category and textbox javascript

the text input filtering is working but i don`t know how to implement with category using combo box. the category is using by there age.
please help my to this task:(
this is my sample code
this is my view
<select>
<option>all age</option>
<option>16</option>
<option>18</option>
<option>20</option>
</select>
<input />
<table class="AvailableGroupLab availGrpLabs avalLabs">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td><span>wewe</span>
</td>
<td>16</td>
</tr>
<tr>
<td><span>Melvin</span>
</td>
<td>18</td>
</tr>
<tr>
<td><span>Marvin</span>
</td>
<td>20</td>
</tr>
<tr>
<td><span>wewex</span>
</td>
<td>20</td>
</tr>
</tbody>
</table>
this is javascript
function filter(element) {
var $trs = $('.AvailableGroupLab tbody tr').hide();
var regexp = new RegExp($(element).val(), 'i');
var $valid = $trs.filter(function () {
return regexp.test($(this).find('td:first-child').text())
}).show();
$trs.not($valid).hide()
}
$('input').on('keyup change', function () {
filter(this);
})
The problem with you code is that you are comparing regexp with 1st child of tr, while you age is in 2nd child.
var $valid = $trs.filter(function () {
return regexp.test($(this).find('td:eq(1)').text())
// or
return regexp.test($(this).find('td:last-child').text())
}).show();
I hope this will help you.

How to avoid duplicate code (toggle when page loaded)?

See the code below, If you click on the sub-title row it then will hide the rows with it. It work well.
On the second sub-title row (<tr class="sub-title default-hide">) - I want this to toggle/hidden by default when the page loaded.. How to do this without writing duplicate code like below?
$(".sub-title").on("click",function() {
tr = $(this).find('span').hasClass("arrow2");
trSpan = $(this).find('span');
$(this).nextUntil(".sub-title").each(function() {
if (!$(this).hasClass('head-order')) {
$(this).toggle();
if (tr) {
trSpan.removeClass('arrow2').addClass('arrow1');
} else {
trSpan.removeClass('arrow1').addClass('arrow2');
}
}
});
});
HTML
<table border="1">
<tbody>
<tr class="head">
<td> title </td>
</tr>
<tr class="sub-title">
<td>Sub Title 1 <span class="arrow2"> </span></td>
</tr>
<tr> <td>Item 1</td> </tr>
<tr> <td>Item 2</td> </tr>
<tr> <td>Item 3</td> </tr>
<tr class="sub-title default-hide">
<td>Sub Title 2 <span class="arrow2"></span></td>
</tr>
<tr> <td>Item 4</td> </tr>
<tr> <td>Item 5</td> </tr>
<tr> <td>Item 6</td> </tr>
</tbody>
</table>
I created a jsFiddle example with the information you provided.
I edited the code a bit, using a default arrow-class and just adding the class close to it, to define the new style, which should make the code a little shorter.
$(".sub-title").on("click",function() {
var trSpan = $(this).find('span');
trSpan.toggleClass('closed');
$(this).nextUntil(".sub-title").each(function() {
if (!$(this).hasClass('head-order')) {
$(this).toggle();
}
});
});
To make the "default-hidden" - element closed on pageload, all I do is to trigger a click-event on it after binding the click-Handler.
$('.default-hide').trigger('click');
See the fiddle for a working example
Create a named function and call it a couple times:
var toggleArrow = function(el) {
tr = $(el).find('span').hasClass("arrow2");
trSpan = $(el).find('span');
$(el).nextUntil(".sub-title").each(function() {
if (!$(el).hasClass('head-order')) {
$(el).toggle();
if (tr) {
trSpan.removeClass('arrow2').addClass('arrow1');
} else {
trSpan.removeClass('arrow1').addClass('arrow2');
}
}
});
};
$(".sub-title").on("click", function(){ toggleArrow(this); });
$(".default-hide").each(function(i, el){ toggleArrow(this); });
You can trigger the click event manually for the default-hide rows.
Like this
$('.default-hide').trigger('click');

Categories

Resources