I have a table where the first column will always turn out to be unique. So when I remove the duplicate rows none would be removed. So i want to remove duplicates by eliminating the first row in the duplicate check. Each cell in the table may contain more than one value.
Input Table
Output table
I found the script for eliminating the duplicate rows from other question. But that is not what I am looking for. This question has something similar, but it is done only on the first column. I do not know how I can eliminate the first column from being accessed.
Script
<script>
var seen = {};
$('table tr').each(function() {
var txt = $(this).text();
if (seen[txt])
$(this).remove();
else
seen[txt] = true;
});
</script>
What I am trying to achieve
I would first eliminate the duplicate elements within the cell and then eliminate the rows with duplicate values. So from the input table above, in the column C_fb 4000 being written twice would be eliminated and then checked for duplicate rows.
Combined not selector and first selector, your code works!
var seen = {};
$('table tr').each(function() {
var txt = $(this).find("td:not(:first)").text();
if (seen[txt])
$(this).remove();
else
seen[txt] = true;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr><td>id1</td><td>aaaaa</td><td>ccccccccc</td></tr>
<tr><td>id2</td><td>bbbbb</td><td>dddddddd</td></tr>
<tr><td>id3</td><td>bbbbb</td><td>dddddddd</td></tr>
<tr><td>id4</td><td>bbbbb</td><td>dddddddd</td></tr>
</table>
Use the :not and the :first jQuery-Selector. source: here
var seen = {};
$('table tr:not(:first)').each(function() {
var txt = $(this).text();
if (seen[txt])
$(this).remove();
else
seen[txt] = true;
});
Related
I have a table with a bunch of data in it. Currently, my code compares textfield input to the data in the table. If there's a match, it will show that particular table row. Here's my code:
$(document).on('keyup','#filterText',function(){
$('.all').hide(); // hide everything
$('tfoot').hide(); // hide everything
var s = $(this).val().toLowerCase(); //get input string
if(s==''){$('.all').show(); $('tfoot').show();}; // if no input then show everything
$('#report tbody tr td').each(function(i,td) {
//go through each table cell and compare
if($(td).text().toLowerCase().indexOf(s)!==-1){
$(td).closest('tr').show(); // show table row
}
});
}); //.but_filterText
This works great. But now, I need to modify this so that a user could do multiple searches at the same time, separated by a comma. So here's what I did and nothing happens:
$(document).on('keyup','#filterText',function(){
$('.all').hide();
$('tfoot').hide();
var s = $(this).val().toLowerCase().split(',');
if(s === undefined || s.length == 0){
$('.all').show(); $('tfoot').show();
};
$('#report tbody tr td').each(function(i,td) {
if(s.indexOf($(td).text().toLowerCase())!==-1){
$(td).closest('tr').show();
}
});
}); //.but_filterText
Seems like it should work but can't get it going. What am I doing wrong. Thank you
I thinks the issue is because in the input field you type space after comma, e.g. text 1, text 2 instead of text 1,text 2
i made a small (similar to yours code) example: (in this example you can type with or without space, since it will be replaced)
$('[name="search"]').on('keyup', function() {
var $tds = $('td');
var s = this.value.toLowerCase().replace(/\,\s/,',').split(',');
// consider replacing comma+space (/\,\s/) with just a comma
// and also i would recommend using filter function for finding matches,
// it will return an array of matched elements, empty if there is no match
$tds = $tds.filter(function(i, td) {
return s.indexOf($(td).text().toLowerCase()) >=0;
});
$tds.addClass('selected');
});
Here is the jsfillde - http://jsfiddle.net/zqdbso1w/1/
UPDATE (based on your comment)
Here is the jsfillde - http://jsfiddle.net/zqdbso1w/3/
simply make second iteration to seek for a substring in haystack
$('[name="search"]').on('keyup', function() {
var $tds = $('td');
var s = this.value.toLowerCase().replace(/\,\s/,',').split(',');
$tds.removeClass('selected');
$tds.each(function() {
var text = $(this).text().toLowerCase();
var r = s.filter( function(t) {
if (!t.length) return false;
return text.indexOf(t) >= 0;
});
if (r.length) $(this).addClass('selected');
});
});
UPDATE regex should be global, and remove all spaces after all commas
Here is the jsfiddle - http://jsfiddle.net/zqdbso1w/4/
My table rows are being dynamically generated when I click "+" button. When I populate the fields and click submit button (next to "+") my JSON gets displayed to the console as shown in the image below.
When I generate JSON, I want to exclude the row which is unfilled (In this case 3rd row). Also, I want exclude column 1 (which consists of 3 buttons).
As we can see the JSON data is consisting lots of "\n" and \t" which is annoying.
I wrote following code by referring to some of the Stack Overflow pages.
function createJSON(){
var myJSON = { Key: [] };
var headers = $('table th');
$('table tbody tr').each(function(i, tr){
var obj = {},
$tds = $(tr).find('td');
headers.each(function(index, headers){
obj[$(headers).text()] = $tds.eq(index).text();
});
myJSON.Key.push(obj);
});
console.log(JSON.stringify(myJSON));
}
The rows that aren't filled have <input> elements. You can use a selector that excludes them.
$('table tbody tr:not(:has(input))').each(...)
You can get rid of all the newline and other whitespace characters around the headings with .trim():
headers.each(function(index, headers){
obj[$(headers).text().trim()] = $tds.eq(index).text();
});
To skip the first column, you can use :gt(0) in the selectors:
var headers = $('table th:gt(0)');
var $tds = $(tr).find('td:gt(0)');
I have a table with 2 columns. One column with a checkbox and another one with plain text. I would like to generate an object array with the the check state and the text. I can go tr after tr with this:
$('#divInfCambios .frozen-bdiv tr').each(function(i)
{ ... }
How can access to td[1], check the state, and recover the text of td[2]?
I got the check state with:
$(this).find('input[type="checkbox"]').prop('checked')
I need now how to access node 2 (td[1]) and grab the text.
//run through each row
$('#divInfCambios .frozen-bdiv tr').each(function (i, row) {
var getInputByName = $(this).find('input[name="selection"]');
if (getInputByName.is(':checked') ){
}
// assuming you layout of the elements
var tds = $(this).find('td');
var getTdText = tds.eq(1).text();
});
I wrote following code to add a custom column to my table. but i want to add a unique id to each cell in those columns. the format should be a(column no)(cell no>)
ex :- for the column no 4 :- a41, a42, a43, ........
So please can anyone tell me how to do that. Thank You!
$(document).ready(function ()
{
var myform = $('#myform'),
iter = 4;
$('#btnAddCol').click(function () {
myform.find('tr').each(function(){
var trow = $(this);
var colName = $("#txtText").val();
if (colName!="")
{
if(trow.index() === 0){
//trow.append('<td>'+iter+'</td>');
$(this).find('td').eq(5).after('<td>'+colName+iter+'</td>');
}else{
//trow.append('<td><input type="text" name="al'+iter+'"/></td>');
$(this).find('td').eq(5).after('<td><input type="text" id="a'+iter+'" name="a'+iter+'"/></td>');
}
}
});
iter += 1;
});
});
You seem to have code that's modifying the contents of the table (adding cells), which argues fairly strongly against adding an id to every cell, or at least one based on its row/column position, as you have to change them when you add cells to the table.
But if you really want to do that, after your modifications, run a nested loop and assign the ids using the indexes passed into each, overwriting any previous id they may have had:
myform.find("tr").each(function(row) {
$(this).find("td").each(function(col) {
this.id = "a" + row + col;
});
});
(Note that this assumes no nested tables.)
try this
if(trow.index() === 0){
//trow.append('<td>'+iter+'</td>');
$(this).find('td').eq(5).after('<td id="a'+column_no+cell_no+'">'+colName+iter+'</td>');
}else{
//trow.append('<td><input type="text" name="al'+iter+'"/></td>');
$(this).find('td').eq(5).after('<td id="a'+column_no+cell_no+'"><input type="text" id="a'+iter+'" name="a'+iter+'"/></td>');
}
you just have to define and iterate the column_no and cell_no variable
When all other cells are numbered consistently (for example using a data-attribute with value rXcX), you could use something like:
function addColumn(){
$('table tr').each(
function(i, row) {
var nwcell = $('<td>'), previdx;
$(row).append(nwcell);
previdx = nwcell.prev('td').attr('data-cellindex');
nwcell.attr('data-cellindex',
previdx.substr(0,previdx.indexOf('c')+1)
+ (+previdx.substr(-previdx.indexOf('c'))+1));
});
}
Worked out in this jsFiddle
I'm having some difficulty with this. In Backbone, I have a function like this:
functionOne: function(){
$('#myTExtbox-' + budgetLine.attr('id')).on('change keyup paste', function(){
that.mySecondFunction(this);
});
}
In this case, the this is a textbox, which is in a table, inside a div. Then:
mySecondFunction: function(tb){
var tbody = tb.parentElement.parentElement.parentElement.parentElement.parentElement;
//gets main parent, which is a tbody, inside a table, inside a div
}
I then want to iterate over tbody, to go through each row and find a textbox in a specific cell. The problem is that this code:
$.each(tbody, function(index, item){
cost = item;
var t= index;
});
Doesn't seem to allow me to get to any of the items. In this example, if I try to do something like:
item.getElementById('test');
I get an error:
TypeError: Object #<HTMLCollection> has no method 'getElementById'
Why can't I iterate over this object and access objects within?
Thanks
UPDATE
Here's a fiddle: http://jsfiddle.net/HX8RL/14/
Essentially, what should happen is this: When a text box changes, I want to iterate over all the rows in the tb's parent table and sum all the Tb values. Keeping in mind, all the tb's in the same cell position, as there could be other tb's in other places that I dont want to include.
There wont be any collection of TBody
try using children() instead
$.each(tbody.children('tr'), function(index, item){
cost = item;
var t= index;
});
Demo Fiddle
Iterate over all input elements directly to get values.
var tbody = tb.parentElement.parentElement.parentElement;
alert(tbody.id);
var input = $('#tbody').find('input');
alert(input);
console.log(input);
for (var i = 0; i < input.length; i++) {
alert(input[i].value);
alert(i);
}
See fiddle-http://jsfiddle.net/HX8RL/18/
I think there are a few things going wrong here. You know you can only have one ID per page? So you have to do document.getElementByid('test') instead.
Since you are also using jQuery you can use the find function, item.find('#test'). But I think this wouldn't solve you problem. Not sure what you want to achieve, maybe I can help you if you explain a bit more in detail what your problem is.
Also
tb.parentElement.parentElement.parentElement.parentElement.parentElement;
can be written as (in jQuery)
$(tb).parents('tbody');
I've setup a fiddle, maybe it can help you.
Code used in fiddle:
var myFuncs = (function() {
function funcA() {
$('input').on('keyup', function() {
funcB(this);
});
}
function funcB(myInput) {
var $table = $(myInput).parents('table');
$table.find('tr > td > input').each(function() {
var $input = $(this);
if($(myInput).attr('id') != $input.attr('id'))
$input.val("I'm called from another input");
});
}
return {
funcA : funcA
}
})();
myFuncs.funcA();