tree view using Nested tables alignment issue - javascript

I need to show hierarchical tree-view in tables. I am trying to create a table inside a parent table when expand is clicked. The child table columns are not aligning properly, even though I gave the same td width using css..
In the below image(http://i60.tinypic.com/352qm2u.jpg) red color lines shows the column reference, where child tds content has to come.. but content is coming in distracted way..
HTML used
<tr class="shaded">
<td>
<span><input type="checkbox" /></span>
</td>
<td>
<span ><img src="></span>
</td>
<td>Q1</td><td>785-061 - SHEATH1</td><td>PUMAfinal221 products</td>
</tr>
<tr>
<td></td>
<td colspan="999">
<div style="height: 180px;overflow-y: auto;">
<table id="tblProducts185346" >
<tbody >
<tr >
<td><input type="checkbox" ></td>
<td>Q1</td><td>785-061 - SHEATH1</td><td>PUMAfinal221 products</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
...... ``
Any idea on how to fix this issue?

I wrote a javascript method to set the target table tds width based on source table td's..
Thanks BigRabbit for your response..
function FormatTable(src, target) {
var count=0;
$(src + ' tr:nth-child(2)').eq(0).children("td").each(function() {
$(target + ' tr:first-child').eq(0).children("td")[count].width = $(this).css("width"); //this.offsetWidth+'px';
count = count + 1;
}
});
}

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.

Access textContent of hidden table cell

I'm working with an html form that displays rows of data only for data elements that are found with a submitted value in the database. For example, the following table row will be toggled off ( style="display:none" ) if there is no value found in the database for 'Seizures_Type', and WILL be displayed if there is a value found in the database.
The javascript works to concatenate values from several similar fields on the form and store in a single field, id="medalert".
When the script runs, it fails if it tries to access a field that is in the display:none state.
What would be a good way to allow the script to run fully, even if it encounters these hidden elements?
Build
<tr style="display:none">
<td title="seizures type">Seizures Type</td>
<td></td>
<td id="par_med_seizures_type"></td>
<td><input type="checkbox" id="chk_med_seizures_type"></td>
</tr>
<tr style="display:none">
<td title="seizures type">Seizures Medication</td>
<td></td>
<td id="par_med_seizures_medication"></td>
<td><input type="checkbox" id="chk_med_seizures_medication"></td>
</tr>
function buildMedAlert(){
var retval = "";
if (document.getElementById('par_med_seizures_type').textContent.length>0) {
retval += "Type: " + document.getElementById('par_med_seizures_type').textContent;
}
if (document.getElementById('par_med_seizures_medication').textContent.length>0) {
retval += "Medication: " + document.getElementById('par_med_seizures_medication').textContent;
}
document.getElementById('medalert').value=retval;
}
You should make a condition to check if the row is visible, give it an ID (since I don't believe you want to work on every element in the code) and then, make sure to check if the element is visible, like this:
var element = document.getElementById('element');
if(element.style.display != 'none'){
}
The thing is that you cannot access the contents of a hidden element since it is hidden and so, the javascript doesn't recognize it. You have to make sure the element is not hidden.
If I add the missing field medalert, it does not fail in neither Chrome nor IE10
function buildMedAlert() {
var retval = "";
if (document.getElementById('par_med_seizures_type').textContent.length > 0) {
retval += "Type: " + document.getElementById('par_med_seizures_type').textContent;
}
if (document.getElementById('par_med_seizures_medication').textContent.length > 0) {
retval += "Medication: " + document.getElementById('par_med_seizures_medication').textContent;
}
document.getElementById('medalert').value = retval;
}
Build
<table>
<tr style="display:none">
<td title="seizures type">Seizures Type</td>
<td></td>
<td id="par_med_seizures_type">Some type</td>
<td>
<input type="checkbox" id="chk_med_seizures_type">
</td>
</tr>
<tr style="display:none">
<td title="seizures type">Seizures Medication</td>
<td></td>
<td id="par_med_seizures_medication">Some med</td>
<td>
<input type="checkbox" id="chk_med_seizures_medication">
</td>
</tr>
</table>
<input type="text" id="medalert">

Show rows in table with cells name attribute containing string from input (JQuery)

I would like to have keyup function that would show only rows matching the input text by cell that spans on multiple rows.
Consider following table:
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1'> dummy1 </td>
</tr>
<tr>
<td name='Key1'> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2'> dummy3 </td>
</tr>
<tr>
<td name='Key2'> dummy4 </td>
</tr>
</table>
jsfiddle
Here each row has second td tag with name that matches its "parent" column text. So when I type 'Key1' at the input field I would like it to show only dummy1 and dummy2. Is it possible in jquery?
I understand that you want to display the rows that has a matching name. If this is wrong, please elaborate more, then I can update it.
Here is a demo: https://jsfiddle.net/erkaner/gugy7r1o/33/
$('input').keyup(function(){
$('tr').hide();
$("td").filter(function() {
return $(this).text().toLowerCase().indexOf(keyword) != -1; }).parent().show().next().show();
});
});
Here's my take on your issue, assuming you always want the first column to show. https://jsfiddle.net/gugy7r1o/2/
<input type="text" id="myInput" />
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1' class="data"> dummy1 </td>
</tr>
<tr>
<td name='Key1' class="data"> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2' class="data"> dummy3 </td>
</tr>
<tr>
<td name='Key2' class="data"> dummy4 </td>
</tr>
</table>
.data{
display:none;
}
var theData = $('td.data');
var input = $('#myInput').on('keyup', function(){
theData.hide();
var value = input.val();
var matches = theData.filter('[name="'+value+'"]');
matches.show();
});
Firstly, I would recommend using <ul> to wrap each key in as tables should be used for data structure (Forgive me if that is what it is being used for).
Secondly, just attach an on keyup event to the search box and then find matches based on the id. See example below:
JS Fiddle Demo
It is also worth mentioning that it could be useful attaching a timeout to the keyup event if you end up having large amounts of rows so that only one filter is fired for fast typers!

