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

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';

Related

Select the first cell of each row placed after a merged cell using JavaScript/jQuery

I have a table with class evo-table, which has two cells of row span of 4, followed by four rows with two cells each (Image). I want to select the first cell of each of these rows using JavaScript. I know I could simply add classes to cells and style it using CSS but I'm restricted to the Table structure below. I am able to select and add CSS to the first cell of the first row using $(".highlight").next().css("background","lightgreen"); but I'm not able to select the first cell of the rest of the rows. Here's the code:
HTML: (This is a DEMO only)
<table class="evo-table">
<tr>
<td rowspan="4">Merged Cell 1</td>
<td rowspan="4" class="highlight">Merged Cell 2</td>
<td>Unmerged Cell 1</td>
<td>Unmerged Cell 2</td>
</tr>
<tr>
<td>Unmerged Cell 3</td>
<td>Unmerged Cell 4</td>
</tr>
<tr>
<td>Unmerged Cell 5</td>
<td>Unmerged Cell 6</td>
</tr>
<tr>
<td>Unmerged Cell 7</td>
<td>Unmerged Cell 8</td>
</tr>
<table>
jQuery/JavaScript:
var tableObj = $(".evo-table");
var mergeLength = $(".evo-table .highlight").attr("rowspan");
var firstRowAfterHighlight = $(".evolution-table .highlight").parent().next().index + 1;
$(".highlight").next().css("background","lightgreen");
for (count = 0; count < mergeLength; count = count + 1) {
$(".evolution-table tr:nth-child(" + (firstRowAfterHighlight + count) + ") td:first-child:not(.highlight)").css("background-color", "green")
}
I am using the rowspan value of .highlight cell to find the number of rows (I could use $(".evo-table tr").length; to get it but the previous one is more useful in my case as I want to select rows which are immediately to the right of the cell) and I'm finding the index of the row after first row and using count variable of the for statement to move on to the next row, and using the :first-child selector on td to select the first cell of every row. The code doesn't seem to work.
jsFiddle
Please reply if you spot any errors in my code, need more details or have a solution. Thank you.
I used the .each function to iterate over every row. And then I used teh :not selector to ignore elements with the attribute [rowspan].
$(".evo-table tr").each(function () {
$(this).find("td:not([rowspan]):first").css("background-color", "red")
});
* {
font-family:Arial;
}
.evo-table {
border-collapse:collapse;
border:1px solid lightgrey;
}
.evo-table td {
padding:4px;
border: 1px solid lightgrey;
}
.highlight {
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="evo-table">
<tr>
<td rowspan="4">Merged Cell 1</td>
<td rowspan="4" class="highlight">Merged Cell 2</td>
<td>Unmerged Cell 1</td>
<td>Unmerged Cell 2</td>
</tr>
<tr>
<td>Unmerged Cell 3</td>
<td>Unmerged Cell 4</td>
</tr>
<tr>
<td>Unmerged Cell 5</td>
<td>Unmerged Cell 6</td>
</tr>
<tr>
<td>Unmerged Cell 7</td>
<td>Unmerged Cell 8</td>
</tr>
<table>
<div style="font-size:12px;color:lightgrey;">
Yellow = .highlight class; Green = Selected using jQuery;
</div>
If you just want to do this for styling, you don't need javascript, you can do it with plain CSS3:
td[rowspan] + td:not([rowspan]), tr > td:not([rowspan]):first-child {
background: red;
}
It selects a td without a rowspan that directly follows after a td with the rowspan attribute (the first tr) and all first td in a tr that do not have a rowspan attribute (all other tr).
If you want it in JavaScript, you can use the same CSS selector with jQuery. No need to loop over the table rows:
$('td[rowspan] + td:not([rowspan]), tr > td:not([rowspan]):first-child')

Javascript getting the value of an input in a table [duplicate]

This question already has answers here:
How to retrieve value of input type in a dynamic table
(6 answers)
Closed 7 years ago.
I'm just wondering if it's possible to get the value of an html input in a table without naming each input separately and using getElementById directly onto the input so if I had the following table
<table id="table01">
<tr>
<td>row 0 cell 0</td>
<td>row 0 cell 1</td>
</tr>
<tr>
<td>row 1 cell 0</td>
<td>row 1 cell 1</td>
</tr>
</table>
I know in Javascript you can use the following to get the value of a specific cell in a specific row using the following
var lv_value = document.getElementById("table01").rows[0].cells[1].innerHTML;
console.log(lv_cont);
and this would give me the value I want which is "row 0 cell 1".
If I had a table like the following however
<table id="table01">
<tr>
<td>row 0 cell 0</td>
<td>row 0 cell 1</td>
<td><input type="text" class="tbl_input"></input></td>
</tr>
<tr>
<td>row 1 cell 0</td>
<td>row 1 cell 1</td>
<td><input type="text" class="tbl_input"></input></td>
</tr>
</table>
Is it then possible to do something along the lines of
<!-- this is obviously wrong -->
var lv_input = document.getElementById("table01").rows[0].cells[2].input.value;
console.log(lv_input);
to get the value of the input in the first row
You should do something like this:
var lv_input = document.getElementById("table01").rows[0].cells[2].firstChild.value;
console.log(lv_input);
or use the querySelector to find the input element
var lv_input = document.getElementById("table01").rows[0].cells[2].querySelector('input').value;
console.log(lv_input);

How to move/reorder an html table row

The idea is to move a particular table row to a different location
HTML
<table id="grid1" class="table table-zebra">
<tbody>
<tr>
<td>Cont 1 tr 1</td>
</tr>
<tr>
<td>Cont 2 tr 2</td>
</tr>
<tr>
<td>Cont 3 tr 3</td>
</tr>
<tr>
<td>Cont 4 tr 4</td>
</tr>
<tr>
<td>Cont 5 tr 5</td>
</tr>
<tr>
<td>Cont 6 tr 6</td>
</tr>
<tr>
<td>Cont 6 tr 6</td>
</tr>
<tr>
<td>Cont 7 tr 7</td>
</tr>
<tr>
<td>Cont 8 tr 8</td>
</tr>
<tr>
<td>Cont 9 tr 9</td>
</tr>
<tr>
<td>Cont 10 tr 10</td>
</tr>
<tr>
<td>Cont 11 tr 11</td>
</tr>
<tr>
<td>Cont 12 tr 12</td>
</tr>
<tr>
<td>Cont 13 tr 13</td>
</tr>
<tr>
<td>Cont 14 tr 14</td>
</tr>
</tbody>
</table>
That is the basic table, now, how do I can I move the TR 11 in a away that it will be under TR 4, I'm sorry that I don't post any JS but I have no idea how to do it... I was looking at this JSbin which is nice but can't use it..
Move the 11th tr to under the 4th:
$("tbody tr:nth-child(11)").insertAfter("tbody tr:nth-child(4)");
Working demo
If you prefer vanilla, you need the selectors the other way around.
document.querySelector("tbody tr:nth-child(4)").insertAdjacentElement("afterend", document.querySelector("tbody tr:nth-child(11)"));
In the context of an HTML table with rows that look like this:
<tr class="form-grid-view-row">
<td>
<a class="up" href="#">⇑</a>
</td>
<td>
<a class="down" href="#">⇓</a>
</td>
<td>
<span id="index1" class="form-label">1</span>
</td>
<td>
<span id="span1" class="form-label">Value 1</span>
</td>
</tr>
And this script:
$('.up,.down').click(function () {
var row = $(this).parents('tr:first');
if ($(this).is('.up')) {
row.insertBefore(row.prev());
} else {
row.insertAfter(row.next());
}
});
$('.up,.down').click(function () {
This is selecting every DOM element with the class "up" and every element with the class "down", e.g. $('.up,.down').click(function () {. The function sets up a click handler for each element.
var row = $(this).parents('tr:first');
$(this) refers to the DOM element which is the target of the click handler (one of the "up" or "down" elements which was selected above). .parents() looks for tr:first, the first <tr> element starting with <a> and travelling up the DOM. It'll end up selecting the entire row.
if ($(this).is('.up')) {
This is checking to see whether or not the element selected has the class "up" or not.
row.insertBefore(row.prev());
This takes the row that was clicked, and moves it right above the upper-most sibling of the row that was clicked.
The jQuery methods used (insertBefore, prev, is, parents, etc.) are described in greater detail in the jQuery documentation.
You can do it by using JQuery Library.
// selecting tbody is bad instead you need to give an id or class to this tag and select according to this
var fourth = $( "tbody tr:nth-child(4)" ),
eleventh = $( "tbody tr:nth-child(11)" );
$( "tbody tr:nth-child(11)" ).insertAfter(fourth);
In order to move dynamically your elements you can add an event to all tbody children. What I basically do is select one element on first click then I move it after second element clicked.
$(document).on("ready", function () {
var $tbody = $("#grid");
var selected = null;
$tbody.children().on("click", function () {
if (selected == null)
selected = this;
else
{
$(selected).insertAfter(this);
selected = null;
}
});
});
It move after an element but is just an idea, you can customize it.
Your html should be like this.
<table>
<tbody id="grid">
<tr> <td> 1 </td> </tr>
<tr> <td> 2 </td> </tr>
<tr> <td> 3 </td> </tr>
<tr> <td> 4 </td> </tr>
</tbody>
</table>

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)
}

Set colspan/rowspan for a cell

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.

Categories

Resources