Resize last column in jqgrid - jqgrid

There seems to be a bug in jqgrid, where one can not resize the last column.
This seems to be a quite old issue raised in 2009. I had a look and the latest jqGrid sample seems to have this issue...
What I found however was that last column can be dragged to resize the grid itself.
See here Go to section what is new in 3.6.
Any pointers if this is already fixed.

Seems I found a solution.
Resizing of the last column can be done only within the area of the header wrapper (div.ui-jqgrid-hbox). In the outer space resizing process losing focus.
Because of existing some padding-right area with default 20 pixels, increasing the size can be done in this small part only.
In addition, we need to temporarily cancel table wrapper influence, because he also cause to stop resizing process.
Here is my solution. I assume, that your table wrapper id is gbox_DataTable_u:
1:
CSS: define new wide padding-right area:
.ui-jqgrid .ui-jqgrid-hbox {float: left; padding-right: 10000px;}
2:
Append 2 events to your grid:
resizeStart:function(event, index){ $('#gbox_DataTable_u').width($('#gbox_DataTable_u').outerWidth() + 10000);}
resizeStop: function(width, index) {$('#gbox_DataTable_u').width($('#DataTable_u').outerWidth());}
Example of working table: http://www.design.atplogic.co.il/aman/philips/users.htm#

I found that the best way is to add an empty unresizable column in the end of the grid.
I'm just doing it manually, by extending the colModel right before the execution of jqgrid constructor. Only problem being - I wasn't able to make it not draggable so far.
Here's an example:
colModel.push({align: "left", editable: false, hidden: false, index: "ghostCol", label: " ", name: "ghostCol", resizable: false, sortable: false, type: "text", width: 50});
Hope this helps.

It is resizing fine for me as well, although you have to resize from the right on the "RTL Support" example, which seems to make sense.
Also be aware that if you are using Chrome, there is a jqGrid bug that causes horizontal scroll bars to appear - see jqgrid-does-not-render-correctly-in-chrome-chrome-frame. This issue has since been resolved, but the demo page has not been updated yet. And it certainly gives the appearance of the last column's resizing not working because you have to scroll all the way over to the right before you can resize the last column.

I have tried to resize the last column with resizeStop, i do some trick like the other guy said. hope it help.
resizeStop(width, index) { var amGrid = $("#jsonmap"), colModel =
$("#jsonmap").jqGrid('getGridParam','colModel'); var oW =
$oldWidths[index]; var cW = colModel[index+1].width+
downCalSize(oW,width); $oldWidths[index+1] = cW; $oldWidths[index] =
width;
$('.ui-jqgrid-labels > th:eq('+(index+1)+')').css('width',cW);
$('#jsonmap .jqgfirstrow > td:eq('+(index+1)+')').css('width',cW);
var w = amGrid.jqGrid('getGridParam', 'width');
$('.ui-jqgrid-htable').css("width",w);
$('.ui-jqgrid-btable').css("width",w); }
i still looking for a common way, can do on more tables in one page and don't affect to each other.

