Slickgrid: Possible to scroll horizontally on grid while dragging column? - javascript

I'm working with Slickgrid to display a large data set which may be used with anywhere from a few to 50 columns. I need the ability for users to reorder the columns as they wish, which I am currently able to do but with some inconvenience. If I happen to be grabbing the very last column and moving it to the front of a grid with several horizontal window widths of columns, I have to drag/drop and manually scroll left before I get the column positioned where I want it.
Does anyone know if there's a way to force the grid to automatically scroll horizontally based on where I'm trying to drag a column (i.e. when I attempt to drag the column outside the current grid viewport)?

Find mouse pointer position where you want to scroll and apply scrolling by this method...
$('#myGrid').mousemove(function(e){ //#myGrid is id of div of grid container
var parentOffset = $(this).offset();
diffX = ( ( parentOffset.left + $('#myGrid').width() ) - e.pageX);
if (diffX < 59 && diffX > 17){ //change the minimum and maximum area where you want to scroll. mine requirement is 59 and 17. You can find your custom position by some alerting or console.log
$('.slick-viewport ').scrollLeft($('.slick-viewport ').scrollLeft() + 5);
}
});

I ended up solving this problem by creating a sortable list of the grid's column names outside of the grid. When the order of the column names changes, the columns displayed on the grid resets based on the new order by calling the function grid.setColumns().

Related

Account for dynamic top element in React Virtualized `Grid`

I have a collection of photos that uses React Virtualized's Grid element.
We've designed an indicator to appear during photo uploads. This hides and shows dynamically and is rendered via the cellRangeRenderer per these docs.
The tricky part has been getting the rest of the Grid items to respect the additional height added by this new element. The approach that's currently in place is to add the height of that element to the style.top of each element rendered in cellRenderer.
const adjustedTopOffset = style.top + heightOfTopElement;
That above calculation is done for each element. This correctly places all elements at the appropriate offsets. However, the height of the Grid does not adjust for the recalculation of the top offsets.
The consequence is that the bottom of the Grid is cut off by the adjusted top amount.
How do I correctly account for adjusted top offsets? Calling recomputeGridSize doesn't seem to do it.
Is adjusting the top offset in cellRenderer the correct approach for accounting for an additional top element? I'll clarify that this isn't a fixed element but rather one that needs to scroll with the Grid like the other elements.
Given that your cell heights are fixed, you should be able to overrides the default height style using the containerStyle prop, like so:
let containerStyle;
if (isTopElementVisible) {
containerStyle = {
height: rowHeight * rowCount + heightOfTopElement,
maxHeight: rowHeight * rowCount + heightOfTopElement,
};
}

Is there way to render <table> horizontally when the list exceeds certain length?

I created a visualization with d3
http://jbk1109.github.io/tennisMapWithPlayersListOnHover.html
When mouse hovers over the histogram, a list appears underneath. There are a couple cases when the list becomes too long and I would like the table to grow horizontally beyond certain length.
Is there an optimal way to do this other than checking the length of list and appending a new table element?
Nice job Brian! I would try to get viewport height with jQuery, and compare it witch table height, something like:
if(table_height > viewport_height) {
// change table css style to 2 column table
}

jqGrid. First single click on column span-resizer sets column width to default calculated

I have an issue when I'm clicking first time to column's span-resizer --> column width returns to some default calculated value. The same thing appears when I'm trying to resize it: it resizes not from current width, but from that calculated!
This shows my table after page load: columns' width are good.
screenshot after page load
But after clicking to resize State column --> it's just returns to some value (in that case
screenshot after click on column resize
How can I fix this issue?
P.S. Sorry, I have no enough rep to add images.
jqGrid hold column header and the column data in separate dives. So jqGrid have to hold scroll position of the header div (hDiv) the same as the scroll position of the div with the grid body (bDiv). I think that jqGrid have a bug in your situation. As the workaround you can use resizeStop where one set the scroll position of hDiv to the current scroll position of bDiv:
resizeStop: function () {
this.grid.hDiv.scrollLeft = this.grid.bDiv.scrollLeft;
}
I think that it should solve the problem.

Telerik RadGrid scrollbar is offsetting the columns

