Hide table column ondblclick - javascript

I have a table and I want to hide a column when I double click a column.
Code for hiding a column is practically all around Stack Overflow. All I need is a hint on how/where to add the ondblclick event so I can retrieve the identity of a <td> within a <table>.

Here are two solutions that should work. One done with jQuery and one with only standard Javascript.
http://jsfiddle.net/GNFN2/2/
// Iterate over each table, row and cell, and bind a click handler
// to each one, keeping track of which column each table cell was in.
var tables = document.getElementsByTagName('table');
for (var i = 0; i < tables.length; i++) {
var rows = tables[i].getElementsByTagName('tr');
for (var j = 0; j < rows.length; j++) {
var cells = rows[j].getElementsByTagName('td');
for (var k = 0; k < cells.length; k++) {
// Bind our handler, capturing the list of rows and colum.
cells[k].ondblclick = column_hide_handler(rows, k);
}
}
}
// Get a click handler function, keeping track of all rows and
// the column that this function should hide.
function column_hide_handler(rows, col) {
return function(e) {
// When the handler is triggered, hide the given column
// in each of the rows that were found previously.
for (var i = 0; i < rows.length; i++) {
var cells = rows[i].getElementsByTagName('td');
if (cells[col]) {
cells[col].style.display = 'none';
}
}
}
}
With jQuery it is much cleaner. This method also uses event bubbling, so you don't need to bind an event handler to each table cell individually.
http://jsfiddle.net/YCKZv/4/
// Bind a general click handler to the table that will trigger
// for all table cells that are clicked on.
$('table').on('dblclick', 'td', function() {
// Find the row that was clicked.
var col = $(this).closest('tr').children('td').index(this);
if (col !== -1) {
// Go through each row of the table and hide the clicked column.
$(this).closest('table').find('tr').each(function() {
$(this).find('td').eq(col).hide();
});
}
});

You can do this way:
<td ondblclick="this.style.display = 'none';">Some Stuff</td>
Here this refers to current td clicked.
Working Example
To go unobtrusive, you can do that easily using jQuery if you want:
$('#tableID td').dblclick(function(){
$(this).hide();
});

Due to lack of answears I came up with a workaround, which is a big ugly, but it works fine.
On the window load event I decided to iterate the table and set each 's onclick event to call my show_hide_column function with the column parameter set from the iteration.
window.onload = function () {
var headers = document.getElementsByTagName('th');
for (index in headers) {
headers[index].onclick = function (e) {
show_hide_column(index, false)
}
}
}
show_hide_column is a function that can be easily googled and the code is here:
function show_hide_column(col_no, do_show) {
var stl;
if (do_show) stl = 'table-cell'
else stl = 'none';
var tbl = document.getElementById('table_id');
var rows = tbl.getElementsByTagName('tr');
var headers = tbl.getElementsByTagName('th');
headers[col_no].style.display=stl;
for (var row=1; row<rows.length; row++) {
var cels = rows[row].getElementsByTagName('td')
cels[col_no].style.display=stl;
}
}
Note: my html only had one table so the code also assumes this. If you have more table you should tinker with it a little. Also it assumes the table has table headers ();
Also I noted this to be an ugly approach as I was expecting to be able to extract the index of a table cell from the table without having to iterate it on load.

Related

Is it possible to add an eventlistener on an object that is modified through javascript?