After 2 days of struggling...I finally found a way to work around.
It seems that jqGrid calculates the resizing object in the dragMove event, where it uses passed event object to get the position of mouse and calculates the new width of resizing column. However when dragging exceeds the grid's boundry, the dragMove event stop shooting...
So my work around is simply modifying jqGrid to calculates resizing object again in the dragEnd event. Here's the modified code
first find the dragEnd event.
...
dragEnd: function(e) { // add a new input parameter
this.hDiv.style.cursor = "default";
if(this.resizing) {
this.dragMove(e); // call dragMove event to calculate resize object
...
then find the mouseup event where dragEvent is triggerd...
...
$(document).mouseup(function (e) { // get the event object
if(grid.resizing) { grid.dragEnd(e); return false;}// pass event to dragEnv
return true;
});
...
Then columns should be able to resize to wherever mouse points.
Hope this would help.

Related

Plotly.js, show tooltips outside of chart container

I need to implement a plotly.js chart on a page with a very restricted width. As a result, a tooltip is partially cut. Is it possible to cause tooltip not to be limited by plotly.js container size?
My code example at codepen: https://codepen.io/anatoly314/pen/gOavXzZ?editors=1111
//my single trace defined as following but it's better to see example at codepen
const yValue1 = [1000];
const trace1 = {
x: [1],
y: yValue1,
name: `Model 1`,
text: yValue1.map(value => Math.abs(value)),
type: 'bar',
textposition: 'outside'
};
It is, by design, not possible for any part of the chart to overflow its container.
I would say it is wrong to say that by design this is not possible! It is a bit hacky, but when you add the following lines, it shows the label outside of svg:
svg.main-svg,svg.main-svg *
{
overflow:visible !important;
}
The answer given by rokdd works. However the css selector should be more specific, otherwise it's natural that you will introduce subtle bugs (particularly if you need to scroll the content where the plotly chart is contained).
If we look at the DOM tree constructed by Plotly, we find that the tooltips are created inside the <g class="hoverlayer"></g> element (which is a direct child of one of the three <svg class="main-svg"></svg>). So that parent (that svg.main-svg element) is only one that needs to affected.
The ideal css selector in this case would be the :has selector. However it's still not supported (as of 2022): https://css-tricks.com/the-css-has-selector/
So the next simplest thing is to use a little bit of javascript right after we call Plotly.newPlot:
// get the correct svg element
var mainSvgEl = document.querySelector('#positive g.hoverlayer').parentElement;
mainSvgEl.style['overflow'] = 'visible';
Or in a more generic way (works for any chart):
Array.from(document.querySelectorAll('g.hoverlayer')).forEach(hoverEl => {
let mainSvgEl = hoverEl.parentElement;
mainSvgEl.style['overflow'] = 'visible';
});

How to set kendo UI grid width

I am facing a problem with the Kendo Grid width. I want the grid to stretch to fit the content of the grid. This grid which I am working on is created dynamically, so at times it may have just 2 columns and at times it may have max 5 columns. I don't want the grid to expand and take the whole page for showing just two columns.
To get this working I added the following css
.k-grid table{
display: inline;
}
The problem is that when this style is applied, it completely messes up the column header and column alignment. Does anyone know how to fix this?
Actually this is really simple. But I wasted lot of time cause I did not get the correct source. You just need to implement following things.
Make the grid sortable: false
and use this CSS
#gridId table {
width: auto;
}
But with this you loose the scrolling feature. But you can wrap your kendo grid in another container and implement your own scrolling.
var grid = $("#kendoGridName");
grid.width(400);
Rather than trying to apply some css you could use some jQuery to perform this task. I do something similar in terms of height. So maybe something like this would work for you (I have modified this to do height and width).
function resizeGrid(size) {
if (size === null || size === undefined) {
size = 0.6;
}
var windowHeight = $(window).height();
var windowWidth = $(window).width();
windowHeight = windowHeight * size;
windowWidth = windowWidth * size;
$(".k-grid-content").height(windowHeight)
$(".k-grid).width(windowWidth);
}
so all this function does is scale the grid based on the current window size so for example if you want the grid to take up all the available space ie max height and width you would call resizeGrid(1) if you wanted it smaller say to take 50% of the screen size then you would use reszieGrid(0.5) if no value is used then the function just goes with a default of 60% of the available width/height.
so you could call this after your initialization of the grid and then scale the grid to an appropriate size.
by targeting the kendo css classes it makes this function easier to reuse.
if you need more info let me know.

Is it possible to set the alignment of kendo datepicker's dropdown calendar in kendo grid with respect to the textbox

When the datatype is Date, the kendo grid uses a kendo datepicker with dropdown calendar for the column.
The datepicker's dropdown calendar usually aligns itself flush with the left edge of the input box. If there isn't room for that, it is moved to the left, but not quite enough. This presents a problem when the rightmost column in the grid is a Date, and the grid is occupying 100% of the width available on the screen: the Saturday column in the dropdown calendar gets "cut off". See pic attached.
Is it possible to tell the calendar dropdown (for a particular column) to align itself flush with the right edge of the text input?
I know that bug. Your datepicker animation container is hidden under right scrollbar. If you set body overflow to hidden, you will not have a scrollbars and calendar will fit and touch right border of screen, like in this example: http://dojo.telerik.com/UCOhA
However if you can't turn off the body scrollbars you need to set calendar position manually dirty way like this:
$("#piker").kendoDatePicker({
open: function(e) {
//setTimeout to let kendo make k-animation-container element at first open
setTimeout(function(){
var animationContainer = $("#" + e.sender.element.attr("id") + "_dateview").parent();
var left = e.sender.element.offset().left + e.sender.element.closest('.k-datepicker').width() - animationContainer.width();
animationContainer.css('left', left);
});
},
//turnoff the animation to avoid strange visual effects
animation: {
open: {
duration: 0
}
}
});
Running example: http://dojo.telerik.com/Imiqa/2

Slickgrid: Final column autosize to use all remaining space

I'm using SlickGrid and struggling to find an elegant solution to the following:
All columns must have a specific initial width when first rendered but be resizable afterwards
The final column should auto fill the remaining column space when the window is resized
I've seen:
Make one column fill remaining space in SlickGrid without messing up explicit width columns
resizing of grid when resizing browser window
How do I autosize the column in SlickGrid?
But these don't seem to quite do what I need.
If I use the forceFitColumns option, then all columns will autosize (unless I put a maxsize on them).
Using resizeCanvas on window.resize works well - but it still only works if forceFitColumns is true.
If I set minWidth=maxWidth - then I can't resize the column.
Any suggestions?
I'm not sure it would correct all your problem but in my case I do use the forceFitColumns and then depending how I want my column to react in size I will use a combination of minWidth and width, and in some cases the ones that will never exceed a certain width, I would then use a maxWidth as well. Now the problem you have is when setting the minWidth to be the same with as maxWidth this of course will make it unresizable, well think about it you set a minimum and a maximum, SlickGrid is respecting it by now being able to size it afterwards. I also have my grid which takes 95% width of my screen so I have a little padding on the side and with it I use a auto-resize using jQuery.
Here is my code:
// HTML Grid Container
<div id="myGridContainer" style="width:95%;">
<div class="grid-header" style="width:100%">
<label>ECO: Log / Slickgrid</label>
<span style="float:right" class="ui-icon ui-icon-search" title="Toggle search panel" onclick="toggleFilterRow1()"></span>
</div>
<div id="myGrid" style="width:100%;height:600px;"></div>
<div id="myPager"></div>
</div>
// My SlickGrid Options
var options = {
enableCellNavigation: true,
forceFitColumns: true
};
// The browser auto-resize
$(window).resize(function () {
$("#myGrid").width($("myGridContainer").width());
$(".slick-viewport").width($("#myGrid").width());
grid.resizeCanvas();
});
EDIT
I also was annoyed by the fact that using all of these together is blocking you from resizing the width of the column. I came up with a different solution, much later after, which makes the fields to expand (take available width) and does not block you afterwards on resizing the width. So this new solution I believe is giving you exactly what you are looking for... First of all remove the maxWidth property and only use minWidth and width, actually you could probably use only the width if you wanted. Now I had to unfortunately, modify 1 of the core file slick.grid.js with the following code:
//-- slick.grid.js --//
// on line 69 insert this code
autoExpandColumns: false,
// on line 1614 PREVIOUS CODE
if (options.forceFitColumns) {
autosizeColumns();
}
// on line 1614 change to this NEW CODE
if (options.forceFitColumns || options.autoExpandColumns) {
autosizeColumns();
}
then going back to my grid definition, I replace my previous options with this:
// My NEW SlickGrid Options
var options = {
enableCellNavigation: true,
forceFitColumns: false, // make sure the force fit is false
autoExpandColumns: true // <-- our new property is now usable
};
with this new change it has some functionality of the force fit (expanding) but does not restrict you on resizing your columns width afterwards like the force fit does. I also tested it with the columnPicker, if you hide a column it's resizing the others accordingly. I also modified the file slick.columnpicker.js to include a checkbox for that property but that is totally optional...I can add the code for that too if any of you want it as well. Voila!!! :)
EDIT #2
I realized much later that there's no need to modify the core file, we can simply call grid.autosizeColumns() after the grid creation. Like this
var options = { forceFitColumns: false };
grid = new Slick.Grid("#myGrid", data, columns, options);
// will take available space only on first load
grid.autosizeColumns();
This will automatically resize the columns to fit the screen on first load but will not give you the restriction of the forceFitcolumns flag.
I know it's kind late for this reply.
But i've managed to do that without having to change things at slick.grid.js or set min/maxWidth at columns array.
Instead what i did was to iterate through the columns array adding the values of "width" field of each column and then i've did a simple math count to set the last column width as innerWidth - totalColumsWidth + lastColumnWidth.
Code:
function lastColumnWidth(columns)
{
var widthSum = 0;
angular.forEach(columns, function(col) {
if(col.width) { widthSum = col.width + widthSum; }
});
if(window.innerWidth > widthSum) {
columns[columns.length-1].width = columns[columns.length-1].width + (window.innerWidth - widthSum);
}
return columns;
}

FabricJS Canvas, Scrolling parent container moves child hit area

I am using FabricJS to create an application. I am finding that scrolling a parent div/container offsets the selectable area of an object to the right in direct relation to amount scrolled.
So, if I have a canvas that is 1200x600 and a container div that is 600x600 and I add a rect to that canvas at 400, 120; when I scroll 200px, I can't click on the rect to select it. Rather, I have to move my mouse to 600, 120 (empty space) to get the cross bar and select the rect.
Not sure if this is known, or has a work around - but I would appreciate any help possible.
You'll have to modify FabricJs code to make it work.
The problem is in the getPointer function, if you search for it in all.js you'll notice the comment "this method needs fixing" from kangax.
A workaround can be substituting this function with
function getPointer(event) {
// TODO (kangax): this method needs fixing
return { x: pointerX(event) + document.getElementById("container").scrollLeft, y: pointerY(event) + document.getElementById("container").scrollTop };
}
where "container" is the wrapper div of you canvas. It's not nice, since you have to put the exact id, but it works.
Hope this helps.

Resources