JQuery sort items by last name - javascript

I want to have sorting on the last name and text to be replaced but I am not able to do it. I have tried following.
HTML
<div id="sort-by-name">
<table>
<tbody>
<tr>
<tr>
<td class="names">
<span class="toggle"></span> Betty j. Sean
</td>
</tr>
<tr>
<td class="names">
<span class="toggle"></span> Ali Khan
</td>
</tr>
<tr>
<td class="names">
<span class="toggle"></span> Will Turner
</td>
</tr>
</tbody>
</table>
</div>
// Sort names
var items = [];
$('#ByMember table tbody .irwMemberName').each(function () {
items.push($(this).html());
});
items.sort();
console.log(items);
I have also try adding a class to last name word. Then applied above sort function it actually sorts all last names but how I can sort whole by that and replace.
$("#sort-by-name table tbody .names").html(function(index, old) {
return old.replace(/(\b\w+)$/, '<span class="name_identifier">$1</span>');
});
Please let me know if I am not clear. Also Ignore any typo's I have modified code here for post.

You can do it like this. Check fiddle: Fiddle
var els = $("#sort-by-name table tbody tr")
.sort(function(a,b){
var t1 = $(a).find('.names')[0].innerText.split(' ').pop(),
t2 = $(b).find('.names')[0].innerText.split(' ').pop();
if(t2 < t1) {
return 1;
} else {
return -1;
}
})
.each(function() {
var t = this.innerText.replace(/(\w+)$/, '<span class="name_identifier">$1</span>');
return $(this).html( t );
});
$('#bodyid').html(els);

To add to Nikolay's answer, I've built a version that works both on Firefox and Chrome.
var els = $("#sort-by-name table tbody tr")
.sort(function(a, b) {
var t1 = $(a).find('.names')[0].textContent.split(' ').pop(),
t2 = $(b).find('.names')[0].textContent.split(' ').pop();
if (t2 < t1) {
return 1;
} else {
return -1;
}
})
.each(function() {
debugger;
var t = this.textContent.trim().replace(/(\w+)$/, '<span class="name_identifier">$1</span>')
return $(this).html(t);
});
$('#bodyid').html(els);
JSFiddle

Related

Looping object inside a table cell and create a unordered list