I have a table where the sum of the rows are updated with javascript when a user changes the quantity within a popup modal. I want to be able to update the grand total of all my rows every time the total of a row change.
I have tried to add an event listener onchange and oninput on the total of each of my row but it doesn't work. I have tried to find a workaround by adding an event listener on the quantity the user is changing but to no effect. I have tried the code in the console and it is working but the event-listener doesn't seem to trigger.
document.getElementById("work_quantity_<%= #work_detail.id %>").addEventListener("change", grandTotal)
var work_detail_quantity = document.getElementById("work_quantity_<%= #work_detail.id %>").value;
var work_detail_block = document.getElementById("work-<%= #work_detail.id %>");
var quant = work_detail_block.getElementsByTagName('td')[1];
quant.innerHTML = work_detail_quantity+" <%= #work_detail.work_resource.unit_measure%>";
function grandTotal() {
var sub_total = document.getElementById("subtotal_lign").innerHTML
var table = document.getElementById("invoice_summary"), sumVal = 0;
for(var i = 1; i < table.rows.length; i++)
{
sumVal = sumVal+ parseFloat(table.rows[i].cells[4].innerText.replace(/[^0-9-.]/g, ''));
}
document.getElementById("subtotal_lign").innerHTML = sumVal.toFixed(2) + ' €' ;
};
If someone could give me a hint it would be more than appreciated, I am a rookie in javascript. Thank you
It's not a good idea to parse the DOM like that to get the values.
Solution 1
You get the object that contains the values of your table form Ruby. Something like that:
var works = <%= #works.to_json %>;
Then, when a user updates his order, you first update the object and then you update the table based on the updated object.
Solution 2
When a user update his order, you send the update to your server and you update the table in the server side.
Solution 3 (Not recommended)
If you still want to do it by parsing the DOM, have a look at MutationObserver to listen the changes in your table.
I confess, I haven't tried this per say; but I did try in jQuery a similar thing, mainly because your example lacks the detail of the table;
but you need to trigger the event when a change occurs, I assume here your not using standard input fields, so are you using like <td contenteditable></td>, they can't be monitored for change, but keyup and blur can be monitored, so if you want to trigger the calc on blur, when that event occurs, trigger your table sum event...
I'd actually use jQuery for this but here goes ...
document.getElementById("work_quantity_<%= #work_detail.id %>").addEventListener("change", grandTotal)
...
function grandTotal() {
var sub_total = document.getElementById("subtotal_lign").innerHTML
var table = document.getElementById("invoice_summary"), sumVal = 0;
for(var i = 1; i < table.rows.length; i++) {
sumVal = sumVal+ parseFloat(table.rows[i].cells[4].innerText.replace(/[^0-9-.]/g, ''));
}
document.getElementById("subtotal_lign").innerHTML = sumVal.toFixed(2) + ' €' ;
};
// something like this
(function() {
// i assume it's cell[4] that is being edited, and it's like contenteditable
var table = document.getElementById("invoice_summary");
for(var i = 1; i < table.rows.length; i++) {
/* assign listener on the cell,
when it blurs, trigger the update,
you could also monitor keyup
*/
table.rows[i].cells[4].addEventListener("blur", function(e) {
document.getElementById("work_quantity_<%= #work_detail.id %>").dispatchEvent("change", grandTotal);
});
}
})();
Updated
I thought that what I wrote below was working but actually the grand total is always one computation behind as it is doing the sum of the rows before the total of the modified row has been updated after a change of quantity.
Ok it is working with a workaround, but I still believe MutationObservers could be a good way to resolve this kind of problem in the future
Good tutorial: for MutationObservers
To make my event listener work I add to define it before the change in the quantity is made by the user (stupid isn't it)
1) Add the event listener to the object you are tracking
document.getElementById("work_quantity_<%= #work_detail.id %>").addEventListener("input", grandTotal)
2) This is where my object is changed with javascript
var work_detail_block = document.getElementById("work-<%= #work_detail.id %>");
var quant = work_detail_block.getElementsByTagName('td')[1];
quant.innerHTML = work_detail_quantity+" <%= #work_detail.work_resource.unit_measure%>";
3) I define the function which is called in the step 1
function grandTotal() {
var sub_total = document.getElementById("subtotal_lign").innerHTML
var table = document.getElementById("invoice_summary"), sumVal = 0;
for(var i = 1; i < table.rows.length; i++)
{
sumVal = sumVal+ parseFloat(table.rows[i].cells[4].innerText.replace(/[^0-9-.]/g, ''));
}
document.getElementById("subtotal_lign").innerHTML = sumVal.toFixed(2) + ' €' ;
};

javascript highlight multiple rows

I have looked all over but can't find a good answer.
So what I'm wanting to do is highlight multiple rows on a table
Then if you click on a highlighted row it gets un-highlighted.
All of this works for me. The problem I'm having is when I un-highlight a row for some reason it won't highlight again.
function highlight_row() {
var table = document.getElementById("display-table");
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
cell.onclick = function () {
var rowId = this.parentNode.rowIndex;
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.className += "selected";
$(cell).toggleClass('selected');
}
}
}
I have changed out $(cell) with $(this) and that works but only re highlighting the cell I click on and not the whole row.
I'm at a lose here.
Thanks
If you want to highlight the whole row, you need to get parent tr
cell.onclick = function () {
$(this).parent('tr').toggleClass('selected');
}

How to set empty data text in a groupable kendo grid?

