Set colspan/rowspan for a cell - javascript

I have a table and I want to change colspan/rowspan property of a cell on runtime. Here is an example:
<html>
<head>
<script type="text/javascript">
function setColSpan() {
document.getElementById('myTable').rows[0].cells[0].colSpan = 2
}
</script>
</head>
<body>
<table id="myTable" border="1">
<tr>
<td>cell 1</td>
<td>cell 2</td>
</tr>
<tr>
<td>cell 3</td>
<td>cell 4</td>
</tr>
</table>
<form>
<input type="button" onclick="setColSpan()" value="Change colspan">
</form>
</body>
</html>
My problem is that the cells shift. Am I supposed to remove the cells over which the cell in question spans?
I can I do without removing?
I want to implement a simple spreadsheet. For now I managed to be able to select a rectangular range of cells and show a menu with a "Merge selected cells" option. I would like to be able to "unmerge" cells, so it would be good to span cells without having to remove other cells.

I think you need to delete the cell. Check with following code. What i did was removed the entire row and added new row with new column span
function setColSpan() {
var table = document.getElementById('myTable');
table.deleteRow(0);
var row = table.insertRow(0);
var cell = row.insertCell(0);
cell.innerHTML= "cell 1"
cell.colSpan = 2
}

The cells shift because that's what you're telling it to do. You're defining a table like this:
<tr>
<td colspan="2">cell 1</td>
<td>cell 2</td>
</tr>
<tr>
<td>cell 3</td>
<td>cell 4</td>
</tr>
So the shift you're seeing is what I would expect.
If you want to merge cells, you would have to take the contents of all the merged cells, concat them into a single cell, and remove the rest. For the trivial example, it'd go like this:
function setColSpan() {
var myTable = document.getElementById('myTable');
var cell2html = myTable.rows[0].cells[1].innerHTML;
myTable.rows[0].deleteCell(1);
myTable.rows[0].cells[0].innerHTML = myTable.rows[0].cells[0].innerHTML + ' ' + cell2html;
myTable.rows[0].cells[0].colSpan = 2;
}
However a more robust solution is...kind of complicated. Especially if you want the ability to unmerge. You'd have to preserve the information of the old cell structure somehow...possibly with putting something like <span class="oldCell">cell 2</span> around merged data? And then checking for the existence of "oldCell" spans when unmerging? But then you would have to preserve that information through user edits. And figure out what that means for merging across rows and columns. And also figure out what that means for overlapping merges.

Related

Access to cell attributes with row id

I have the following table and jQuery code to create an object based on some columns/cells data-attributes:
<tbody>
<tr id="1">
<td data-name1="Name 1">Name 1</td>
<td data-name2="Name 2">Name 2</td>
<td data-name3="Name 3">Name 3</td>
</tr>
<tr id="2">
<td data-name1="Name 1">Name 1</td>
<td data-name2="Name 2">Name 2</td>
<td data-name3="Name 3">Name 3</td>
</tr>
</tbody>
Right now I have stored all the tr id's in a variable so I have this jQuery code:
for (var x = 0; x < idsVar.length; x++) {
var tdName1 = $(`#${idsVar[x]} > td`).attr('data-name1');
var tdName2 = $(`#${idsVar[x]} > td`).attr('data-name2');
}
This code seems to work. The problem is that now I'm implementing jQuery DataTables library with default pagination and the problem I'm facing is that for example; if my table contains more than 1 page the above code only works for the rows on the current page, if I want to access to the rows from other page they doesn't exists for my jQuery code.
I was reading the DataTables documentation and seems that this code could help:
var table = $('#example').DataTable();
table.rows().nodes().etc...
But I think that code loops throught all the table rows and what I'm trying to do is only on some specific row ids. So my question is how can I access to a specific row id and some data attributes. Maybe something like:
table.rows('specificId').nodes('data-attribute')
or
table.rows('specificId').nodes().something to get the data attribute
To access to a specific row by its ID you can use this:
var row = table.row('#idHere')
And for access to the data attributes of that row you can use this:
var row = table.row('#idHere').nodes()[0];
$(row).attr('data-attributeName');
Please go to datatable docs for more information.

Vuejs - tr row not showing 100% when adding display block

