Javascript function not working - javascript

My jsp page contains a table ,the code for the same is given below:
<table width="400" border="1" cellpadding="0" cellspacing="1" id="student_table">
<thead>
<tr>
<th scope="row">ID</th>
<th scope="row">Name</th>
<th scope="row">Country</th>
<th scope="row">Marks</th>
<th scope="row">Rank</th>
</tr>
<tbody>
<tr>
<td>1</td>
<td>Smith</td>
<td>US</td>
<td><input type="text" name="marks" value="40"/></td>
<td>20</td>
</tr>
<tr>
<td>2</td>
<td>John</td>
<td>England</td>
<td><input type="text" name="marks" value="80"/></td>
<td>29</td>
</tr>
<tr>
<td>3</td>
<td>William</td>
<td>Australia</td>
<td><input type="text" id="nm" name="marks" value="60" onblur="return(myFunction1())"/></td>
<td>33</td>
</tr>
<tr>
<td>4</td>
<td>Michael</td>
<td>Germany</td>
<td><input type="text" name="marks" value="90"/></td>
<td>29</td>
</tr>
I have a javascript function which compares the values in two cells. But the javascript function is not working. I cannot find out why. Please anyone help me with a solution. I know that there are other ways to validate. but i need to get it done this way. This is an example of a big program which i need to get done in this way. Please help
function myfunction11(){
var myTable = document.getElementById('student_table').tBodies[0];
// first loop for each row
for (var r=0, n = myTable.rows.length; r < n; r++) {
// this loop is getting each colomn/cells
for (var c = 0, m = myTable.rows[r].cells.length; c < m; c++) {
if(myTable.rows[r].cells[c].childNodes[0].value){
var rank = myTable.rows[r].cells[4].innerText;
var marks = myTable.rows[r].cells[c].childNodes[0].value;
if(rank>marks){
alert("rank cannot be greater than marks:"+marks);
myTable.rows[r].cells[c].childNodes[0].value="0";
return false;
}
}
}
}
return true;
}

