How to obtain responsive table after sticky header? - javascript

I have installed sticky header module in my angular application and I want to obtain a sticky-responsive thead.
Initial
<!--"table" = responsive boostrap class-->
<table class="table">
<thead>
<tr>
<th>...</th>
<th>...</th>
</tr>
</thead>
<tbody>
<tr>
<td>...</td>
<td>...</td>
</tr>
</tbody>
</table>
After sticky header executes the table width is fixed:
<thead>
<tr>
<th style="width:173px">...</th>
<th style="width:173px">...</th>
</tr>
</thead>
I tried to remove the style attribute from the script, but this is not helpful. I have also seen that angular-scrollable-table directive is responsive.
var headersAreFixed = $q.defer();
function fixHeaderWidths() {
if (!$element.find("thead th .th-inner").length) {
$element.find("thead th").wrapInner('<div class="th-inner"></div>');
}
if($element.find("thead th .th-inner:not(:has(.box))").length) {
$element.find("thead th .th-inner:not(:has(.box))").wrapInner('<div class="box"></div>');
}
$element.find("table th .th-inner:visible").each(function (index, el) {
el = angular.element(el);
var width = el.parent().width(),
lastCol = $element.find("table th:visible:last"),
headerWidth = width;
if (lastCol.css("text-align") !== "center") {
var hasScrollbar = $element.find(".scrollArea").height() < $element.find("table").height();
if (lastCol[0] == el.parent()[0] && hasScrollbar) {
headerWidth += $element.find(".scrollArea").width() - $element.find("tbody tr").width();
headerWidth = Math.max(headerWidth, width);
}
}
var minWidth = _getScale(el.parent().css('min-width')),
title = el.parent().attr("title");
headerWidth = Math.max(minWidth, headerWidth);
el.css("width", headerWidth);
if (!title) {
// ordinary column(not sortableHeader) has box child div element that contained title string.
title = el.find(".title .ng-scope").html() || el.find(".box").html();
}
//el.attr("title", title.trim());
});
headersAreFixed.resolve();
}