In my VuewJS application, I want to be able to click a row and show/hide the row below. However, when I do that I get a weird bug were the row below only fills one column width.
Here is my table structure:
NOTE: This table is generated dynamically.
The top row with 4 columns has an attribute of id and the long row that fills up 4 columns has a a data attribute data-body-id.
<tr v-bind:key="data.id" v-bind:id="index" v-on:click="rowClick(index)">
<td>Col 1</td>
<td>Col 2</td>
<td>Col 3</td>
<td>Col 4</td>
</tr>
<tr v-bind:key="data.id" v-bind:data-body-id="index">
<td colspan="4">Col 5 (This is a really long 4 colspan row ..............)</td>
</tr>
which computes as:
<tr data-v-1a25d82d="" id="0">
<td data-v-1a25d82d="">Col 1</td>
<td data-v-1a25d82d="">Col 2</td>
<td data-v-1a25d82d="">Col 3</td>
<td data-v-1a25d82d="">Col 4</td>
</tr>
<tr data-v-1a25d82d="" data-body-id="0">
<td data-v-1a25d82d="" colspan="4">Col 5 (This is a really long 4 colspan row ..............)</td>
</tr>
in my rowClick(index) method I have:
methods: {
rowClick(id) {
var dataId = "data-body-id='" + id + "'";
var row = document.querySelector('[' + dataId + ']');
row.style.display = 'block';
}
}
When I click a row, the row below is visible but it shows like so:
If I use the developer inspector and find the attribute and uncheck the display: none; that is set in the CSS initially to hide the row it shows perfectly.
What is going on and how do I fix it?
When trying to show dynamic table rows that are hidden please use:
display: 'table-row',
so in your case:
row.style.display = 'table-row';

Load HTML content in a newly created table row