In your HTML, you have:
onblur="return(myFunction1())
but your actual function's name is:
myfunction11()
Once the names are matched, your function runs. But, you do have one (at least) issue with your code. You are comparing rank > marks but marks comes from an input field. All HTML data is strings, so you must convert that string to a number to do any kind of mathematical operation on it. Also, innerText is non-standard code, use textContent instead. See comments in code.
function myFunction1(){
var myTable = document.getElementById('student_table').tBodies[0];
// first loop for each row
for (var r=0, n = myTable.rows.length; r < n; r++) {
// this loop is getting each colomn/cells
for (var c = 0, m = myTable.rows[r].cells.length; c < m; c++) {
if(myTable.rows[r].cells[c].childNodes[0].value){
// All HTML data is strings. If you expect a number, you have to convert it.
// Also, use textContent to get the text of an element. innerText is non-standard
var rank = parseInt(myTable.rows[r].cells[4].textContent,10);
var marks = parseInt(myTable.rows[r].cells[c].childNodes[0].value, 10);
if(rank > marks){
alert("rank cannot be greater than marks: " + marks);
myTable.rows[r].cells[c].childNodes[0].value = "0";
return false;
}
}
}
}
return true;
}
<table width="400" border="1" cellpadding="0" cellspacing="1" id="student_table">
<thead>
<tr>
<th scope="row">ID</th>
<th scope="row">Name</th>
<th scope="row">Country</th>
<th scope="row">Marks</th>
<th scope="row">Rank</th>
</tr>
<tbody>
<tr>
<td>1</td>
<td>Smith</td>
<td>US</td>
<td><input type="text" name="marks" value="40"/></td>
<td>20</td>
</tr>
<tr>
<td>2</td>
<td>John</td>
<td>England</td>
<td><input type="text" name="marks" value="80"/></td>
<td>29</td>
</tr>
<tr>
<td>3</td>
<td>William</td>
<td>Australia</td>
<td><input type="text" id="nm" name="marks" value="60" onblur="return(myFunction1())"/></td>
<td>33</td>
</tr>
<tr>
<td>4</td>
<td>Michael</td>
<td>Germany</td>
<td><input type="text" name="marks" value="90"/></td>
<td>29</td>
</tr>
</table>
Now, to correct your code and have it use modern standards so that it works when you leave any of the fields, we'd write:
// Don't use inline HTML event handling attributes like "onclick", "onblur", etc.
// Instead, use modern standards of separating all your JavaScript from your HTML
// Get a collection of all the input fields. There are many ways to do this, but here
// we are getting all the elements that use the marks class (HTML adjusted above)
var inputs = document.querySelectorAll(".marks");
// Loop through the collection and assign the checkMarks function as the blur event
// callback funciton to each of them.
for(var i = 0; i < inputs.length; i++){
inputs[i].addEventListener("blur", checkMarks);
}
function checkMarks(evt){
// Just check the marks and the rank next to it
// All HTML data is strings. If you expect a number, you have to convert it.
// The parseInt() function can extract numbers from a string.
// Also, use textContent to get the text of an element. innerText is non-standard
// All event handling functions automatically recieve an argument representing the
// event that they are responding to (evt in this case). That event object, in turn,
// has a property (target) that references the element that triggered the event in the
// first place. To get to the table cell that comes after an input field, we start at
// the input field (evt.target) and then get the parent element of that (the <td> element
// that the input is inside of) and then the next element that is a sibling of that (the <td>
// that contains the rank.
var rank = parseInt(evt.target.parentNode.nextElementSibling.textContent, 10);
// To get the value of the input, just look at evt.target's value
var marks = parseInt(evt.target.value, 10);
if(rank > marks){
alert("rank cannot be greater than marks: " + marks);
evt.target.value = "0";
}
}
<table width="400" border="1" cellpadding="0" cellspacing="1" id="student_table">
<thead>
<tr>
<th scope="row">ID</th>
<th scope="row">Name</th>
<th scope="row">Country</th>
<th scope="row">Marks</th>
<th scope="row">Rank</th>
</tr>
<tbody>
<!-- Form elements should generally have unique names so you can tell them apart when
they submit their data. -->
<tr>
<td>1</td>
<td>Smith</td>
<td>US</td>
<td><input type="text" class="marks" name="US_Marks" value="40"/></td>
<td>20</td>
</tr>
<tr>
<td>2</td>
<td>John</td>
<td>England</td>
<td><input type="text" class="marks" name="England_Marks" value="80"/></td>
<td>29</td>
</tr>
<tr>
<td>3</td>
<td>William</td>
<td>Australia</td>
<td><input type="text" id="nm" class="marks" name="Austrailia_Marks" value="60"></td>
<td>33</td>
</tr>
<tr>
<td>4</td>
<td>Michael</td>
<td>Germany</td>
<td><input type="text" class="marks" name="Germany_Marks" value="90"/></td>
<td>29</td>
</tr>
</table>

try changing onblur="return(myFunction1())" to onblur="return(myFunction11())"

Related

JS/jQuery: Copying Contents of td to clipboard

