jQuery function to create HTML table from another HTML table - javascript

I have an HTML table on a page that I'd like to use jQuery to take the information from, clean/sanitize it, and create a new "clean" HTML table with the information.
I have the table with the following <tr> structure:
<tr class="dirRow">
<td style="border-style:None;width:35px;">
<a href="http://www.link.com">
<img class="class-here" src="/media/proxy.ashx?id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&size=50w50h_fxd" style="border-width:0px;height:35px;width:35px;">
</a>
</td>
<td style="border-style:None;">
Full Name
</td>
<td style="border-style:None;">
<span>123.456.7890</span>
</td>
<td style="border-style:None;">
<span>456.789.0123</span>
</td>
<td style="border-style:None;">
<span>Office</span>
</td>
<td style="border-style:None;">
<span>Title</span>
</td>
<td style="border-style:None;">
<span>Supervisor</span>
</td>
</tr>
<!-- 150+ more tr with same structure -->
Which I'd like to input the information into the following table (formatted this way to use a plugin that takes this table input and formats it into an org chart). I've commented how the information should be modified from the original HTML table.
<table id="orgChartData">
<tbody>
<tr>
<th>id</th>
<th>parent id</th>
<th>image</th>
<th>name</th>
<th>phone</th>
<th>phonecell</th>
<th>office</th>
<th>title</th>
<th>supervisor</th>
</tr>
<tr>
<td>
<!-- Full Name (text only, no href, goes here) -->
Full Name
</td>
<td>
<!-- Supervisor (text only, no span, goes here) -->
Supervisor
</td>
<td>
<!-- img src (just the relative path, no query string) -->
/media/proxy.ashx?id=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
</td>
<td>
<!-- Full Name (including href with "xlink:" added to the beginning of the href) -->
<a xlink:href="http://www.google.com/" target="_blank">Full Name</a>
</td>
<td>
<!-- Phone (no span) -->
123.456.7890
</td>
<td>
<!-- Phonecell (no span) -->
456.789.0123
</td>
<td>
<!-- Office (no span) -->
Office
</td>
<td>
<!-- Title (no span) -->
Title
</td>
<td>
<!-- Supervisor (no span) -->
Supervisor
</td>
</tr>
</tbody>
</table>
Updated my code based on Michael Sacket's answer below
I now have all the variables in the right format, but need to create the new <tr>s based on these variables.
$('tr.dirRow').each(function () {
var tds = $(this).children();
var fullName = tds.eq(1).text();
var supervisor = tds.eq(6).text();
var imgSource = tds.eq(0).find("img").attr("src");
var imgSourceClean = imgSource.substring(0, imgSource.indexOf('&'));
var fullNameHref = tds.eq(1).find("a").attr("href");
var fullNameHyperlink = '<a xlink:href="' + fullNameHref + '">' + fullName + '</a>';
var phone = tds.eq(2).text();
var phoneCell = tds.eq(3).text();
var office = tds.eq(4).text();
var title = tds.eq(5).text();
});
Thanks for any help.

My suggestion is to break it up, one part at a time. To get you started:
Getting the data
var data = [];
var tds = null;
$('tr.dirRow').each(function(){
tds = $(this).children();
data.push({
"fullName": tds.eq(1).text()
});
});
console.log(data);
Sending it to the destination table
// grab a reference to the destination table
var destTbody = $('#orgChartData > tbody');
// loop through the data adding rows
var newRow = null;
for(var i=0;i<data.length;i++){
newRow = $('<tr/>');
newRow.append( $('<td>' + data[i].fullName + '</td>') );
destTbody.append(newRow);
}
Note: You could also do all that in a single loop within the $('tr.dirRow').each().

Related

Good code for structure manipulation of table's cells/rows with JQuery

I'm writing wysiwyg editor (iframe in designmode), and I can't find good right code to operate with table. Not simple table where any cells have rowspan or colspan is 1! I mean about hard table variant, like this:
<table border=1>
<tr>
<td rowspan=2 colspan=2 width=60px height=60px> </td>
<td height=30px width=30px> </td>
</tr>
<tr>
<td rowspan=2 width=30px height=60px> </td>
</tr>
<tr>
<td height=30px width=30px> </td>
<td height=30px width=30px> </td>
</tr>
</table>
Any code I was found is only for simple tables. For example, this is code for insert rows and it do that wrong:
var cell = select.current;
var row = cell.closest('tr');
var table = row.closest('table');
row.after('<tr></tr>');
var row_new = row.next();
row.children().each(function()
{
var cs = $(this).prop('colSpan');
if ( cs == 1 )
{
row_new.append('<td> </td>');
}
else
{
row_new.append('<td colspan=' + cs + '> </td>');
}
});
I think the right code maybe will analyze all table rows and change rowspan values and etc.

How to check if TD is last with class in row

