Is there any way to figure out which cell position is clicked if you have merged table cells? We have 20 cells etc merged together and we would like to figure out if the user has clicked on what would have been for example the 7th cell
We have merged cells which mean specific things but we now need to figure out logically which cell was clicked by a user (even though they are merged).
Is this possible?
You can judge it based on the dimensions of unmerged cells in the same table. Here is an example using jQuery (just because it's much more concise than native JS to demonstrate this point):
var $mergedTd = $('td.myMergedTd'),
$unmergedThs = $('th');
$mergedTd.click(function(e) {
var clickedUnmergedIndex = 0;
$unmergedThs.each(function(i) {
var $th = $(this);
if(e.pageX < $th.pageX + $th.width()) {
clickedUnmergedIndex = i;
} else {
// Stop iterating; we've found the unmerged index
return false;
}
});
alert('You just clicked 0-based cell index #' + clickedUnmergedIndex);
});
I would keep two copies of that table in DOM. One visible and one hidden. You take click events on the visible table, and before you merge the cells, mark the clicked cell (e.g. add a data attribute to it indicating it was marked such as data-marked='1') and copy that table to the hidden one.
Related
I'm using ChartJS to generate a pie chart in that elements are added every time the user clicks a specific button (I have 14 buttons that trigger the adding of a specific element in the pie chart, each one triggers a function that adds info to 3 arrays as needed in order for the chart to work.
Every time the user clicks a button a new one is created in a div that contains all the elements that are present in the chart because I want them to be able edit or delete the elements as needed.
To know what which elements from my arrays is edited by which edit button I'm using a variable named btnctr that I initialized with 0 at the beginning of my JS file. That variable gives every new ”edit button” an ID and then then increments, like this:
function CreateEditButton() {
var buttonnode= document.createElement('input');
buttonnode.setAttribute('type','button');
buttonnode.setAttribute('id',btnctr);
...
$("#rotationelements").append(buttonnode);
$("#rotationelements").append(' ');
btnctr++;
};
My problem is that I also have to make deleting elements possible. I'm using splice for deleting elements from the arrays, but that also messes up the position of other elements and my edit buttons become useless.
I want to also edit the IDs of my buttons when I delete elements, because I need them to be in sync.
Here's what I've come with so far:
// Get editbuttons
var editbuttons = document.getElementsByClassName('editbtn');
// Delete element
function deleteElement (x) {
names.splice(x,1);
dataset.splice(x,1);
colors.splice(x,1);
chart1.update();
time=time-length[x];
length.splice(x,1);
UpdateTime();
var delbtn=$("#"+x);
$(delbtn).remove();
var newid=x;
for (var i=0; i<editbuttons.length;i++) {
if (editbuttons[i].id>x) {
editbuttons[i].id=newid;
newid++;
btnctr=newid++;
}
}
}
Thanks!
Lulian, inside of your for loop it looks like you are only changing the id's of editbtns after the one that was deleted above. You may want to try taking out the if statement and replacing "newid" with "i":
for (var i=0; i<editbuttons.length;i++) {
// if (editbuttons[i].id>x) {
editbuttons[i].id=i;
//newid++;
btnctr=i;
// }
}
This way you can re-initialize all of you editbtn's and btnctr to match from beginning to end.
Suppose there is Table with variable number of rows of fixed number of columns, and suppose each row has a button too, now I want to select for example a column's value(let's say this selected column is textarea, so I select it's content) when that row's button is clicked.
For example in above image I want that if submit is pressed than all data of 'textarea' of corresponding row should be stored in a variable.
You can use the jQuery closest() function to find an element near the clicked button. Add click handlers to the buttons and then traverse up to find the textarea.
$('.button').on("click",function(){
var thisRowsTA = $(this).closest("textarea");
console.log($(thisRowsTA).val());
});
A simply way is to:
Put an ID pattern to your textareas, like: txt_area_1, txt_area_2, txt_area_3.
Then, on the Click Event of your buttons, make them catch the corresponding textarea in their row. Use the ID patterns to do this.
Post your code for further help.
You will need to ad an event handler for each button. Inside of that you can write something like this.
function eventHandler(e){
var row = this; // start at the button
while(row.nodeName != 'TR' && row.parent){
// go up till we find the row
row = row.parent;
}
var textArea = row.querySelector('textarea');
var value = textArea.value;
// do something with supplied feedback.
}
In order to attach the handlers, you would do something like this.
function attachTableEvents(){
var table = document.querySelector('table'); // or more specific selector if needed
var buttons = table.querySelectorAll('button');
for (var i = buttons.length; i--;){
buttons[i].addEventListener(eventHandler);
}
}
Counting on the DOM structure is really BAD.
I would put an attribute in my controls that holds the line number. Then when clicking an element you can easily query the DOM by element type and the property value to get any elements in this line.
Later if you change to DIVs or change structure your will still run correctly
I have table containing 4 main rows and one (expand or collapse) button.On click of (expand or collapse) button i want to insert one more row in middle of all rows(which result in total 8 rows) by iterating the table rows.How to do this using Javascript?See the image below.Any suggestion.
This is the code i have return on click of Expand or Collapse button,
jQuery('#btnId').click(function() {
var that = this;
$("#example tbody tr").each(function(i) {
//what code need to add here
});
});
Due to the fact, that you haven't provided a code example, I only can suggest one way to achieve this.
You can determine the row above the row you'll want to insert by an id on the tr or by a css selector like :nth-of-type(4) for example.
After that, you can use this row as jquery element (example: $("tr#yourrow")) and append a row after it using append().
Example: $("tr#yourrow").append("<tr>... your row definition ...</tr>")
Based on the updated question:
jQuery('#btnId').click(function() {
var that = this;
$("#example tbody tr").each(function(i, object) {
$(object).after("<tr>... your row definition ...</tr>")
});
});
The row definition should be done by yourself. I don't know the logic behind the iteration in your case. But I think you'll get it. :)
I'm using knockout.js 2.3.0 and I have a table with dynamically added rows and select lists in each of these rows. Upon changing a date input, the select lists populate with different content. Because different dates will populate the lists with different content, I want to remove any previously added rows because the content may not be accurate.
The issue I'm having is that not all of the rows are being removed. Ex: If I have more than 4 rows, there will always be 2 remaining. The only time all rows are cleared is when there is only 1 row to start with.
Here's the subscribed function for deleting the rows
self.date.subscribe(function() {
//I also tried setting the loop length to a very long number but the same results happened each time
for (i = 0; i < self.customers().length; i++){
self.customers.remove(self.customers()[i]);
}
//now populate the select list and add an empty row - commented out for testing to make sure rows are being deleted
//setCustomerList(self.date());
//self.customers.push(new AddCustomer(self.customerList[0]));
});
I was just testing to see what would happen, and the only way I've gotten all of the rows to remove is by adding multiple for loops which obviously isn't desirable.
Is there a simpler way to remove all dynamically added rows?
If you want to remove all the items in an observable array, use the removeAll method:
self.customers.removeAll();
If you really want to use a loop, you could do so by continuously removing the last (or first) item until there are none left:
while (self.customers().length) {
self.customers.pop();
}
I think you need to reverse the for loop and remove the items from the bottom up. the problem with your code is that the each time an item is removed the length of the array changes.
self.date.subscribe(function() {
var customerLength = self.customers().length
for (i = customerLength ; i >= 0; i = i - 1){
self.customers.remove(self.customers()[i]);
}
});
I have a table with a set of columns fetching values from a database along with a dropdown and button in each row. Depending on the value of one of the columns(YEAR), the dropdown (SALARY) and button (UPDATE) need to be disabled.
I tried two different approaches using Javascript and Jquery. But both don't seem to work.
1) I tried triggering an event on pageload using Javascript
<body onload="dropdownDisabler();">
Javascript part:
function dropdownDisabler()
{
if ($("#YEAR").val() >= 2005)
{
$("#SALARY").enabled=false;
$("#UPDATE").enabled=false;
}
}
2) I tried matching all the YEAR column elements which have a certain criteria using JQuery:
if($('#YEAR').val() >= 2005)
{
$(this).find("#SALARY").prop('disabled',true);
$(this).find("#UPDATE").prop('disabled',true);
}
You can iterate over all the rows, check the value of the year and then set the disabled property on the select and button element in that row:
$(document).ready(function() {
$("#UpdateSalary tbody tr").each(function( index ) {
var $this = $(this);
if ($this.children("td:first").text() >= 2005 ) {
$this.find("select, button").prop("disabled", true);
}
});
});
jsFiddle Demo
Note that since you have multiple rows (I assume), you should not use IDs for your elements, ID's must be unique on each document. You could use classes though to more easily target your elements within each row, e.g. <td class="year">2004</td>