I'm working on a project where I have a table full of first names, last names, and e-mail addresses. The last td should be a button that allows the user to copy that particular person's e-mail address to the clipboard.
Also yes, I'm aware this is in old-school JS, I'm working on a legacy project.
Here's my code on codepen.io: https://codepen.io/anfperez/pen/ZZdwWL
HTML
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>E-mail</th>
<th>Button</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td id="email">jsmith#whatever.com</td>
<td><button>Click to Copy</button></td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td id="email">ejackson#whatever.com</td>
<td><button>Click to Copy</button></td>
</tr>
</table>
JS
function copyToClipboard() {
var copyText = document.getElementById("email")
copyText.select();
document.execCommand("copy");
alert("Copied the text: " + copyText.value);
}
So, I have two dilemmas:
1) how can I get each button generated to copy the correct e-mail address (not just one or all of them)? I need to assign unique IDs to each entry it seems, but I don't really know how to start generating those if the list gets longer.
2) I keep getting the error that "copyText.select() is not a valid function". I've been following several tutorials in which this method is used, so I'm not sure why it's not working here.
As Robin Zigmond says, you need to change id="email" to class="email" to be able to find the correct TD, and because each id must be unique.
Once you have done that, you can add an event listener to each button programmatically, and within the listener find the email TD with the email classname.
Selecting text only works in elements that can have text input (i.e. textarea and input type="text"), so you need to create a temporary element to put the text into, and copy it from there.
(function()
{
let buttons = document.getElementsByTagName('Button');
for(let i = 0; i < buttons.length; i++)
{
let button = buttons[i];
button.addEventListener('click', e =>
{
let button = e.target;
let email = button.parentNode.parentNode.getElementsByClassName('email')[0].innerHTML;
let text = document.createElement('input');
text.setAttribute('type', 'text');
text.value = email;
document.body.appendChild(text);
text.select();
document.execCommand('copy');
document.body.removeChild(text);
});
}
})();
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>E-mail</th>
<th>Button</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td class="email">jsmith#whatever.com</td>
<td><button>Click to Copy</button></td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td class="email">ejackson#whatever.com</td>
<td><button>Click to Copy</button></td>
</tr>
</table>
I have modified your Codepen code.
Here is a working example.
document.querySelectorAll('button[data-type="copy"]')
.forEach(function(button){
button.addEventListener('click', function(){
let email = this.parentNode.parentNode
.querySelector('td[data-type="email"]')
.innerText;
let tmp = document.createElement('textarea');
tmp.value = email;
tmp.setAttribute('readonly', '');
tmp.style.position = 'absolute';
tmp.style.left = '-9999px';
document.body.appendChild(tmp);
tmp.select();
document.execCommand('copy');
document.body.removeChild(tmp);
console.log(`${email} copied.`);
});
});
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>E-mail</th>
<th>Button</th>
</tr>
<tr>
<td>Jill</td>
<td>Smith</td>
<td data-type="email">jsmith#whatever.com</td>
<td><button data-type="copy">Click to Copy</button></td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td data-type="email">ejackson#whatever.com</td>
<td><button data-type="copy">Click to Copy</button></td>
</tr>
<tr>
<td>Eve1</td>
<td>Jackso1n</td>
<td data-type="email">ejackssdfon#whafdstever.com</td>
<td><button data-type="copy">Click to Copy</button></td>
</tr>
<tr>
<td>Eve2</td>
<td>Jackson2</td>
<td data-type="email">asdas#whasdftever.com</td>
<td><button data-type="copy">Click to Copy</button></td>
</tr>
</table>
This source can be helpful as well source

How to get multiple selected cell array values with checkbox in jquery, then send with ajax post