I overrode the th width property with a css class in my main stylesheet:
<table class="table-fix">
<thead>
<tr>
<th class="table-header-fix2">...</th>
<th class="table-header-fix2">...</th>
</tr>
</thead>
.table-header-fix2{
width:12.50% !important; // 12.50 = fullScreenWidth / nr_Columns
}
I will update this answer if I manage to translate the code above into the js module
Update
If you have different table head structures in your app (for example 2 tables with 2 th and other 5 tables with 10 th) you might want to set the proper th width percentage for each table by doing a change in the fsm-sticky-header.js function setColumnHeaderSizes():
var thNumber = 0;
function setColumnHeaderSizes() {
if (clonedHeader.is('tr') || clonedHeader.is('thead')) {
var clonedColumns = clonedHeader.find('th');
thNumber = 100 / ($(".table-fix").find("tr:first th").length;
header.find('th').each(function (index, column) {
var clonedColumn = $(clonedColumns[index]);
clonedColumn.css( 'width', thNumber + '%');
});
}
};

Related

Jquery Compare table rows selected with checkbox and compare a column

i have a table that i compare row values using checkbox to see if they are the same, am using a jquery code to compare the table rows that were selected by a checkbox, it works perfectly, now what i want is to be able to exclude two columns from the comparison and compare other columns in the two selected rows
$('.ApprovalForm').submit(function(event) {
event.preventDefault(); // Prevent the form from submitting via the browser
if ($(":checkbox:checked").length < 2 || $(":checkbox:checked").length > 2) {
alert('You have to select two flights');
} else {
var form = $(this);
//get all checkboxes that are selected
var selected = $("input:checked");
//loop through your columns
var x = 0;
for (var i = 1; i <= 17; i++) {
var prev = null;
$.each($(selected), function() {
var curr = $(this).closest("tr").find("td").eq(i).text();
//if at least one value is different highlight the column
if (curr !== prev && prev !== null) {
x++;
console.log(3333);
}
prev = curr;
})
}
console.log(x);
if (x <= 0) {
$("#modal-Approve").modal('show');
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
}).done(function(response) {
$("#MessageStatus ").val(response);
location.reload();
}).fail(function(data) {
// Optionally alert the user of an error here...
alert(data);
});
} else {
alert('Selected flights are not the same, check if they are the same by using detail button');
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th style="display:none">id</th>
<th>Mission</th>
<th>First Pilot</th>
<th>Second Pilot</th>
<th>Aircraft</th>
<th>No</th>
<th style="display:none">TakeOffTime</th>
<th style="display:none">LandingTime</th>
<th style="display:none">Date</th>
</tr>
</thead>
<tbody>
<tr>
<td>test Flying</td>
<td>Juliet</td>
<td>Pascal</td>
<td>boeing 42</td>
<td>255</td>
<td>12:45</td>
<td>14:20</td> <!-- exclude this from the values that will be compared -->
<td>12/1/2020</td> <!-- exclude this too -->
<td> <input type="checkbox" name="FlightId[]"> </td>
</tr>
<tr>
<td>test Flying</td>
<td>Juliet</td>
<td>Pascal</td>
<td>boeing 42</td>
<td>255</td>
<td>12:45</td>
<td>14:30</td> <!-- exclude this from the values that will be compared -->
<td>12/2/2020</td> <!-- exclude this too -->
<td> <input type="checkbox" name="FlightId[]"> </td>
</tr>
</tbody>
</table>
so the idea is to be able to exclude some td values from the comparison
Add 'exc_toggle' class to each th in your header row
Add event listener for clicking these classes to toggle an 'exclude' data attribute
Add a hidden cell to each row in tbody so your column counts are the same between the header and tbody rows
Add to your form submit event listener to iterate over the 'exc_toggle' class and create a to_ignore index for each data-exclude = 1
Skip your comparison when i is found in your ignore index
Code below.
HTML:
<table>
<thead>
<tr id="header_row">
<th style="display:none" class="exc_toggle">id</th>
<th class="exc_toggle">Mission</th>
<th class="exc_toggle">First Pilot</th>
<th class="exc_toggle">Second Pilot</th>
<th class="exc_toggle">Aircraft</th>
<th class="exc_toggle">No</th>
<th class="exc_toggle">TakeOffTime</th>
<th class="exc_toggle">LandingTime</th>
<th class="exc_toggle">Date</th>
</tr>
</thead>
<tbody>
<tr>
<td style="display:none"></td>
<td>test Flying</td>
<td>Juliet</td>
<td>Pascal</td>
<td>boeing 42</td>
<td>255</td>
<td>12:45</td>
<td>14:20</td> <!-- exclude this from the values that will be compared -->
<td>12/1/2020</td> <!-- exclude this too -->
<td> <input type="checkbox" name="FlightId[]"> </td>
</tr>
<tr>
<td style="display:none"></td>
<td>test Flying</td>
<td>Juliet</td>
<td>Pascal</td>
<td>boeing 42</td>
<td>255</td>
<td>12:45</td>
<td>14:30</td> <!-- exclude this from the values that will be compared -->
<td>12/2/2020</td> <!-- exclude this too -->
<td> <input type="checkbox" name="FlightId[]"> </td>
</tr>
</tbody>
</table>
jQuery (in document header):
$(document).on('click', '.exc_toggle', function(){
if($(this).data('exclude') == 1)
{
$(this).data('exclude', 0);
$(this).css('background-color', '');
} else {
$(this).data('exclude', 1);
$(this).css('background-color', '#F00');
}
});
jQuery (modified ApprovalForm submit event):
$('.ApprovalForm').submit(function(event) {
event.preventDefault(); // Prevent the form from submitting via the browser
if ($(":checkbox:checked").length < 2 || $(":checkbox:checked").length > 2) {
alert('You have to select two flights');
} else {
var ignore_indices = [];
var cnt = 0;
$('.exc_toggle').each(function(){
if($(this).data('exclude') == 1)
{ignore_indices.push(cnt);}
cnt++;
});
var form = $(this);
//get all checkboxes that are selected
var selected = $("input:checked");
//loop through your columns
var x = 0;
for (var i = 1; i <= 17; i++) {
if(ignore_indices.indexOf(i) < 0)
{
var prev = null;
$.each($(selected), function() {
var curr = $(this).closest("tr").find("td").eq(i).text();
//if at least one value is different highlight the column
if (curr !== prev && prev !== null) {
x++;
console.log(3333);
}
prev = curr;
})
} else {
prev = null;
}
}
console.log(x);
if (x <= 0) {
$("#modal-Approve").modal('show');
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
}).done(function(response) {
$("#MessageStatus ").val(response);
location.reload();
}).fail(function(data) {
// Optionally alert the user of an error here...
alert(data);
});
} else {
alert('Selected flights are not the same, check if they are the same by using detail button');
}
}
});
To compare duplicate takeoff times, add the class 'takeoff' to each td in your takeoff time column, then add this jQuery:
$(document).on('change', 'input:checkbox', function(){
var takeoff = '';
$('.takeoff').css('background-color', '');
$('input:checked').each(function(){
var td_target = $(this).closest('tr').find('.takeoff');
takeoff = td_target.html();
var matches = $('input:checked').parents('tr').find('.takeoff:contains("'+takeoff+'")');
if(matches.length > 1)
{td_target.css('background-color', '#F00');}
else
{td_target.css('background-color', '');}
});
});

assign variable to an individual table cell

I am trying to put images in a table. I have that working, if you click, you cycle through the available options. However, the counter is not cell related, it is a global counter. Is there a way to make a local variable, to keep track of where that individual cell is in the array?
I have tried making a local variable, only to a single cell, but it wasn't working.
Here is the related function in js:
var i = 1;
var table = document.getElementsByTagName('table')[0];
var def = ["tex/white.png", "tex/grass.jpg", "tex/stone.jpg", "tex/water.jpg", "tex/wood.jpg", "tex/lava.jpg"];
table.onclick = function(e) {
var target = (e || window.event).target;
if (target.tagName in { TD: 1, TH: 1 }) {
target.className = "img";
console.log((e || window.event).target);
target.setAttribute('style', 'background-image:' + "url(" + def[i] + ")");
if (i < def.length) {
i++
}
if (i == def.length) {
i = 0;
}
}
};
Here is a working fiddle of what I have done so far:
https://jsfiddle.net/6L0armd4/
The desired result is that I start the array at single cells and it only counts for those cells. At the moment, it always gives the next texture, even when I select a different cell.
A possible solution : using ids to identify each cells, and an object to keep track of which background is currently used for each cells (using their id as key)
<html>
<head>
</head>
<body>
<table>
<tr>
<td id='1'></td>
<td id='2'></td>
<td id='3'></td>
</tr>
<tr>
<td id='4'></td>
<td id='5'></td>
<td id='6'></td>
</tr>
<tr>
<td id='7'></td>
<td id='8'></td>
<td id='9'></td>
</tr>
</table>
</body>
</html>
<script>
var table = document.getElementsByTagName('table')[0];
var def = ["https://cdn1.imggmi.com/uploads/2019/6/19/5e4aedcf566fa5e4501ab584d357be01-full.jpg", "https://cdn1.imggmi.com/uploads/2019/6/19/3d39445ffda6687a6b0e80a69a35fdea-full.jpg"];
var currents = {}
getNextIndex = function(index) {
return index === undefined || index >= def.length - 1 ? 0 : index + 1
}
table.onclick = function(e) {
var target = (e || window.event).target;
if (target.tagName in { TD: 1, TH: 1 }) {
var new_bg_index = getNextIndex(currents[target.id])
currents[target.id] = new_bg_index
target.setAttribute('style', 'background-image:' + "url(" + def[new_bg_index] + ")");
}
};
</script>
you need to make listener event
you may change the color codes to your image path on the below code and avoid any local path image links issue try to use online images direct ones .
var table = document.querySelector('#table')
var selectedCells = table.getElementsByClassName('selected')
table.addEventListener('click', function(e) {
var td = e.target
if (td.tagName !== 'TD') {
return
}
if (selectedCells.length) {
selectedCells[0].className = ''
}
td.className = 'selected'
})
table {
cursor: text;
}
tr {
background-color:white;
}
td {
font-size: 14;
cursor: default;
}
td.selected {
background-color: red;
// replace this with background image tag like this
background-image: url("paper.gif
<table border="1" cellpadding="8" cellspacing="2" id="table">
<tr>
<td>Cell one</td>
<td>Cell Tw</td>
<td>Cell three</td>
<td>Cell Four</td>
<td>Cell five</td>
<td>Cell sex</td>
<td>Cell five</td>
<td>cell seven</td>
<td>cell eight</td>
<td>cell nine</td>
<td>cell tens</td>
<td>cell eleven</td>
<td>cell twelve</td>
</tr>
<tr>
<td>AKo</td>
<td>KK</td>
<td>KQs</td>
<td>KJs</td>
<td>KTs</td>
<td>K9s</td>
<td>K8S</td>
<td>K7s</td>
<td>K6s</td>
<td>K5s</td>
<td>K4s</td>
<td>K3s</td>
<td>K2s</td>

Why is the total not updating when a new value is place in the number input

Here is what I have so far but I'm stuck because I cannot get the input elements to change the amount when the number of the quantity is changed.
function calculateTotal(quantity, price) {
var total = quantity * price;
return total;
}
function makeRow() {
var i = 0;
for (i = 0; i < 3; i++) {
var total = calculateTotal(quantities[i], prices[i]);
outputCartRow(filenames[i], titles[i], quantities[i], prices[i], total);
}
}
function outputCartRow(file, title, quantity, price, total) {
var content = "<tr><td><img src='" + file + "' class='photo' /></td>";
content += "<td>" + title + "</td>";
content += "<td><input class='quant' type='number' value='1'
onchange = 'newAmount' / > < /td>";
content += "<td>" + price + "</td>";
content += "<td class='amount'>" + total + "</td></tr>";
var section = document.querySelector(".rows").innerHTML;
document.querySelector(".rows").innerHTML = section + content;
}
function newAmount() {
var quantity = document.getElementsByClassName("quant");
var quantity1 = quantity[0];
var quantity2 = quantity[1];
var quantity3 = quantity[2];
var amount1 = calculateTotal(quantity1, 80);
var amount2 = calculateTotal(quantity2, 125);
var amount3 = calculateTotal(quantity3, 75);
var items = document.getElementsByClassName("amount");
for (var i = 0; i < items.length; i++) {
items[i] = amount1;
}
}
$(document).ready(function() {
$("input").change(function() {
alert("The text has been changed.");
});
});
js data;
var filenames = ["images/106020.jpg", "images/116010.jpg", "images/120010.jpg"];
var titles = ["Girl with a Pearl Earring", "Artist Holding a Thistle", "Portrait of Eleanor of Toledo"];
var quantities = [1, 1, 1];
var prices = [80, 125, 75];
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1.0,maximum-
scale=1.0,width=device-width">
<title>Chapter 08 - Project 01</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="css/styles.css" rel="stylesheet" />
<script src="js/data.js" type="text/JavaScript"></script>
<script src="js/functions.js" type="text/JavaScript"></script>
</head>
<body onload="makeRow();">
<div class="title">
<h1>Shopping Cart</h1>
</div>
<table class="table-fill">
<thead>
<tr>
<th colspan="2">Product</th>
<th>#</th>
<th>Price</th>
<th>Amount</th>
</tr>
</thead>
<tbody class="rows">
<tbody>
<tr class="totals">
<td colspan="4">Subtotal</td>
<td>$515.00</td>
</tr>
<tr class="totals">
<td colspan="4">Tax</td>
<td>$51.50</td>
</tr>
<tr class="totals">
<td colspan="4">Shipping</td>
<td>$40.00</td>
</tr>
<tr class="totals focus">
<td colspan="4">Grand Total</td>
<td>$606.50</td>
</tr>
</tbody>
</table>
</body>
</html>
<form> tag
IMO if using more than one form controlāœ± on a page, a <form> tag should be wrapped around everything. There are several advantages when you use a <form> tag:
HTMLFormControlsCollection and HTMLFormElement interface allows us to access form controls with a simple and terse syntax. Compare:
Common Procedure
// Reference <form> by #id
var main = document.getElementById('main');
// Collect radio buttons into a NodeList and convert it into an array
var radios = Array.from(document.querySelectorAll('[name=rad]'));
// Reference <button> by tagName
var button = document.querySelector('button');
HTMLForm | ControlsCollection | Element Interfaces
// Reference <form> by #id or [name]
var main = document.forms.main;
// Collect radio buttons into a HTMLCollection and convert it into an array
var radios = Array.from(main.elements.rad);
// Reference <button> by index
var button = main.elements[4];
Demo
Details commented in demo
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0,maximum-
scale=1.0,width=device-width">
<title>Chapter 08 - Project 01</title>
<style>
html,
body {
font: 400 16px/1.4 Consolas;
}
caption {
font-weight: 700;
font-size: 1.2rem;
}
table {
table-layout: fixed;
border-spacing: 7px;
}
th {
border-bottom: 3px ridge grey;
}
tfoot tr:nth-child(3) td:nth-child(2),
tfoot tr:nth-child(3) td:nth-child(1) {
border-bottom: 4px ridge grey;
}
.totals tr td,
tbody tr td:nth-of-type(3),
tbody tr td:nth-of-type(4),
tbody tr td:last-of-type,
tfoot tr td {
text-align: right;
}
td.cap {
text-align: left;
}
output::before {
content: '$';
}
input {
display: block;
width: 6ch;
text-align: center;
font: inherit;
}
</style>
</head>
<body>
<form id='cart'>
<table>
<caption>Shopping Cart</caption>
<thead>
<tr>
<th colspan="2">Product</th>
<th>Qty</th>
<th width='10%'>Price</th>
<th width='20%'>Amount</th>
</tr>
</thead>
<tbody class="rows"></tbody>
<tfoot class="totals">
<tr>
<td colspan="4">Subtotal</td>
<td><output id='sub'></output></td>
</tr>
<tr>
<td colspan="4">Tax (8.25%)</td>
<td><output id='tax' data-tax='.0825'></output></td>
</tr>
<tr>
<td colspan="4">Shipping ($3.00)</td>
<td><output id='SH'></output></td>
</tr>
<tr>
<td colspan="4">Grand Total</td>
<td><output id='grand'></output></td>
</tr>
</tfoot>
</table>
</form>
<script>
// Reference the <form>
var form = document.forms.cart;
// Data arrays
var imgArr = ["https://i.ibb.co/ZHvWsKb/o1z7p.jpg", "https://i.ibb.co/ZHvWsKb/o1z7p.jpg", "https://i.ibb.co/ZHvWsKb/o1z7p.jpg"];
var capArr = ["Girl with a Pearl Earring", "Artist Holding a Thistle", "Portrait of Eleanor of Toledo"];
var qtyArr = [0, 0, 0];
var prcArr = [80.69, 124.99, 75.00];
/*
setRow() -- passes an index counter and 4 variables
- Creates a template literal of a <tr>
- Interpolates variables into TL
- Parses the TL as HTML
*/
function setRow(i, img, cap, qty, prc) {
var R = `<tr id='R${i}'>
<td><img class='img' src='${img}' width='50px'></td>
<td class='cap'>${cap}</td>
<td><input id='qty${i}' class='qty' type='number' min='0' max='99'></td>
<td><output id='prc${i}' class='prc'></output></td>
<td><output id='amt${i}' class='amt'></output></td>
</tr>`;
var rows = document.querySelector('.rows');
rows.insertAdjacentHTML('beforeend', R);
var rID = document.getElementById('R' + i);
rID.children[2].children[0].value = qty;
rID.children[3].children[0].value = prc.toFixed(2);
rID.children[4].children[0].value = (parseFloat(qty) * parseFloat(prc)).toFixed(2);
}
/*
overRide() -- passes a 3D array
- Iterates through the 3D array
- On each iteration it passes array elements to the
setRow() function
*/
function overRide(x3DArray) {
var img, cap, qty, prc;
for (let x = 0; x < x3DArray[0].length; x++) {
img = x3DArray[0][x];
cap = x3DArray[1][x];
qty = x3DArray[2][x];
prc = x3DArray[3][x];
var cart = setRow(x, img, cap, qty, prc);
}
}
/*
calcAmt() callback function -- passes the Event Object
- Reference the tag receiving the user data (input.qty)
- Reference the tag registered to event (form#cart)
- Collect all form controls into a HTMLCollection
*/
/*
- if the clicked tag is NOT the registered tag...
- if the clicked tag has the .qty class...
- Reference the <tr> the clicked tag is nested in...
...get the index of <tr>...
...get the values of qty and prc...
...set the amt by qty x prc
*/
/*
- Collects all .amt into a NodeList then converts into an array.
- map() the array and extract each .amt value
- reduce() the array values into a single sum
- Set the .totals column values to calculate totals when the user enters data.
*/
function calcAmt(event) {
var tgt = event.target;
var cur = event.currentTarget;
var UI = this.elements;
if (tgt !== cur) {
if (tgt.className === 'qty') {
var rID = tgt.closest('tr').id;
var idx = rID.split('').slice(1).join('');
var qty = tgt.value;
var prc = UI['prc' + idx].value;
UI['amt' + idx].value = (parseFloat(qty) * parseFloat(prc)).toFixed(2);
var amtArray = Array.from(document.querySelectorAll('.amt'));
var subVal = amtArray.map(function(sub) {
return parseFloat(sub.value);
});
var amtVal = subVal.reduce(function(acc, cur) {
return acc + cur;
}, 0);
UI.sub.value = amtVal.toFixed(2);
UI.tax.value = (parseFloat(UI.sub.value) * parseFloat(UI.tax.dataset.tax)).toFixed(2);
UI.SH.value = (3).toFixed(2);
UI.grand.value = (parseFloat(UI.sub.value) + parseFloat(UI.tax.value) + parseFloat(UI.SH.value)).toFixed(2);
}
}
}
/*
Register the input event to the <form>
When user enters data to input.qty the callback
function calcAmt() is called
*/
form.addEventListener('input', calcAmt);
/*
This is a 3D array of the data arrays which will be
passed to the function overRide()
*/
var table = [
[...imgArr],
[...capArr],
[...qtyArr],
[...prcArr]
];
// Call the overRide() function -- pass the table array
overRide(table);
</script>
</body>
</html>

sorting html table with jquery

I have a table in html, I have set for each td an id that I will need to sort the table with a Jquery code.
Sorting works with the FireFox browser, but with Chrome it does not work ... do you know how to help me?
$(function() {
$(".table-user-th").click(function() {
var o = $(this).hasClass('asc') ? 'desc' : 'asc';
$('.table-user-th').removeClass('asc').removeClass('desc');
$(this).addClass(o);
var colIndex = $(this).prevAll().length;
var tbod = $(this).closest("table").find("tbody");
var rows = tbod.find("tr");
rows.sort(function(a, b) {
var A = $(a).find("td").eq(colIndex).attr('id');;
var B = $(b).find("td").eq(colIndex).attr('id');;
if (!isNaN(A)) A = Number(A);
if (!isNaN(B)) B = Number(B);
return o == 'asc' ? A > B : B > A;
});
$.each(rows, function(index, ele) {
tbod.append(ele);
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1">
<thead>
<tr>
<th class="table-user-th">Firstname</th>
<th class="table-user-th">Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td id="Mark">Mark</td>
<td id="Red">Red</td>
</tr>
<tr>
<td id="Nick">Nick</td>
<td id="Sid">Sid</td>
</tr>
<tr>
<td id="Alex">Alex</td>
<td id="Nirv">Nirv</td>
</tr>
</tbody>
</table>
It seems like there is no purpose of using ids here.
Actually the problem was in you sort function. It should return not just true/false but the numeric difference between two values. As usual it is return -1/0/1
So here I wrote comparator func that does just that. And depending on sort type I just multiply it on -1 or 1.
I've also refactored a little bit your code not to use classes or ids. Using jquery you can use data method that stores data on element by key/value.
$(function() {
function cmp(a,b) {return a < b ? 1 : a > b ? -1 : 0}
$(".sortable-table").on('click', 'th', function() {
var th = $(this);
var colIndex = th.data('column');
if(typeof colIndex === 'undefined') {
return;
}
var sortType = th.data('sort') === 'asc' ? 'desc' : 'asc';
th.data('sort', sortType);
var table = $(this).closest("table");
table.find('thead th').removeClass('asc desc');
th.addClass(sortType);
var tbody = table.find("tbody");
var rows = tbody.find("tr");
rows.sort(function(a, b) {
var A = $(a).find("td").eq(colIndex).text();
var B = $(b).find("td").eq(colIndex).text();
return cmp(A,B) * (sortType === 'asc' ? -1 : 1);
});
$.each(rows, function(index, ele) {
tbody.append(ele);
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" class="sortable-table">
<thead>
<tr>
<th data-column="0">Firstname</th>
<th data-column="1">Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mark</td>
<td>Red</td>
</tr>
<tr>
<td>Nick</td>
<td>Sid</td>
</tr>
<tr>
<td>Alex</td>
<td>Nirv</td>
</tr>
</tbody>
</table>
Update
Added
var table = $(this).closest("table");
table.find('thead th').removeClass('asc desc');
th.addClass(sortType);

dynamic pricing table list

i am writing a code to select/remove the product from display table, and when the product is selected,then product with its price mus be displayed in some other table where at the end sum total is also needed which get updated as per selected product prices
<table id="table-example" class="table">
<thead>
<tr>
<th>Cause</th>
<th>Monthly Charge</th>
</tr>
</thead>
<tbody>
<tr>
<div id="selectedServices"></div>
<td id="myDiv"></td>
</tr>
</tbody>
</table>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<table id="table-example" class="table">
<thead>
<tr>
<th>Cause</th>
<th>Monthly Charge</th>
</tr>
</thead>
<div>
<tbody>
<p>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>table</label>
</td>
<td>80</td>
</tr>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>chair</label>
</td>
<td>45</td>
</tr>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>set</label>
</td>
<td>10</td>
</tr>
</tbody>
</div>
</table>
script
$(function() {
$(":checkbox").change(function() {
var arr = $(":checkbox:checked").map(function() { return $(this).next().text(); }).get();
$("#myDiv").text(arr.join(','));
});
});
function ToggleBGColour(item) {
var td = $(item).parent();
if (td.is('.rowSelected'))
td.removeClass("rowSelected");
else
td.addClass("rowSelected");
}
Here is the corresponding fiddle.
Based on your comment for my other answer, this should work for you then:
$(":checkbox").change(function () {
// Toggle class of selected row
$(this).parent().toggleClass("rowSelected");
// Get all items name, sum total amount
var sum = 0;
var arr = $(":checkbox:checked").map(function () {
sum += Number($(this).parents('tr').find('td:last').text());
return $(this).parents('tr').clone();
}).get();
// Display selected items and their sum
$("#selectedServices").html(arr).find('input').remove();
$("#total").text(sum);
});
This avoids the need for creating new HTML elements in the JavaScript code, and reduces the number of .maps() and .each() loops to one.
http://jsfiddle.net/samliew/uF2Ba/
Here is the javascript for but u need to remove onClick attrs :
$(function() {
$(":checkbox").change(function() {
ToggleBGColour(this);
var arr = $(":checkbox:checked").map(function() {
return $(this).next().text();
}).get();
var nums = $(":checkbox:checked").map(function() {
return parseInt($(this).parent().next().html());
}).get();
var total = 0;
for (var i = 0; i < nums.length; i++) {
total += nums[i] << 0;
}
$("#myDiv").text(arr.join(',') + 'total : '+total);
});
});
function ToggleBGColour(item) {
var td = $(item).parent();
if (td.is('.rowSelected'))
td.removeClass("rowSelected");
else
td.addClass("rowSelected");
}
I updated your fiddle with my answer : http://jsfiddle.net/A2SKr/9/
Here's what i've changed.
Slightly better formatted.
i removed the onclick attribute. Its bad practice to use this because of performance issues. Use delegates
Ive also changed a lil bit of your HTML. the output is now a table
added a total element to the output as well
javascript code :
$(":checkbox").change(function () {
var total = 0;
var check = $(":checkbox:checked");
var causes = check.map(function () {
return $(this).next().text();
}).get();
var costs = check.map(function () {
return $(this).parent().next().text()
}).get();
var tbody = $("#table-example tbody").empty();
$.each(causes, function (i, cause) {
tbody.append("<tr><td>" + cause + "</td><td id='" + i + "'><td/></tr>");
});
$.each(costs, function (i, cost) {
$('#' + i + '').html(cost);
total += parseInt(cost, 10);
});
tbody.append("<tr><td>Total</td><td>" + total + "<td/></tr>");
});
});

Categories