Get the closest class from a list jquery

It's hard to explain, so I created an example:
jsfiddle
My idea is to change the color of each column when the respective input is in action...
If anyone has a better idea to do this - please let me know!
When I focus the input, I need the current class of the column.
first column input, get the class of the RED column
and the second one, get the class of the BLUE column
and so go's on...
Because if I get the class, then I can manipulate anything with this class.
the code is here:
$(".inputTest").focusin(function(){
var class = $(this).closest('.tableList')
.children().children().children('.auxClass')
.attr('class')
.split(' ')[0];
alert(class);
});
This is the main code, I try alot of stuffs to get, but nothing.
Thanks
First I'd add an outer table to split the page in a left and a right hand side. That way, the inputs below the red border and the inputs below the blue border each have their own table.
Then you can search for the first td below the closest table:
$(".inputTest").focusin(function(){
var class = $(this).closest('table').find('td:eq(0)').attr('class');
alert(class);
});
Click for working jsfiddle example.
Try this:
$(".inputTest").focus(function(){
var class = $(this).closest('table').parent().attr('class');
alert(class);
});
Edit: Oh, i just realised your inputs are not inside your tables, i think you're gonna have a hard time matching them up to the table/column they're under then. You'd need to add a common attribute to identify them by.
As mentioned in other answers your inputs are not actually in the same "columns" as your red/blue bordered tables, but you can make it so they are using the <col> element on the main table, then using the index value you can match your inputs to their column
Working Example
HTML - the only addition is the two <col> elements at the start
<table width="100%" border="1" class='tableList'>
<col span="2" class="left">
<col span="2" class="right">
<tr>
<td class="101 auxClass" width="261px" colspan="2" style="border: solid red;">
<table border="1" cellspacing="1" cellpadding="1" width="100%" height="70px">
<tbody>
<tr>
<td colspan="2">Something</td>
</tr>
<tr>
<td width="78px">Something 2</td>
<td>Total</td>
</tr>
</tbody>
</table>
</td>
<td class="102" width="261px" colspan="2" style="border: solid blue;">
<table border="1" cellspacing="1" cellpadding="1" width="100%" height="70px">
<tbody>
<tr>
<td colspan="2">
Something 3
</td>
</tr>
<tr>
<td width="78px">Something 4</td>
<td width="75px">Total 2</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td>Result</td>
<td><input type="text" class="inputTest"/></td>
<td>Result</td>
<td><input type="text" class="inputTest"/></td>
</tr>
<tr>
<td>Result</td>
<td><input type="text" class="inputTest"/></td>
<td>Result</td>
<td><input type="text" class="inputTest"/></td>
</tr>
<tr>
<td>Result</td>
<td><input type="text" class="inputTest"/></td>
<td>Result</td>
<td><input type="text" class="inputTest"/></td>
</tr>
</table>
CSS:
col.current {background: #eee;}
jQuery
$(".inputTest").focusin(function(){
var colidx = $(this).closest('td').index();
if (colidx == 1) {
$("col").removeClass('current');
$("col.left").addClass('current');
} else if (colidx == 3) {
$("col").removeClass('current');
$("col.right").addClass('current');
}
});
Your main table is actually 4 columns, and you need to split it into two halfs of two columns each with the input being in the second column of each half
The jQuery is finding the index of the parent td of the input - there are four columns in the main table so the index of a td will either be 0,1,2 or 3 - and the input is either going to be in cell index 1 or cell index 3. When it finds out which one it add a class to the relevant col element to which you can add a background highlight..
Note though that the CSS you can apply to a col element is limited, see: http://www.quirksmode.org/css/columns.html , for the options so it would depend what you want to do
however I think from this you could probably target td index 0 & 1, or td index 2 & 3 if needed

Combining Rows in Javascript

I'm looking for some help on the Javascript angle of this problem. I have a table that goes like...
<table>
<tbody>
<tr> (Row 1)
<td colspan="3">
<p>This Says Something</p>
</td>
</tr>
<tr> (Row 1a)
<td>
<select option>
</td>
</tr>
<tr> (Row 2)
<td colspan="3">
<p>This Says Something</p>
</td>
</tr>
<tr> (Row 2a)
<td>
<select option>
</td>
</tr>
<tr>
<td colspan="3">
<p>This Says Something</p>
</td>
</tr>
<tr>
<td>
<select option>
</td>
</tr>
<tbody>
</table>
There are actually more like 20 rows and row a's but I didn't think I'd want to copy them all.
I basically need to add a container row (a single row) around every two rows (# and #a). Something like:
<tr> (Container Row 1)
<td>
+<tr> (Row 1)
+<tr> (Row 1a)
</td>
</tr>
It needs to cycle through the whole table. Somehow it has to retain the HTML data inside since all of the "a"s have options.
I hope this makes sense...
Any help would be greatly appreciated, as I'm at a loss. I'm novice at best at javascript and am struggling my way through the DOM and TOM methods.
Thank you so much in advance for any help or headway.
[EDIT] For clarification, the table is already constructed from a third party database, I am editing it after it's constructed. I guess this clarifies why it would have to be javascript to be done through the DOM.
Embed another table:
<tr> (Container Row 1)
<td>
<table>
<tr><td>(Row 1a)</td></tr>
<tr><td>(Row 1b)</td></tr>
</table>
</td>
</tr>
Or if you are wanting to do that via Javascript, you can give the parent <td> an id and set it's innerHTML.
<tr> (Container Row 1)
<td id='rowX'>
</td>
</tr>
document.getElementById('rowX').innertHTML = "<table><tr><td>(Row 1a)</td></tr><tr><td>(Row 1b)</td></tr></table>";
As mentioned in another answer you can't add tr elements directly in td like you are trying.
You would first create an inner table.
If you were using jQuery you would do something like this:
//setup some click actions just to prove that they remain attached even after moving
$('#outterTable tr').click(function(){
alert('You clicked on row: '+$(this).text());
});
//update the table (group each even row with the one after it)
$('#outterTable tr:even').each(function() {
var $tr1 = $(this),
$tr2 = $tr1.next('tr'),
$t = $('<table></table>');
$('<tr></tr>').append($t).insertBefore($tr1);
//click actions will remain attached
//if that is not required, than use $tr1.remove()
$t.append($tr1).append($tr2);
});​
See this live jsFiddle example.
without jQuery it may look like that:
<script type="text/javascript">
<!--
function fx(table)
{
var tmp=document.createElement('table');
tmp.appendChild(document.createElement('tbody'))
while(table.rows.length)
{
if(table.rows.length%2==0)
{
var wrapper=tmp.lastChild.appendChild(document.createElement('tr'));
wrapper.appendChild(document.createElement('td'));
wrapper.getElementsByTagName('TD')[0].appendChild(document.createElement('table'));
wrapper.getElementsByTagName('TD')[0].lastChild.appendChild(document.createElement('tbody'));
}
wrapper.getElementsByTagName('TD')[0].lastChild.lastChild.appendChild(table.getElementsByTagName('TR')[0])
}
table.parentNode.replaceChild(tmp,table);
tmp.setAttribute('border',1);
}
window.onload=function(){fx(document.getElementsByTagName('table')[0]);}
//-->
</script>
Example#jsFiddle
But: why do you need this grouping?
If the only benefit is a visible grouping I would prefer to do this by setting the borders of the cells .
Give all cells a border and to the even a border-top:none / to the odd a border-bottom: none

Categories

Resources