How should I get an array value from a table cell when clicking checkbox with jQuery? If I've selected cell 1, I want to get array like ["BlackBerry Bold", "2/5", "UK"], but if I've selected all of them, I want to get all the data in the form of an array of arrays.
<table border="1">
<tr>
<th><input type="checkbox" /></th>
<th>Cell phone</th>
<th>Rating</th>
<th>Location</th>
</tr>
<tr>
<td align="center"><input type="checkbox"/></td>
<td>BlackBerry Bold 9650</td>
<td>2/5</td>
<td>UK</td>
</tr>
<tr>
<td align="center"><input type="checkbox" /></td>
<td>Samsung Galaxy</td>
<td>3.5/5</td>
<td>US</td>
</tr>
<tr>
<td align="center"><input type="checkbox"/></td>
<td>Droid X</td>
<td>4.5/5</td>
<td>REB</td>
</tr>
Please help.
Onclick get 3 children of the parent and add content to data. Used jquery nextAll for siblings and splice the 3 required.
Attached event to the table, onclick will check if element is INPUT.
If it's input, will get parent of that input which will be <td>.
For this parent element, will get three siblings using jquery.
Will add in selected if not present else delete, using indexOf.
CodePen for you to playaround: [ https://codepen.io/vivekamin/pen/oQMeXV ]
let selectedData = []
let para = document.getElementById("selectedData");
let tableElem = document.getElementById("table");
tableElem.addEventListener("click", function(e) {
if(e.target.tagName === 'INPUT' ){
let parent = e.target.parentNode;
let data = [];
$(parent).nextAll().map(function(index, node){
data.push(node.textContent);
})
let index = selectedData.indexOf(JSON.stringify(data))
if(index == -1){
selectedData.push(JSON.stringify(data));
}
else{
selectedData.splice(index,1);
}
para.textContent = "";
para.innerHTML = selectedData ;
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table border="1" id="table">
<tr>
<th><input type="checkbox" /></th>
<th>Cell phone</th>
<th>Rating</th>
<th>Location</th>
</tr>
<tr>
<td align="center"><input type="checkbox"/></td>
<td>BlackBerry Bold 9650</td>
<td>2/5</td>
<td>UK</td>
</tr>
<tr>
<td align="center"><input type="checkbox" /></td>
<td>Samsung Galaxy</td>
<td>3.5/5</td>
<td>US</td>
</tr>
<tr>
<td align="center"><input type="checkbox"/></td>
<td>Droid X</td>
<td>4.5/5</td>
<td>REB</td>
</tr>
</table>
<h3> Selected Data: </h3>
<p id="selectedData"></p>
Updated to meet your needs.
create a function to build the array values based on looking for any checked inputs then going to their parents and grabbing the sibling text values
attach your change event to the checkbox click even.
I provided a fiddle below that will output the array in the console.
function buildTheArray(){
var thearray = [];
$("input:checked").parent().siblings().each(function(){
thearray.push($(this).text());
});
return thearray;
}
$("input[type='checkbox']").change(function(){
console.log(buildTheArray());
});
Fiddle:
http://jsfiddle.net/gcu4L5p6/

How to change the node when blur event occur?

Source HTML structure.
<table>
<tr>
<td>class</td>
<td><input type="text" id="data1"></td>
</tr>
<tr>
<td>name</td>
<td><input type="text" id="data2"></td>
</tr>
</table>
Event: The Source HTML struture turns into the Target HTML struture after typing test1 in input whose id is data1 and mouse focus go out of the input.
Target HTML structure.
<table>
<tr>
<td>class</td>
<td>test1</td>
</tr>
<tr>
<td>name</td>
<td><input type="text" id="data2"></td>
</tr>
</table>
Here is my JS.
function changeNode(event){
ob =document.activeElement;
_str = ob.value;
ob.parentNode.removeChild(ob);
ob.parentNode.innerText = _str;
}
document.addEventListener("blur",changeNode,true);
Why my JS can't achieve my expected target?
How to fix it?
You are selecting the active element while the event is that an object's focus is lost.
You should select event.target as ob and your code should work:
Also: you don't need to delete the object, your overriding all inner text so the object is automatically deleted.
function changeNode(event){
ob = event.target;
_str = ob.value;
ob.parentNode.innerText = _str;
}
document.addEventListener("blur",changeNode,true);
<table>
<tr>
<td>class</td>
<td><input type="text" id="data1"></td>
</tr>
<tr>
<td>name</td>
<td><input type="text" id="data2"></td>
</tr>
</table>
Several problems in your code:
You need to add the event listener to the input itself, not the document object. You can then simply use event.target instead of activeElement (input is no longer active after the blur event…)
You're trying to access ob.parentNode after removing ob. Try storing it in a variable first:
function changeNode(event) {
var ob = event.target;
var cell = ob.parentNode;
var _str = ob.value;
cell.removeChild(ob);
cell.innerText = _str;
}
document.querySelectorAll("input").forEach(function(input) {
input.addEventListener("blur", changeNode);
});
<table>
<tr>
<td>class</td>
<td><input type="text" id="data1"></td>
</tr>
<tr>
<td>name</td>
<td><input type="text" id="data2"></td>
</tr>
</table>
Note: querySelectorAll(…).forEach
might not be reliable in some old browsers, if you need to support them, see css-tricks.com: Loop Over querySelectorAll Matches
function changeNode(event){
var ob=event.target;
ob.parentNode.append(ob.value);
ob.parentNode.removeChild(ob);
}
document.getElementById("data1").addEventListener("blur",changeNode,true);
<table>
<tr>
<td>class</td>
<td><input type="text" id="data1"></td>
</tr>
<tr>
<td>name</td>
<td><input type="text" id="data2"></td>
</tr>
</table>
function changeNode(event) {
var ob = event.target;
var cell = ob.parentNode;
var _str = ob.value;
cell.removeChild(ob);
cell.innerText = _str;
}
document.addEventListener("blur",changeNode,true);

JQuery: Identify duplicate values in a table textbox column and highlight the textboxes

I'm using JQuery and I'm sure this is pretty simple stuff but I was unable to find a solution. I have an employee table with "Number" column which is editable(text box). I want to find the duplicates in the "Number" column and highlight those textboxes. For example in the table below I want to highlight all textboxes with values 10 and 20. Also when a edit is done and there are no longer duplicates, remove the highlight.
Here's the JSFiddle
Any Ideas?
<table id="employeeTable">
<tr>
<th>Id</th>
<th>Name</th>
<th>Number</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Sally</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td>10</td>
</tr>
<tr>
<td>4</td>
<td>Sam</td>
<td>30</td>
</tr>
<tr>
<td>5</td>
<td>Chris</td>
<td>20</td>
</tr>
</table>
There are different possibilities, basically you'll have to test if the value of an array exists more than one time, for example like this.
Update:
Using the value selector works fine in the initial state, but it seems that when a value is changed by direct user input or by calling .val(), the HTML attribute value is not changed (only the native JS .value). Therefore - to use the value selector in this context, the html value attribute is always updated with the JS .value.
function highlightDuplicates() {
// loop over all input fields in table
$('#employeeTable').find('input').each(function() {
// check if there is another one with the same value
if ($('#employeeTable').find('input[value="' + $(this).val() + '"]').size() > 1) {
// highlight this
$(this).addClass('duplicate');
} else {
// otherwise remove
$(this).removeClass('duplicate');
}
});
}
$().ready(function() {
// initial test
highlightDuplicates();
// fix for newer jQuery versions!
// since you can select by value, but not by current val
$('#employeeTable').find('input').bind('input',function() {
$(this).attr('value',this.value)
});
// bind test on any change event
$('#employeeTable').find('input').on('input',highlightDuplicates);
});
Updated fiddle is here.
I guess this is what you are exactly looking for:
Working : Demo
1) First for loop for taking all input values into an array inpValArr[]
2) Second for loop for sorting and finding out the duplicate ones.
3) Third for loop for adding class .highLight to duplicate ones.
Now all this is in a function: inputCheck() which is called on DOM Ready and after you edit the text field.
inputCheck();
$("#employeeTable input").bind("change paste keyup", function() {
inputCheck();
});
function inputCheck() {
var totalInp = $("#employeeTable input").length;
var inpValArr = [];
for (var j = 0; j < totalInp; j++) {
var inpVal = $("#employeeTable input:eq(" + j + ")").val();
inpValArr.push(inpVal);
}
var sorted_arr = inpValArr.sort();
var results = [];
for (var i = 0; i < inpValArr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
$('#employeeTable input').removeClass('highLight');
for (var k = 0; k < totalInp; k++) {
$('#employeeTable :input[value="' + results[k] + '"]').addClass('highLight');
}
}
#employeeTable th,
#employeeTable td {
padding: 0.8em;
border: 1px solid;
}
#employeeTable th {
background-color: #6699FF;
font-weight: bold;
}
.highLight {
background: red;
}
<table id="employeeTable">
<tr>
<th>Id</th>
<th>Name</th>
<th>Number</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>
<input type="text" value="10" />
</td>
</tr>
<tr>
<td>2</td>
<td>Sally</td>
<td>
<input type="text" value="20" />
</td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td>
<input type="text" value="10" />
</td>
</tr>
<tr>
<td>4</td>
<td>Sam</td>
<td>
<input type="text" value="30" />
</td>
</tr>
<tr>
<td>5</td>
<td>Chris</td>
<td>
<input type="text" value="20" />
</td>
</tr>
</table>
You could easily give a class such as 'hasInput' to all td with inputs and then try a .each on all of them and check for value if they are 10 or 20 and then add a class to make them styled as you wish.
html:
<table id="employeeTable">
<tr>
<th>Id</th>
<th>Name</th>
<th>Number</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td class="hasInput"><input type="text" value = "10"/></td>
</tr>
<tr>
<td>2</td>
<td>Sally</td>
<td class="hasInput"><input type="text" value = "20"/></td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td class="hasInput"><input type="text" value = "10"/></td>
</tr>
<tr>
<td>4</td>
<td>Sam</td>
<td class="hasInput"><input type="text" value = "30"/></td>
</tr>
<tr>
<td>5</td>
<td>Chris</td>
<td class="hasInput"><input type="text" value = "20"/></td>
</tr>
css:
#employeeTable th, #employeeTable td{
padding:0.8em;
border: 1px solid;
}
#employeeTable th{
background-color:#6699FF;
font-weight:bold;
}
.colored {
background-color: red;
}
js:
$('.hasInput > input').each(function() {
if ($(this).val() == 10 || $(this).val() == 20) {
$(this).addClass('colored');
}
});
DEMO
This would work:
var dupes=[], values=[];;
$('.yellow').removeClass('yellow');
$('#employeeTable td:nth-child(3) input').each(function(){
if($.inArray($(this).val(),values) == -1){
values.push($(this).val());
}
else{
dupes.push($(this).val());
}
});
$('#employeeTable td:nth-child(3) input').filter(function(){return $.inArray(this.value,dupes) == -1 ? false : true }).addClass('yellow');
#employeeTable th, #employeeTable td{
padding:0.8em;
border: 1px solid;
}
#employeeTable th{
background-color:#6699FF;
font-weight:bold;
}
.yellow{
background-color:yellow;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="employeeTable">
<tr>
<th>Id</th>
<th>Name</th>
<th>Number</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td><input type="text" value = "10"/></td>
</tr>
<tr>
<td>2</td>
<td>Sally</td>
<td><input type="text" value = "20"/></td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td><input type="text" value = "10"/></td>
</tr>
<tr>
<td>4</td>
<td>Sam</td>
<td><input type="text" value = "30"/></td>
</tr>
<tr>
<td>5</td>
<td>Chris</td>
<td><input type="text" value = "20"/></td>
</tr>
</table>
Expanding on the answer provided by #axel.michel using .count() selector of Linq.js. I decided to go this route because I couldn't get the JQuery selector to work correctly provided in his answer. And I really like the Linq.js and find myself loving it more each time i implement a use of it.
var allTextBoxes = $().find('input:text');
// loop over all input fields on page
$(allTextBoxes)
.each(function() {
// select any other text boxes that have the same value as this one
if (Enumerable.from(allTextBoxes).count("$.value == '" + $(this).val() + "'") > 1) {
// If more than 1 have the same value than highlight this textbox and display an error message
$(this).addClass('duplicate');
$('#custom-field-validator').html('Custom fields must have unique names.');
valid = false;
} else {
// otherwise remove
$(this).removeClass('duplicate');
}
});
This is working fine without needing to worry about the value selector and syncing the value attributes.

Sorting pairs of rows with tablesorter

http://jsfiddle.net/9sKwJ/66/
tr.spacer { height: 40px; }
$.tablesorter.addWidget({
id: 'spacer',
format: function(table) {
var c = table.config,
$t = $(table),
$r = $t.find('tbody').find('tr'),
i, l, last, col, rows, spacers = [];
if (c.sortList && c.sortList[0]) {
$t.find('tr.spacer').removeClass('spacer');
col = c.sortList[0][0]; // first sorted column
rows = table.config.cache.normalized;
last = rows[0][col]; // text from first row
l = rows.length;
for (i=0; i < l; i++) {
// if text from row doesn't match last row,
// save it to add a spacer
if (rows[i][col] !== last) {
spacers.push(i-1);
last = rows[i][col];
}
}
// add spacer class to the appropriate rows
for (i=0; i<spacers.length; i++){
$r.eq(spacers[i]).addClass('spacer');
}
}
}
});
$('table').tablesorter({
widgets : ['spacer']
});
<table id="test">
<thead>
<tr>
<th>Name</th>
<th>Number</th>
<th>Another Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>Test4</td>
<td>4</td>
<td>Hello4</td>
</tr>
<tr>
<td colspan="3">Test4</td>
</tr>
<tr>
<td>Test3</td>
<td>3</td>
<td>Hello3</td>
</tr>
<tr>
<td colspan="3">Test3</td>
</tr>
<tr>
<td>Test2</td>
<td>2</td>
<td>Hello2</td>
</tr>
<tr>
<td colspan="3">Test2</td>
</tr>
<tr>
<td>Test1</td>
<td>1</td>
<td>Hello1</td>
</tr>
<tr>
<td colspan="3">Test1</td>
</tr>
</tbody>
</table>
This sorts just the way I want it if you sort it by the first column, but the other two columns don't maintain the same paired 'tr' sort im looking for.
Any help on this?
Use the expand-child class name on each duplicated row:
<tr>
<td>Test3</td>
<td>3</td>
<td>Hello3</td>
</tr>
<tr class="expand-child">
<td colspan="3">Test3</td>
</tr>
It's defined by the cssChildRow option:
$('table').tablesorter({
cssChildRow: "expand-child"
});​
Here is a demo of it in action.

Categories

Resources