I am new to jQuery and hope someone can help me with this.
I have a large HTML table with dynamically added rows.
The table has a standard structure (incl. thead, tbody and tfoot).
Within this table there are editable TDs (which have the class "editable" and contain a contenteditable div) and non-editable TDs (which dont't have the class "editable" and do not contain a div).
If a user is in such a div I would like to check if the current (closest) TD is the last TD within the same row that has a certain class ("editable").
I tried the below but this doesn't work here. Can someone tell me what I am doing wrong ?
My jQuery (in doc ready):
$(document).keydown(function(e){
var current = $(e.target);
// ...
if($(current).closest('td').is('td.editable:last')){
alert('last editable td in current row'); // test alert
}
// ...
});
My HTML (example row):
<tr>
<!-- ... -->
<td class="editable"><div contenteditable="true"></div></td> <!-- editable -->
<td class="editable"><div contenteditable="true"></div></td> <!-- editable -->
<td></td> <!-- non-editable -->
<td></td> <!-- non-editable -->
<td class="editable"><div contenteditable="true"></div></td> <!-- editable -->
<!-- ... -->
</tr>
Try the :last-of-type selector? Never use :last or :first, as they are implemented differently in every browser!
if ($(current).closest('td').is('td.editable:last-of-type')) {
Use jQuery index() like
$('div').click(function() {
var editables = $(this).closest('tr').find('td.editable')
var count = editables.length;
if(editables.index($(this).closest('td')) == (count - 1))...
});
The above should not return an index if closest('td') does not have class editable
$('div').click(function() {
var editables = $(this).closest('tr').find('td.editable')
var count = editables.length;
console.log('Is last editable td: ' + (editables.index($(this).closest('td')) == (count - 1)));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tr>
<!-- ... -->
<td class="editable">
<div contenteditable="true">test</div>
</td>
<!-- editable -->
<td class="editable">
<div contenteditable="true">test</div>
</td>
<!-- editable -->
<td>
<div contenteditable="true">not editable</div>
</td>
<!-- non-editable -->
<td>
<div contenteditable="true">not editable</div>
</td>
<!-- non-editable -->
<td class="editable">
<div contenteditable="true">test</div>
</td>
<!-- editable -->
<td>
<div contenteditable="true">not editable</div>
</td>
<!-- ... -->
</tr>
</table>
Fiddle
<table>
<tr>
<td class="editable"><div contenteditable="true">11</div></td>
<td class="editable"><div contenteditable="true">22</div></td>
<td>33</td>
<td>44</td>
<td class="editable"><div contenteditable="true">55</div></td>
</tr>
</table>
$("table tr td.editable").keydown(function(){
var col = $(this).parent().children().index($(this));
if(col == $(this).parent().children().size() - 1){
alert('last editable td in current row'); // test alert
}
});
Hey you can try this: https://jsfiddle.net/alaingoldman/5cseugvs/1
Basically what i did is i targeted the table tag and looked through it's descendants with the pseudo class last-of-type.
Hopefully this helps. Cheer.s
$('table tr:last-of-type').css({backgroundColor: "pink"})

How to make a column of a table to take only two words per line in jquery?

I have made a table in html which is updated when a person chosse an item from the item list. I want when a cell of the table is updated, it should only take two words of the selected item and if the selected item is of three words, then the third word should print on next line of the cell.
This is html table from where an item is selected
<table>
<tr>
<td style="text-align:left;"><input type='checkbox' name='it's 2' value='Two Words'>Two words</input>
</td>
<td style="width:200px;"></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td style="text-align:left;">
<input type='checkbox' name='this is three' value='Three Words' >Three words Next line</input>
</td>
<td style="width:200px;"></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
This is the html table which is updated...
<table border="1" class="table2">
<tr>
<td>Name</td>
<td>Value</td>
</tr>
<tr>
<td class="text"></td>
<td class="value"></td>
</tr>
</table>
</div>
I want that second element of first table when selected is printed on second table but in two lines, where first line will have "three words" and the second line will have "Next line" on the same cell of second table. Pl help.
jQuery Code :
$('input[type="checkbox"]').click(function(){
if($(this).is(":checked")){
var x = $(this).val();
$('.text').append(x + ' <br />').show();
var z = $(this).attr('name');
$('.value').append(z + ' <br />');
}
else if($(this).is(":not(:checked)")){
var x = $(this).val();
var y = $('.text').text().replace(x, '');
$('.text').text(y).show();
$('.text').append('<br/>');
var z = $(this).attr('name');
var a = $('.value').text().replace(z, '');
$('.value').text(a).show();
$('.value').append(' <br/>');
}
});
To capture first two words: var theTwoWords = yourText.match(/([a-zA-Z]+\s+[a-zA-Z]+)/)[0]; To get the next two after these: var theNextTwoWords = theTwoWords.substr(theTwoWords.length + 1);

Selecting td element in a tr

Here is the code I want to process using javascript / jquery
EDITED THE BELOW CODE BLOCK FOLLOWING THE COMMENTS
<table>
<tbody>
<tr class="promote">
<td>1</td>
<td><span class="team_logo visible-lg visible-sm" style=""></span><a class="team_name " href="/team/show/7473/Power-Hiters">Power Hiters</a><span class="online" title="user is online"></span></td>
<td style="text-align:center">5</td>
<td style="text-align:center">10</td>
<td style="text-align:center">5</td>
<td style="text-align:center">0</td>
<td style="text-align:center">0</td>
<td style="text-align:center">6.713</td>
</tr>
<tr> <!-- Similar Above tr Content --> </tr>
<tr> <!-- Similar Above tr Content --> </tr>
<tr> <!-- Similar Above tr Content --> </tr>
</tbody>
</table>
I want to get the inner content/html of each <td> tag in a array using javascript / jquery
Extra Info:
When I tried it seems jquery strips the td and tr tags.
Actual thing I want to do is extract td in a multi dimensional array for each tr
the table structure:
<table>
<tbody>
<tr> <!-- Above tr Content --> </tr>
<tr> <!-- Above tr Content --> </tr>
<tr> <!-- Above tr Content --> </tr>
</tbody>
</table>
Since you want a multidimensional array, you will need to:
Make an array that will hold all table data
Iterate through all tr and create an array per row
Push that array in the first one, that holds all table data.
something like this:
var tableContent = [];
$('table tr').each(function(){
var trcontent = [];
$('td', this).each(function(){ trcontent.push($(this).text()); });
tableContent.push(trcontent);
})
console.log(tableContent);
example in jsfiddle
Try,
var arr = $("#cache").find('td').map(function(){ return this.textContent; }).get();

Remove tables from HTML using jQuery

I've got many chunks of HTML coming into my app which I have no control over. They contain tables for layout, which I want to get rid of. They can be complex and nested.
What I want is to basically extract the HTML content from the tables, so that I can inject that into other templates in the app.
I can use jQuery or plain JS only, no server side trickery.
Does anyone know of a jQuery plugin of good tip that will do the job?
Littm - I mean to extract content from the td tags essentially. I want no trace of table left in the code when it's done. Thanks!
Here's an example of the type of HTML in question. It all comes in via XHR from some ancient application so I have no control over the markup. What I want is to get rid of the tables completely, leaving just the rest of the HTML or other text content.
<table>
<tr><td colspan="4"></td></tr>
<tr>
<td width="1%"></td>
<td width="40%" style="padding-left: 15px">
<p>Your access level: <span>Total</span></p>
</td>
<td width="5%">
<table><tr><td><b>Please note</b></td></tr></table>
</td>
<td width="45%" style="padding-left: 6px" valign="top"><p>your account</p></td>
</tr>
<tr><td colspan="4"> </td></tr>
<tr>
<td width="1%"></td>
<td width="40%" style="padding-left: 15px">
<table>
<tr>
<td align="right">Sort Code: </td>
<td align="center"><strong>22-98-21</strong></td>
</tr>
<tr>
<td align="right">Account Number: </td>
<td><strong>1234959</strong></td>
</tr>
</table>
</td>
<td width="5%"></td>
<td width="45%" style="padding-left: 6px">Your account details for</td>
</tr>
</table>
I've tried;
var data = ""
$("td").each(function(){
data += $(this).html()
});
$("article").append(data);
$("table").remove();
But var data still contains nested td tags. I'm no JS expert so I'm not sure what else to try....
Let's suppose that you have X number of tables.
In order to extract all the content information from these, you could try something like this:
// Array containing all the tables' contents
var content = [];
// For each table...
$("table").each(function() {
// Variable for a table
var tb = [];
$(this).find('tr').each(function() {
// Variable for a row
var tr = [];
$(this).find('td').each(function() {
// We push <td> 's content
tr.push($(this).html());
});
// We push the row's content
tb.push(tr);
});
// We push the table's content
content.push(tb);
});
So for instance, if we have the following 2 tables:
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>A</td>
</tr>
</table>
<table>
<tr>
<td>r1</td>
<td>r2</td>
<td>r3</td>
</tr>
<tr>
<td>rA</td>
<td>rB</td>
</tr>
<tr>
<td>rP</td>
</tr>
</table>
The array content will be something like this:
content = [ [ [1, 2], [A] ] ] , [ [r1, r2, r3], [rA, rB], [rP] ] ]
\_______________/ \______________________________/
1st table 2nd table
and if you want to access the first table, you'll just have to access content[0] for instance.
Now, let's suppose that you have a DIV, with and id my_div, and that you want to output some table content in it.
For example, let's suppose that you only want to have the 1st table only. Then, you would do something like this:
// Note: content[0] = [[1, 2], [A]]
var to_print = "<table>";
for(var i=0; i<content[0].length; i++) {
to_print += "<tr>";
for(var j=0; j<content[0][i].length; j++)
to_print += "<td>"+ content[0][i][j] +"</td>";
to_print += "</tr>";
}
to_print += "</table>";
$("#my_div").html(to_print);
which will give you something like this:
<div id="my_div">
<table>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>A</td>
</tr>
</table>
</div>
Hope this helps.
Edit: You should create a recursive function to do that.
Simply create you function that gets "td"'s as a value:
function searchTexts(td) {
if (td.find("td")) {
searchTexts(td.find("td"));
}
td.each(function(){
data += $(this).html()
$(this).remove(); // remove it for avoiding duplicates
});
}
Then call it passing a jQuery object to the function.

Categories

Resources