I have an HTML table that has a delete button in the last column of every row. I am attempting to make each complete row deletable using the JS code below. I am able to get a console readout of what seems to be the correct tr to delete with console.log but am unable to figure out the code for actually deleting it:
var bns = document.getElementsByTagName("button");
for (var i = 0; i < bns.length; i++) {
bns[i].addEventListener("click", function()
{
console.log(this.parentNode.parentNode);
});
}
Related
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.
I have a grid with a good amount of data which the user can filter or show/hide groups of columns by using combo boxes. Some of the column switches take a long time to load and I want to call setLoading(true,true) on the grid or the combobox to show the user that the browser is working.
I have a listener function that is called when the user makes a selection on the combo box. I call combo.setLoading(true,true) before starting any of the code that takes a while to execute. Then I call combo.setLoading(false,false) at the very bottom of the function.
The loading only shows up for a split second after the code between the two setLoading calls has executed. If I take out the call to remove the loading icon, the icon still only shows up after the code is executed.
Anyone have an idea what is happening? This seems very odd to me.
categorycomboselect: function(combo, records){
combo.setLoading(true,true);
var panel = combo.up('panel');
console.log(panel);
var category = records[0].data.name;
var grid = Ext.ComponentQuery.query('grid')[1];
Ext.suspendLayouts();
grid.suspendedLayout=true;
var columns = grid.columns;//.getView().getGridColumns();
//slow code that shows/hides columns
grid.suspendedLayout=false;
Ext.resumeLayouts(true);
combo.setLoading(false,false);
},
UPDATE
Here is my code with Trimboli's suggestion, it still isn't working. I'm showing/hiding the columns based on a string in their ID. I did it this way because the categories I want to show/hide the columns on are dynamic and the columns are dynamic.
categorycomboselect: function(combo, records){
combo.setLoading(true,true);
setTimeout( function(){
var panel = combo.up('panel');
var category = records[0].data.name;
var grid = Ext.ComponentQuery.query('grid')[1];
Ext.suspendLayouts();
grid.suspendedLayout=true;
var columns = grid.columns;
if(category=='All grade items'){
for(var i = 0; i< columns.length; i++){
columns[i].setVisible(true);
}
}else{
for(var i = 0; i< columns.length; i++){
columns[i].hide();//setVisible(false);
if(!(typeof columns[i].itemId ==='undefined')){
if((columns[i].itemId).indexOf(category)>=0){
columns[i].show();
}
}
}
}
grid.suspendedLayout=false;
Ext.resumeLayouts(true);
combo.setLoading(false,false);
},1);
},
Also, I wasnt sure if
Ext.suspendLayouts();
grid.suspendedLayout=true;
do the same thing or not. And if not, which is better.
What you're essentially doing is this:
showMask();
for (i = 0; i < 10000000; ++i) {
// busy loop
}
hideMask();
If you show/hide a mask without giving the browser a "break" for it to update the DOM, you won't see anything because it all gets flushed out at the end once you relinquish control back to the browser.
If you wanted to let the mask actually show, you need to give a slight delay before continuing on with your busy loop:
showMask();
setTimeout(function() {
// Busy stuff
hideMask();
}, 1);
For example I selected (checked) 2 rows from second page than go to first page and select 3 rows. I want get information from 5 selected rows when I stay at first page.
$('tr.row_selected') - not working
Thanks.
Upd.
I created handler somthing like this:
$('#example').find('tr td.sel-checkbox').live("click", function () {
/*code here*/
});
But right now when click event is hadle the row from table is hidding. I think it may be sorting or grouping operation of DataTables. Any idea what I must do with this?
When a checkbox gets selected, store the row information you want in a global object as a Key-Value pair
I don't remember specifically how i did it before but the syntax was something like
$('input[type=checkbox]').click(function()
{
var row = $(this).parent(); //this or something like it, you want the TR element, it's just a matter of how far up you need to go
var columns = row.children(); //these are the td elements
var id = columns[0].val(); //since these are TDs, you may need to go down another element to get to the actual value
if (!this.checked) //becomes checked (not sure may be the other way around, don't remember when this event will get fired)
{
var val1 = columns[1].val();
var val2 = columns[2].val();
myCheckValues[id] =[val1,val2]; //Add the data to your global object which should be declared on document ready
}
else delete myCheckValues[id];
});
When you submit, get the selected rows from your object:
for (var i = 0; i < myCheckValues.length; i++)
...
Sorry, haven't done JS in a long time so code as is might not work but you get the idea.
$('#example').find('tr td.sel-checkbox').live("click", function () {
var data = oTable.fnGetData(this);
// get key and data value from data object
var isSelected = $(this).hasClass('row_selected');
if(isSelected) {
myCheckValues[key] = value;
checkedCount++;
} else {
delete myCheckValues[key];
checkedCount--;
}
});
.....
On submit
if(checkedCount > 0) {
for(var ArrVal in myCheckValues) {
var values = myCheckValues[ArrVal]; // manipulate with checked rows values data
}
}
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.
function newRow(t) {
var parent = t.parentNode.parentNode.parentNode;
var row = t.parentNode.parentNode.cloneNode(true);
row.firstChild.nextSibling.firstChild.setAttribute('value', 'sumit');
parent.appendChild(row);
}
function removeRow(t) {
var y = t.parentNode.parentNode;
y.parentNode.removeChild(y);
}
the above code is working fine but i want to delete all the clones at once which are created by above code on a onchange event of a select box
Just add a class name to the cloned elements which would allow you to search for them and delete them later:
var row = t.parentNode.parentNode.cloneNode(true);
row.className += ' clonedrow';
...
// Remove all the cloned rows
var clonedRows = document.querySelectorAll('.clonedrow');
for (var i = 0; i < clonedRows.length; i++) {
clonedRows[i].parentNode.removeChild(clonedRows[i]);
}
Once the cloned rows have been added to the DOM, they look (to JavaScript) just like the original rows.
Since you're just appending cloned rows to the table body, what I would do is as follows:
Outside the functions, as soon as the document loads, use .childNodes.length to get the number of rows in your table and store it globally in, say, lastpos.
When you need to delete the clones, start at .childNodes[lastpos] and remove nodes until the table has lastpos rows again.