I am having a groupable kendo grid.
Please help me out with setting some custom text whenever the grid is empty.
If grid is not groupable i could acheive it using databound funtion.
Here's a version I adapted from KendoGridBinderEx as I wanted a function on databound that could handle not only empty but error cases too. I've modified it back to mostly suit what you're struggling with. When my datasource has errors I'll read them out of the event that I pass into the function itself, thus why you see 'e' referenced as a parameter but not used.
function DisplayNoResultsFound(evt) {
var grid = evt.sender.element;
//Only do this if you can properly find the grid
if (grid.data("kendoGrid") == undefined) {
return;
}
// Get the number of Columns in the grid
var dataSource = grid.data("kendoGrid").dataSource;
var colCount = grid.find('.k-grid-header colgroup > col').length;
//Check for an empty datasource
if (dataSource._view.length == 0) {
//Clear the grid
//you may or may not need this depending on how your datasource returns
grid.find('.k-grid-content tbody').empty();
//Add the no result row
grid.find('.k-grid-content tbody')
.append('<tr class="kendo-data-row"><td colspan="' + colCount + '" style="text-align:center" class="k-state-error"><b>No Results Found</b></td></tr>');
}
// Get visible row count
var rowCount = grid.find('.k-grid-content tbody tr').length;
// If the row count is less that the page size add in the number of missing rows
if (rowCount < dataSource._take) {
var addRows = dataSource._take - rowCount;
for (var i = 0; i < addRows; i++) {
grid.find('.k-grid-content tbody').append('<tr class="kendo-data-row"><td> </td></tr>');
}
}
}
EDIT: Here's a JSFiddle example

Get table cell value on first rowclick in javascript

I am trying to get a value of a cell in a html table within JavaScript. I can do this when the row is clicked twice or when I click on a row and then another row but I need to get the cell value on first click
This is my code so far
var table = document.getElementById('ContentPlaceHolder1_htmltable');
if (table != null) {
for (var i = 0; i < table.rows.length; i++) {
for (var j = 0; j < table.rows[i].cells.length; j++)
table.rows[i].cells[j].onclick = function () {
cellvalue = this.innerHTML;
};
}
}
This runs on an onclick event on the ASPxListBox object from devexpress I am using.
Note: I can't use third party libraries like jQuery for this.
Thanks
The jsfiddle code posted by arcade Gandalf above does work, however, to fix my problem of getting the cell value on first click, the code needs to run when the page load is complete
window.onload = getCellValueOfTable;
function getCellValueOfTable {
jsFiddle code or my code posted above...
}
Then in the onclick event for the listbox or a table as I described in the question, just call the above function and that is all.

Add Button into HTML Table with JavaScript without generator file

I apologize in advance, English is not my native language.
I am working on a project that was delegated to me. I am working on a webpage, that is being generated by an XSLT file. I only have access to the source code of the generated page.
What does it do: The page shows a synopsis in form of a table. The left most column (lets call that one A) and the top most row (lets call it B) are the Header (?) segments (like in this table i found on google)
There are also Buttons in the top most row to sort the table.
Now the problem: There is a button to invert the table which activates the following code. This is where the problem is
I have this java code
// FAULTY FUNCTION BEGINNING
function swap_table_horizontally_vertically() {
//This is the code I already have
// Deletes all sort buttons
for (i = 0; i <= 1000; i++) {
try {
var sort_buttons = document.getElementById('sort_buttons');
}
catch(err) {
alert(err.message);
continue;
} finally {
sort_buttons.parentNode.removeChild(sort_buttons);
}
}
//End of the Code I made
//This code was already in the file
var old_table = document.getElementById('synopsis_table'),
old_table_rows = old_table.getElementsByTagName('tr'),
cols = old_table_rows.length, rows = old_table_rows[0].getElementsByTagName('td').length,
cell, next, temp_row, i = 0, new_table = document.createElement('table');
while(i < rows) {
cell = 0;
temp_row = document.createElement('tr');
if (i == 0) {
while(cell < cols) {
next = old_table_rows[cell++].getElementsByTagName('td')[0];
temp_row.appendChild(next);
}
new_table.appendChild(temp_row);
++i;
}
else {
while(cell < cols) {
next = old_table_rows[cell++].getElementsByTagName('td')[0];
temp_row.appendChild(next);
}
new_table.appendChild(temp_row);
++i;
}
}
old_table.parentNode.replaceChild(new_table, old_table);
new_table.setAttribute("id", "synopsis_table");
}
// FAULTY FUNCTION END
Now what I need is a way to add the buttons again into the new table head (top most row) with a class and id attribute.
To summarize: I need to delete the buttons from the previous top most row (because the left column shouldn't have them) and add them again to the new top most row (the previous left column).

Categories

Resources