I have a page with anywhere between 1 and 6 dynamically built iframes containing RadGrids in two columns on the page. I've managed to get a column by the name Document Number to line up in all of them, however if one of them contains more data then the space allowed it will scroll. This is expected and correct.
My issue is when the scrollbar does show it pushes all my columns left just a smidge in that grid, and now it's out of sync with the other grids. I've added a small column which I can dynamically display to push the other grids' columns to match, I just need to be able to detect/determine if a scroll bar is actually being displayed.
I found an old telerik post that suggests I use the scroll height vs the overflow height and if scroll height is larger then we know there's a scroll bar being displayed. My attempts to use the supplied javascript have shown me that the post is outdated and that GridDataDiv no longer exists.
Is there a new/updated way to detect the presence of a scrollbar? Alternatively, is there a better way to have my document number columns even regardless of scrollbar?
Compare the grid's client width and the scroll area width of the grid data:
var grid = document.getElementById("RadGrid1"),
scrollArea = document.getElementById("RadGrid1_GridData");
// ex. 171 (note no units included)
alert("grid.clientHeight: " + grid.clientHeight);
// ex. 300px (note the "px" units are included)
alert("scrollArea.style.height: " + scrollArea.style.height);
// Is the verticle scroll bar visible?
var vertIsVis = scrollArea.style.height.replace("px", "") > grid.clientHeight;

Scroll a div when hovering over a clipped item

This is a tricky problem to describe...I have a fixed height <div> on my page with a bunch of content items inside. Each item is a square <div>, floated left, so they fill in the area left to right and top to bottom. If there are too many items to fit in the view, then the content area will scroll (overflow-y: auto).
Forgive the ASCII art:
---------------------
| [ 1 ] [ 2 ] [ 3 ] |
| [ 4 ] [ 5 ] [ 6 ] |
| [ 7 ] [ 8 ] [ 9 ] |
---------------------
The thing is, the items inside don't fit perfectly in the area without the bottom row getting clipped. So what I want to do is somehow automatically scroll the view down when the user hovers over an item that's clipped off the bottom of the content area.
I can't figure out how I would go about determining whether a particular item is clipped or not.
Is this totally wacky? Or is there a logical method for doing this?
This is a very basic example.
http://jsfiddle.net/8Kb7N/
Essentially, each of your square divs would have an associate anchor inside with a unique name.
You want to set a hover event for each item that sets the window.location to the name of its anchor. This should let it navigate inside the area.
After first experimenting with #Geuis' method, I realized I was solving the wrong problem, because the last row of items isn't necessarily the same row that's getting clipped.
For example, say I have 12 items in a 3x4 grid: 3 items per row, 4 rows in total. Then say my container is only tall enough to show the first two rows and the top half of the third row. The last row is the fourth row, but the row that's getting clipped is the third row, assuming I'm scrolled to the top. Or, what if I scroll to the bottom of the container? Now the second row is getting clipped, and off the top rather than the bottom.
So I realized that rather than looking at the rows, I need to look at the particular item that's being hovered over and determine if that single item is being shown in full or not. If it is, do nothing; if it's not, scroll up or down depending on which end of the item is clipped.
Here's what I came up with. On hover:
var containerHeight = $container.height(),
itemHeight = $(this).height(),
itemOffset = Math.floor($(this).position().top),
itemVisible = containerHeight - itemOffset,
itemClip = itemHeight - itemVisible;
if (itemClip > 0){
$container.scrollTo('+=' + itemClip, 600);
} else if (itemOffset < 0){
$container.scrollTo('-=' + Math.abs(itemOffset), 600);
}
($container is defined elsewhere in my script as the containing div)
Line by line:
Get the height of the container that holds all the items
Get the height of the item being hovered
Get the distance from the top of the container to the top of the hovered item
Subtract the distance (line 3) from the height of the container (line 1)
Take the difference from line 4 and subtract it from the height of the item being hovered (line 2)
Now, this tells you two things:
If the result of line 3 is negative, the item is being clipped by that many pixels past the top of the container
If the result of line 5 is positive, the item is being clipped by that many pixels past the bottom of the container
Knowing this, you can then scroll the container in the correct direction and by the correct distance to reveal the whole item.
The actual scrolling itself requires the jQuery ScrollTo plugin in order to scroll up or down x number of pixels from the current scroll position (not from the top of the container, which is what jQuery's built-in .scrollTop() function does).
(ScrollTo does not take a negative number as a value, so in order to scroll up, you need to get the absolute value of itemOffset - hence Math.abs(itemOffset)).

Categories

Resources