I have this table that has a column in which the cell may or may not contain a value, but when it does, it is in a JSON format; otherwise it will be empty (null).
<table>
<tbody>
<tr>
<td>Barley</td>
<td>AK, AZ</td>
<td class="fpdCell">[{"date":"06/01/2016","error":"Double/Triple cropping","id":2},{"date":"06/07/2016","error":"Lack of Planting Dates Established","id":2}]</td>
<td>null</td>
</tr>
<tr>
<td>Barley</td>
<td>AK, AZ, AR</td>
<td class="fpdCell">[{"date":"06/04/2016","error":"No Error Found","id":3},{"date":"06/27/2016","error":"Lack of Planting Dates Established","id":3},{"date":"06/28/2016","error":"Weather Patterns","id":3}]</td>
<td>null</td>
</tr>
<tr>
<td>Burley Tobacco</td>
<td>null</td>
<td class="fpdCell">null</td>
<td>null</td>
</tr>
<tr>
<td>Fire Cured Tobbacco</td>
<td>null</td>
<td class="fpdCell">null</td>
<td>null</td>
</tr>
<tr>
<td>Flue Cured Tobacco</td>
<td>null</td>
<td class="fpdCell">null</td>
<td>null</td>
</tr>
<tr>
<td>Oats</td>
<td>null</td>
<td class="fpdCell">null</td>
<td>null</td>
</tr>
What I need to do is to loop through each of the cells with the fpdCell class, loop the object inside of each of those cell, create a list and add them as list element.
This is as far as I was able to get. I really don't know how to move forward from here.
var theCells = $('.fpdCell');
$.each(theCells, function(index, value) {
var cellValues = $.parseJSON(value.textContent);
if (cellValues != 'null') {
console.log(cellValues);
value.textContent = '';
$(value).append('<ul class="list-group ul'+index+'"></ul>')
//then add <li class="list-group-item">Test</li>
//Not working------------------
/*
for (var u = 0; u < cellValues. length; u++) {
$('ul' + index).append('<li class="list-group-item">'+cellValues[u].date+'</li>');
console.log(cellValues[u].date);
}
*/
}
});
Thanks in advance.
To achieve this you just need two loops, one to go through the .fpdCell elements, the other to go through the parsed JSON and build the HTML of the ul. Try this:
$('.fpdCell').each(function() {
var $el = $(this), html = '';
$.each(JSON.parse($el.text()), function(i, obj) {
html += '<li class="list-group-item">' + obj.date + '</li>';
})
$el.append('<ul>' + html + '</ul>');
});
Working example
var theCells = $('.fpdCell');
$.each(theCells, function() {
var cellValues = $.parseJSON($(this).text());
if (cellValues != 'null') {
console.log(cellValues);
$(this).html("");
var list = '<ul class="list-group ul'+index+'">';
for (var u = 0; u < cellValues.length; u++) {
list+='<li class="list-group-item">'+cellValues[u].date+'</li>';
console.log(cellValues[u].date);
}
if(cellValues.length>0)
list+="</ul>";
$(this).append(list);
}
The objects in the fpdcell columns are array objects which you may have missed in your logic.
One more thing, may be a typo, but, you missed the . in the commented code to append list items to the ul :)
Here is a solution which loops through the array and then loops through the individual elements in each array element to create a linear list.
var theCells = $('.fpdCell');
$.each(theCells, function(index, value) {
var cellValues = JSON.parse(value.textContent);
if (cellValues != 'null') {
$(value).html('<ul class="list-group ul'+index+'"></ul>');
$.each(cellValues, function(cellValueIndex, cellValue){
for (var prop in cellValue) {
$('.ul'+index).append('<li class="list-group-item">'+ cellValue[prop] +'</li>');
}
});
} else {
$(value).html('');
}
});
This may not be the exact solution to what you are looking for but, should help you along the line you would want to go. Happy coding.
Here is a fiddle with the solution JSFiddle

for each table push to array

I'm a beginner with code,
I'm trying to run on this table and get the text from each .winner class and push it to an Array, so instead of getting:
["aa","aa","dd"]
I'm getting
["aaaadd","aaaadd","aaaadd"]
$(document).ready(function(){
var arr = [];
var winner = $('.winner').text() ;
for ( i = 0; i < $('table').length ; i++ ) {
arr.push(winner);
}
console.log(arr);
});
HTML:
<table>
<tr>
<td>#</td>
<td class="winner">aa</td>
<td>bb</td>
<td>cc</td>
<td>dd</td>
</tr>
</table>
<table>
<tr>
<td>#</td>
<td class="winner">aa</td>
<td>bb</td>
<td>cc</td>
<td>dd</td>
</tr>
</table>
<table>
<tr>
<td>#</td>
<td class="winner">dd</td>
<td>cc</td>
<td>bb</td>
<td>aa</td>
</tr>
</table>
I guess something is wrong with my for loop
var arr = [];
$('table .winner').each(function () {
arr.push($(this).text());
})
Example
or version without class .winner
$('table').each(function () {
arr.push($(this).find('tr').eq(0).find('td').eq(1).text());
});
Example
$('table .winner') - returns 3 td's with class .winner
$(this).text() - get text from current element.
In your example $('.winner').text() returns text "aaaadd", then you get $('table').length (will be 3) and three times push the same text to arr
The sentence
var winner = $('.winner')
will give you an array of objects, so you need to loop each of them and call text() method for each one.
With this:
var winner = $('.winner').text();
You are getting a combined texts from all the td elements marked as winner (see docs here).
Then, for each table, to push this value to the array:
for ( i = 0; i < $('table').length ; i++ ) {
arr.push(winner);
}
This is actually not necessary.
What you want is probably:
var winners = $('.winner');
for (var i = 0; i < winners.length(); ++i) {
arr.push(winners.eq(i).text());
}

JQuery .appendTo() adding rows multiple times

Bit of a strange problem, but I'm not sure how to fix it.
While inside of the code below, I'm trying to take all of the element of a table a sort them based on the row heading that was clicked.
The starting HTML:
<table id="PracticeTable" class="col-md-10 col-md-offset-2">
<tr id="Column Names">
<td class="ClientID col-xs-1">Client ID</td>
<td class="ClientName col-xs-1">Client Name</td>
<td class="PracticeID col-xs-1">Practice</td>
</tr>
#for (int i = 0; i < ViewBag.ClientDatabase.getDatabase().Count; i++)
{
#:<tr class="DataRow">
<td class="ClientID col-xs-1" data-name="#ViewBag.ClientDatabase.getByIndex(i).Id">#ViewBag.ClientDatabase.getByIndex(i).Id</td>
<td class="ClientName col-md-2 col-xs-1" data-name="#ViewBag.ClientDatabase.getByIndex(i).getClientName">#ViewBag.ClientDatabase.getByIndex(i).getClientName</td>
<td class="PracticeIDs col-xs-1" data-name="#ViewBag.ClientDatabase.getByIndex(i).getPracticeID">#ViewBag.ClientDatabase.getByIndex(i).getPracticeID</td>
<td class="EditButtons col-xs-1" data-bind="visible: editVisible">Edit</td>
#:</tr>
}
Example of one of the click functions:
jQuery(document).ready(function () {
$(".ClientName").click(function () {
alert("Name Clicked");
var clients = $(".DataRow");
var compareLine = $(clients).children(".ClientName");
compareLine.sort(function (a, b) {
var an = $(a).attr("data-name");
var bn = $(b).attr("data-name");
alert(an + " " + bn);
if (an > bn) {
return 1;
}
if (an < bn) {
return -1;
}
return 0;
});
compareLine.detach().appendTo(clients);
});
});
When I attempt to append the lines as above, the names from Client Name appear in every row. Is there something I'm missing? I tried to loop through the data in compareLine to add them individually, but I couldn't figure it out.
EDIT: Removing duplicated code from a fix attempt that wasn't fully removed.
If you want to sort the rows, I think you just need to make a small change:
jQuery(document).ready(function () {
$(".ClientName").click(function () {
alert("Name Clicked");
var clients = $(".DataRow");
clients.sort(function(a, b) {
var an = $(a).children(".ClientName").attr("data-name");
var bn = $(b).children(".ClientName").attr("data-name");
alert(an + " " + bn);
if (an > bn) {
return 1;
}
if (an < bn) {
return -1;
}
return 0;
});
clients.detach().appendTo("#PracticeTable");
});
});
Seems like your sort function was designed to be working with the rows, but you were sorting a collection of the columns.

JQuery, Find results in table column

Im trying to find the results in a table column if its set in my function below, most of this was setup by someone else, ive just added some extras into it, my final one is searching 1 column only by name set in the thead but alas in its current edition nothing happens at all :|
thanks for any help
USAGE
<a href='javascript:searchTable("Bob", "table",1,"Name");'>Test</a>
TABLE
<table id="table" class="table">
<thead>
<tr>
<th id="blank"> </th>
<th id="Name">Name</th>
<th id="Dept">Department</th>
<th id="JobTitle">Job Title</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td>Bob</td>
<td>IT</td>
<td>IT Support</td>
</tr>
<tr>
<td> </td>
<td>Fred</td>
<td>Finance</td>
<td>Finance Man</td>
</tr>
</tbody>
</table
FUNCTION
function searchTable(inputVal, tablename,starts, column) {
var table = $(tablename);
table.find('tr:not(.header)').each(function (index, row) {
if (column != '') {
//Columnname
var Cells = $(row).find('td').eq(column);
} else {
//AllCells
var Cells = $(row).find('td');
}
if (Cells.length > 0) {
var found = false;
Cells.each(function (index, td) {
if (starts == 1) {
var regExp = new RegExp((starts ? '^' : '') + inputVal, 'i');
} else {
var regExp = new RegExp(inputVal, 'i');
}
if (regExp.test($(td).text())) {
found = true;
return false;
}
});
if (found == true) $(row).show().removeClass('exclude'); else
$(row).hide().addClass('exclude');
}
});
}
As you're passing the column as a string, you need get the corresponding elements index:
var Cells = $(row).find('td:eq(' + $('#' + column).index() + ')');
The above presumes that you're matching based on the id, if you're matching based on the text within the <th> you could use the :contains selector:
$(row).find('td:eq(' + $(table.prop('id') + ' th:contains(' + column + ')').index() + ')');
If you can control and modify the function calls, the best thing to do would be to just pass the elements index directly to the function:
javascript:searchTable("Bob", "table", 1, 1); <-- Would be the "Name" column
That way, you won't have to do any of the above.
By the way, your table selector is incorrect based on your comment, not sure if that's just a typo on your part?
var table = $(tablename);
Should be:
var table = $('#' + tablename);
I am not sure what you are trying to control but you can use this to loop through rows and get the values of cells.
$("#table>tbody>tr").each(function(){
var name= $(this).children("td").eq(1).html();//Name
var department= $(this).children("td").eq(2).html();//Department
var jobTitle= $(this).children("td").eq(2).html();//Job Title
alert(name);
});
http://jsbin.com/uvefud/1/edit
Edit:
You can try this searchTable function.
function searchTable(name,tableName,row,column){
var $Tds= $("#"+tableName+">tbody>tr").eq(row-1).children("td");
if(column=="Name"){
$Tds.eq(1).html(name);
}
else if(column=="Dept"){
$Tds.eq(2).html(name);
}
else if(column=="JobTitle"){
$Tds.eq(3).html(name);
}
}
http://jsfiddle.net/W9zpq/2/
Usage: This will update the name column of 2nd row of tbody to 'Bob'
searchTable("Bob", "table",2,"Name")

Nested tag name with getElementsByTagName doesn't work

I have the following div that contains the table and its data queried from database
<div id="content">
<table>
<tbody>
<tr>
<th class="header" colspan="2">Food items include:</th>
</tr>
<tr>
<td id="15" class="fruits">Papaya+salt</td>
<td><p>This includes papaya and salt</p></td>
</tr>
<tr>
<td class="meat">Baked chicken</td>
<td><p>This includes a chicken thide and kethup</p></td>
</tr>
<tr>
<td id="1" class="Juices">Strawberry Sting</td>
<td><p>Sugar, color and water</p></td>
</tr>
<table>
</div>
That table is defined in a page.aspx
and here is my code used to sort that table data alphabetically
OldFunc = window.onload;
window.onload = OnLoad;
function OnLoad(){
try{
var pathName = window.location.pathname.toLowerCase();
if( pathName=="/Resources/Glossary.aspx") {
sort_it();
}
OldFunc();
}
catch(e) {
}
}
function TermDefinition(def_term,def_desc)
{
this.def_term=def_term;
this.def_desc=def_desc;
}
function sort_it()
{
var gloss_list=document.getElementsByTagName('td');
var desc_list=document.getElementsByTagName('td p');
var gloss_defs=[];
var list_length=gloss_list.length;
for(var i=0;i<list_length;i++)
{
gloss_defs[i]=new TermDefinition(gloss_list[i].firstChild.nodeValue,desc_list[i].firstChild.nodeValue);
}
gloss_defs.sort(function(a, b){
var termA=a.def_term.toLocaleUpperCase();
var termB=b.def_term.toLocaleUpperCase();
if (termA < termB)
return -1;
if (termA > termB)
return 1;
return 0;
})
for(var i=0;i<gloss_defs.length;i++)
{
gloss_list[i].firstChild.nodeValue=gloss_defs[i].def_term;
desc_list[i].firstChild.nodeValue=gloss_defs[i].def_desc;
}
}
Please lookat the the two getElementsByTagName, I think I am misuse its content since nothing is done on the output.
Invalid:
desc_list=document.getElementsByTagName('td p');
You can't pass a css selector to that function, only a tag name like div\ span input etc'.
You might want to use:
desc_list = $('td p');
Since you tagged the question with jQuery, or document.querySelectorAll for vanilla js:
desc_list = document.querySelectorAll('td p');

Categories

Resources