TL;DR: the "click" listener is not accurate for table cells (td) and headers (th), seemingly listening beyond the cell's border when tapping on an iPad 2 with mobile Safari. Is this a known issue and is there a workaround?
Pretty specific question, and no sample code (there's no need). Hope somebody out there finds this question and has solved this problem before!
I have a table, built using DataTables.net and jQuery UI. That should be incidental, but I wanted to mention it anyhow. The table listens for click events (which I believe mobile Safari simply translates as taps) on a number of different elements, including row headers (for sorting) and certain cell contents.
Using Inspector on a Mac (to which the iPad is connected) I can clearly see that there are no accidentally overlapping elements in terms of padding, borders, margins, or even content that is "visibility: hidden" or anything like that. Besides, they are table cells with default behaviour; not simulations of table cells.
In the top row of actual data, if I tap anywhere in the upper half of the cell, it is actually tripping the listener for clicks in the row header. I zoom in to a ludicrous level so that I know I'm not accidentally nudging the header, and I have confirmed that the tap occurs entirely within the table cell, not the header above.
Does anyone know if there is a meta property or some CSS or even a JavaScript workaround for this lack of precision? At least half the time that I tap the cell, it's actually triggering the column sort (from a ghost header tap) instead.
The only thing I can think of as a workaround is to wrap the contents of each cell in a div or span, pad them away from the edges of the cell a bit, and hopefully artificially reduce the tap target area that way.
If the x,y coordinate is outside of the table then can you not simply ignore it?
If the click is inside the table, and the x,y coordinates are wrong then that might be a scaling issue, or a bug.
Related
Use case
I want to detect if html tables get too wide, and if so, I want to flip the table header cells to become vertical (e.g. with writing-mode: vertical-lr;).
I want to update this on resize: If the viewport gets bigger, the text in the cells might become horizontal again.
The flip condition is whether the original table with horizontal labels would be wider than its container.
Question
How do I determine the width a table would have with horizontal labels, without changing the table itself?
Thoughts
My current idea would be to make an invisible copy of the table with horizontal labels, and use it as a "sensor". But I am afraid this will pollute the DOM and cause side effects somewhere. Also I would need to keep this copy updated all the time.
Is there a "best practice" or a known pattern to solve this problem?
It is actually quite simple:
We can change the css on the table during the script run. Once we query a property like element.width, this will cause a reflow during the script execution, but it won't cause a repaint. So this means we can do the test without the need for a cloned DOM element, and without visible changes.
See https://developers.google.com/speed/docs/insights/browser-reflow
I have a scrolling tbody in my html page. For certain reasons (mainly performance reasons) I only show 25 rows in that div instead of the 1.000 or 10.000 rows that exist in the underlying data variable / DB.
Right now I do something much alike to what DataTables.net does; I rotate the contents of those 25 rows on scroll event. Works fine.
One thing that annoys me though is that for instance you have 1000 rows, 25 showing: the scrollbar moves just like always but only takes in to account the 25 rows (because it only sees those, duh ;-) ).
DataTables' solution though show a scrollbar that moves down according to those 1000 rows so it moves a lot slower and dragging it all the way down really goes to record 1000 instead of 25.
Does anyone know how to maybe influence the 'presentation' of the scrollbar in a way that DataTables are able to? (I've googled a lot but no dice)
I use html5, Javascript / jQuery and PHP.
You can set the length of the scrolling container depending on the total number of rows, then dynamically load the visible rows into view, when the user stops scrolling.
This means that you need to know the exact height of one row, and you'll have to manually position the rows in the container. Sorting the rows might be an interesting problem then.
To make that all a little easier, it might perform well enough if you add only the 1.000 rows, without the data, then dynamically load the data.
I have an Ant Design table where columns are resizable using react-resizable and drag-able using react-drag-listview.
All of the features are working nicely although there is a bug that exhibits itself under certain circumstances which means that the entire solution to having those features working together might not be viable or ready for production.
Here is the correct behaviour - when clicking on a table header cell the entire cell is dragged and you can see the box-shadow around its borders like this:
The bug is that sometimes after resizing a column and then clicking the header cell of the column to the right, the header cell is not dragged, only the the content (text in this case) / column title is, which looks like this:
Here is a code sandbox and a step by step guide on how to recreate the bug:
Go to the code sandbox
Click on the right hand border of any column
Drag and resize that column to the right / bigger until the mouse is over the title of the column to the right of it like this:
As soon as you have done this lift the mouse button up and press it down on the title of the column you are hovering over i.e. (click on the title of that column to the right)
Drag the column
Sometime the behaviour is intermittent but it is easily reproducible and may be more visible if the steps are repeated quickly.
How can this bug be solved?
Issue occurs because header text is selectable and dragable by default. Add following style for dragHandle class and th elements. You will not be able to select text in the header but on the bright side issue will be resolved.
thead tr th,.dragHandler {
user-select: none;
}
Take a look at the updated example.
I'm creating an app which allows the user to manipulate a table structure by adding and removing columns and rows, setting column widths and cell colspans, and inserting elements into table cells. While testing, I came across a scenario in which Firefox 4 and Internet Explorer 8 render the table in the way I expect it to be rendered and Google Chrome 11 doesn't. I'm using table-layout: auto and I am aware that CSS does not specify a rendering algorithm to be used in this case (http://www.w3.org/TR/CSS21/tables.html, section 17.5.2.2). Nonetheless, I'd like to have consistent views in the three mentioned browsers, if possible.
Here's a very simple scenario to illustrate the different rendering (try it in Chrome and Firefox/IE to see the difference): http://jsbin.com/ayuja4/3
Even though the table is wide enough to contain the blue div (because the first column is set to 200 px and the second column, although having a width of 100 px, must expand to 300 px to contain the green div), in Chrome the first column is widened beyond its 200 px. This results in extra, unnecessary space in the last row, which is precisely what I'm trying to avoid.
Any ideas to make this table look the same in Chrome as it does in Firefox and Internet Explorer? I don't need a pure HTML/CSS approach - manipulating the table with JavaScript is a valid option, if it solves my problem. I'm already considering using fixed table layout, but this will result in extra effort to handle elements that are wider than columns, so it's a last resort.
If you make the divs inside the table display as cells with table div {display:table-cell;} you'll get the same results. Also, the way you're going about it now is leaving a 1px gap because the 500px element doesn't get the 1px border calculated into it.
I actually took a second look at it, and if you use min-width instead of width it'll work that way too.
I have a set of Javascript functions I use with a table of input elements to enable navigation. Things like keeping track of the currently focused element, and overflowing from the end of one row to the start of the next. I have scrollbar support with a fixed first column by creating one table that is only one column wide as my fixed column and having a scrollbar for the other table.
However, I have been noticing recently, that the default behavior of the scrollbar is a bit deficient. When I navigate to the last column, Firefox leaves that column partially obscured by the scrollbar instead of scrolling far enough to see it. Likewise, once I scroll over so I can see the other part of the last column, when I move on to the next row and the nav code sets focus to a cell in the first column (the frozen table), Firefox doesn't change the scrollbar so I can see all of the first column.
Because of this, I've been looking into how to modify scrollbar positioning using javascript. My table doesn't use a vertical scrollbar, only a horizontal one. So I stumbled upon scrollLeft.
document.getElementById("meastable").scrollLeft = 1; // reset scroll to leftmost
Unfortunately this seems to only work once in a while. When I enabled Firebug and traced through my navigation code where this line is, it seems to work once in a while, but most of the time, this line will run but the tables scroll left property is unchanged and I can't see a change visually either.
I also set scrollLeft to a high number so it will be set to the maximum as is described in the documentation, and that also does not work (except once in a while).
I use the following code to set up the scrollbar with my table.
<div style="overflow:auto">
<table id="meastable" border="1">
According to Mozilla's documentation, this seems to be something that originated in IE but now works in Firefox. Does this actually not work in Firefox as the inhouse project this is for will be Firefox only.
So I'm trying to figure out what's wrong. Is scrollLeft known to not work right, or should I go back and see if I've screwed something up in my definition of the scrollbar or something along those lines?
The containing div is the element with overflow. You need to set the scrollLeft of the div, not the table.