I've got a web page of very neatly structured data. There are about 20 "parents" and about 1000 "children". Right now I show a huge table of all the children. What I want to do is display the table of parents, and have a button/toggle for each row that when clicked would:
add a row beneath that parent in the table
execute a GET request to display an HTML table of children in that row
on the next click the button/toggle would remove that row from the table
My HTML looks like this:
<table id="tableofparents">
<tr>
<th>Buttons</th>
<th>Col B</th>
<th>Col C</th>
</tr>
<tr class="adder" id="101">
<td id="101" class="toggleChildren">Button</td> # unique id per row already exists
<td>Info Field 1</td>
<td>Info Field 2</td>
</tr>
<tr class="adder" id="202">
<td id="202" class="toggleChildren">Button</td>
<td>Info Field 1</td>
<td>Info Field 2</td>
</tr>
</table>
I figured out the code to toggle creation/deletion of a new table row here from here - Toggle between the creation and destruction of a table row jquery
<script type="text/javascript">
$(document).ready(function()
{
$('#tableofparents').on('click', ".toggleChildren", function () {
var thisRow = $(this).parents('tr.adder');
var hasNextRow = thisRow.next('tr.added').length;
if (hasNextRow) {
thisRow.next('tr.added').remove();
} else {
$(this).parents('tr.adder').after('<tr class="added"><td colspan="3" >This is where I want to load the HTML of the children via a GET request</td></tr>');
}
});
}
</script>
When I click on the button in the first row, it now toggles the addition of a new table row. But I also need that same click to execute a GET request to http://example.com/childdata?id=101 and load the HTML from that request into the new row, and I just can't figure out how to do that.
Is there a way to load HTML into the newly created row?
In your else statement you can do this:
var parent = $(this).parents('tr.adder'), id = parent.attr('id');
$.get('http://example.com/childdata?id='+id, function(html) {
parent.after('<tr class="added"><td colspan="3" >'+html+'</td></tr>');
});
I hope this will help you.

Save each table column in a variable

For a jQuery plugin I need to add / remove classes to table columns. To do that I want to save each table column (multiple <td>) in its one variable once. The HTML for the table looks more or less like this:
<table>
<tr>
<td>Column 1</td>
<td>Column 2</td>
<td>Column 3</td>
</tr>
<tr>
<td>Column 1</td>
<td>Column 2</td>
<td>Column 3</td>
</tr>
</table>
In the end I want an array like $tableColumn[] or something, so that I can just add a class to my first column with $tableColumn[ 0 ].addClass('test');.
I could loop through each <tr> and <td>, but I'm not sure how to add multiple td to the same variable? Is there any other and better (e.g better performance) way to do that?
var $tableColumn = [];
$('table tr').each(function() {
// Loop through all rows
$( this ).find('td').each(function( idx ) {
// If I do something like this, there's only one td in my array
// Probably there is a better way to do this without needing to have two 'each' functions
$tableColumn[ idx ] = $( this );
});
});
First of, why is there two table ? You don't need to have a table tag for each row.
For your question and since you use jquery you can try something like this : (by using CSS3 selector)
$('table tr td:nth-child(' +columnNumber +')').addClass( className )
The nth-child selector will effectively select the columnNumber child of each row (tr) and therefore $('table tr td:nth-child(columnNumber)') get the columnNumber-th column of the table.
jsBin : http://jsbin.com/qisosado/2/edit?html,css,js,output
You could use nth-child to create an array of jQuery selections.
var i,
columns = [],
nColumns = $('table tr:first td').length;
for(i = 1; i <= nColumns; i ++) {
columns.push($('td:nth-child(' + i + ')'));
}
columns[0].addClass('a');
columns[1].addClass('b');
http://jsfiddle.net/gb0y0y6g/
Alternatively, check out the col tag.
i have created a jsfiddle for you..
for single column in row:-
code:-
var tableColumn = [];
$(document).ready(function() {
$('table tr td').each(function() {
tableColumn.push($(this));
});
//access the td from the array
tableColumn[0].addClass("yellow")
});
working example:-
http://jsfiddle.net/zoohcveh/12/
for all columns in row:-
code:-
var tableColumn = [];
$(document).ready(function() {
$('table tr').each(function() {
tableColumn.push($(this));
});
//access all the td from the array
tableColumn[0].addClass("yellow")
});
working example:-http://jsfiddle.net/zoohcveh/13/
thanks
You could use a column group if you're trying to do column specific things, like changing the background color of every cell in a column.
You can also use jQuery selectors to get a specific group of cells out of a collection.
jsbin: http://jsfiddle.net/pqm2gbqz/
HTML:
<button>Toggle</button>
<table>
<colgroup>
<col />
<col />
<col />
</colgroup>
<tbody>
<tr>
<td>Column 1</td>
<td>Column 2</td>
<td>Column 3</td>
</tr>
<tr>
<td>Column 1 row 2</td>
<td>Column 2 row 2</td>
<td>Column 3 row 2</td>
</tr>
</tbody>
</table>
JS:
var colgroup = document.querySelectorAll('col'),
button = document.querySelector('button'),
$tds = $("table").find("td")
;
button.addEventListener('click', function(e) {
e.preventDefault();
colgroup.item(0).classList.toggle('some-class');
$tds.filter(":last-of-type").toggleClass('hide');
});
CSS:
.some-class {
background: green;
}
.hide {
display: none;
}

How can I loop through all elements of a certain type through jQuery?

There are some similar questions, but mine is a little bit more specific.
I have a table element with an id of "myTable" and some tr elements inside it (let's say the tr elements are 2).
<table id="myTable">
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
</table>
If I try to see the number of rows in the #myTable table element, by writing
var numberOfRows = $("#myTable tr").length;
I always have 1 in the numberOfRows variable.
It only works when I add a class to all the tr elements.
<table id="myTable">
<tr class="myRows">
<td>Row 1</td>
</tr>
<tr class="myRows">
<td>Row 2</td>
</tr>
</table>
Let's say the class is "myRows" and write the following:
var numberOfRows = $("#myTable .myRows").length;
Then, I get the right number - 2.
So, my question is how can I get the number of certain elements or loop through them if they are not distinguished by a class (like in the example above)?
you can use like :
$('#myTable > tbody > tr').each(function() {...code...});
Pure JavaScript that also works in all meyor browsers
var rows=document.getElementById("myTable").rows;
for(var rowIndex=0;rowIndex<rows.lenght;rowIndex++){
//now do everything with tr $(rows[rowIndex]).height(80)
}

Categories

Resources