jqGrid - how to reset grid column widths? - javascript

If users manually resize jqGrid columns, how can you reset the column width back to whatever the original values were?

I don't believe that there are any built in methods for reseting the widths, leaving the option of recording them at creation and restoring them at a later point. Unfortunately, this functionality is the same as it was 10 months ago with column width being one of the few options that cannot be changed once the grid has been created. I even tried the newest version of the grid just to be sure (3.8.2) and it does not allow you to change the column sizes.
$('#jqGrid').getColProp(colName).width; //Properly retrieves value of column width
$('#jqGrid').setColProp(colName, {width: newWidth}); //Does nothing visually
$('#jqGrid').getColProp(colName).width; //Returns newWidth, although it doesn't show it on page
I don't know if it would be worth it, but you could try Oleg's solution here of destroying the current grid and creating a new one in its place. The practicality of this solution I suppose would be dependent upon how you are getting the data and how long it would take to re-bind the data to a new grid.

Related

How Do I Make Ctrl-f Always Work in Tabulator Plus Questions on Pagination and Height?

How do you make it possible to search for any item in the table regardless of the number of rows loaded using ctrl-f?
I have a large table consisting of over 10,000 rows.
So, far I have tried using Pagination. This works regardless of how large I change the "paginationSize".
Is there a way to make the pagination controls always visible regardless of paginationSize?
Right now setting the paginationSize to certain amounts will need a scroll bar to view the pagination controls.
Also when using pagination if I include a height to the table then ctr-f cannot find everything on any page.
How does the height setting affect the number of rows loaded?
How do I figure how many rows the table will load based on the height setting?
With both of those questions in mind, how do you know how many of the loaded rows will be searchable with ctrl-f
It says in the documentation "The virtual DOM renders a number of rows above and below the visible rows to ensure a smooth scrolling experience." What determines the number of rows above and below the visible rows?
Finally is there a better way to make ctrl-f always work on the table besides using pagination?
// Creating the tabulator table
var table = new Tabulator('#themeTestCaseMetricsTable', {
height:"100%",
pagination:"local",
paginationSize:100,
layout: "fitDataFill",
cssClass: "column data",
responsiveLayout: true,
tooltips: true,
// "safe" turns off auto-escaping
columns: {{columns|safe}},
data: {{rows|safe}},
persistenceMode: "local",
persistence: {
columns: true
}
});
Appreciate any help and feedback
Ctrl+f
Tabulator uses a virtual DOM to improve render efficiency on large data sets, this means that only the visible rows actually exist, as you scroll rows are created and destroyed in realtime as they become visible. therefore you cannot search the table in that way.
The ctrl+f feature of browsers is more of a convenience feature of browser and it is bad UX to expect your users to use this to find things, if you want users to be able to search a table, you should add a search input and use the built in table Filter Functionality. you can see an example of this on the Tabulator Home Page where it lets you filter the table by the name column
That being said you can disable the virtual DOM by setting the virtualDom property to false although this will result in the table no longer scrolling and the table will take a long time to load if displaying large data sets
var table = new Tabulator("#example-table", {
virtualDom:false, //disable virtual DOM rendering
});
paginationSize
You are having this issue because you are setting both a page size and a height, if you want the table to resize to fit the height of a page of data you should not set the height. if you would like the page to take up the height of the table you should not set the page size

Change Ag-Grid infinite scroll block size?

Is there a way to change the block size when the row model used is "infinite" and a datasource is set?
I.e. when the datasource's getRows() is called, is there a way to set startRow and/or endRow? Default behaviour is to fetch 100 rows at a time which results in blank rows for me, since I only have about ~12 new data rows coming in at a time with infinite scroll. So, when getRows() is triggered, it'll try to fetch rows 100 to 200 (as an example) when there are only 45 data points in the first place. To compensate it adds a bunch of blank rows.
I've tried the following two additional grid options without success:
cacheOverflowSize: 2
infiniteInitialRowCount: 32
Fetching 100 rows at a time instead of 12 solves the issue, but I'd reeeeeally rather not do this (due to some design constraints of the product I'm working on).
Shoutout to #kamil-kubicki for their comment. cacheBlockSize was indeed what I was looking for. It didn't solve my whole problem though, so I'll outline my complete solution below.
I had ag-grid's row height set to the default 25px max. That meant that on load, when it was populating the initial data, it was coming close to rendering my entire initial data set of 32 items. On scroll, getRows() would then look for rows outside of the total data collection's bounds, so it added blank rows.
I changed how many data results are loaded on each scroll to 50. This is relatively large but it works and is performant for now, so I think I'll keep it.
For those with a similar problem:
Use cacheBlockSize in gridOptions
Make sure that your ag-grid isn't rendering anything close to your full initial data collection (e.g. if your collection is 32 items, don't render anything above like 16 items - control this by changing the height of your rows and the size of your grid)
Change how many data items are loaded in to your collection on scroll to a larger number; something that can populate data faster than the user can scroll. For me it was 50. For you it might be more, or less.

React.js FixedDataTable - Row heights are not evaluated when table is re-rendered - scrollbar is missing

I have dynamic data in my table. The amount of data in a cell may change. I have implemented a rowHeightGetter method to calculate the height of a row. When I add content to a cell and rerender my table, the content appears and the cell is larger, but if the additional content caused overflow, scrollbars do not show up. Please see the jsfiddle and click on a row. You'll see that you can no longer access the bottom row of the table until you click a second time.
https://jsfiddle.net/3cooper/ed7Ltc6o/1/
It appears that _calculateState() is not getting the actual row heights from the rowHeightGetter methods when it calls
var scrollContentHeight = this._scrollHelper.getContentHeight()
At this point it is getting the height of the rows by checking the rowHeight property on the table. I see in _calculateState() there are other calls that eventually call this._scrollHelper._updateHeightsInViewport() to properly get the height. Should this be done again. Just really started looking into this today - so I could be missing something obvious. Thanks.
Is there a better way to handle this?
Update:
Also, I notice that once a scrollbar appears so that the contents can scroll, if you click a row again, the table with shift down but the scrollbar will not adjust. Then once you start to scroll up the scroll jumps to the correct position and allows you to scroll the entire table correctly.

Compositefield inside formpanel with autoHeight

I have a formpanel with various fields. The panel has autoScroll.
CompositeField has a SuperBoxSelect based element ( ux - multiple selected tags in form etc) - and a button at the end.
Now the problem is that the compositefield does not resize to fit the increased size of its contents.
It keeps the default size it had on render.
Form is populated from selected grid rows. So data amount can change.
It will fix itself when i resize the whoel formpanel ( split bars on left/top).
I added autoResize to almost everywhere when testing, still nothing.
Is there a way to force the formpanel to reload or render when i add data to it, so it? ( since apparently the height/width change works).
this seemed to do the trick:
this.fields.tags.on('autosize', function(tags){
tags.ownerCt.doLayout();
});

Table Row SHOW / HIDE *Without* Column Width Resizing, w/ TableLayout: auto

I have table with multiple rows, showing items for sale. When the user clicks on a row, a Javascript inserts / shows a new row right beneath it with details about the item. The issue is when the description is long, it forces the column widths to readjust / resize. This shifts the columns positions and is really annoying, especially for the user. Right now, I have my table.style.tableLayout: auto. I actually prefer it this way, because the columns are adjusted to the content.
My question is: how do I dynamically "lock" the widths of the columns in my table so that when I insert / show the new row, the columns do not readjust / resize?
I've tried:
dynamically setting the table to temporarily "tableLayout: fixed"
inserting / showing my new row
changing the table back to "tableLayout: auto"
Actions 1 & 2 works in in FireFox, but not in Safari and IE (6 & 7). However, doing all three seems to prevent the columns from shifting too much.
The frustration is unbearable ... loosing lots of sleep ... please help!
Thanks.
For those looking for the code (this is done in jQuery). This also assumes the first row has the proper widths for each cell. Pretty easy changes if needed.
$('table.class_of_table_to_fix tr:first td').each(function() {
$(this).css({'width': $(this).width()+"px"});
});
I would set a percent width on each column simply as a guide. Set it just once on the TH of each column. The browser will still adjust the columns to content if necessary, but the columns will stay in place more consistently.
Next, I would never put css "white-space:nowrap" anywhere on that table. A long description should not break the table layout, it should wrap around properly on multiple lines, and be readable if you set the widths on each column to suit the type of data. Similarly I would keep the use of (non breakable spaces) to dates, times and numbers and allow the text to wrap.
Other than that, I do this at my job on a dialy basis, and there's a time when you need to stop ulling hairs asking the browser to do something it's not designed to do. Content should flow and adapt. Locking column widths to pixels is 99.99999% of the time a bad idea.
PS: If you really, reeally, REALLY need to lock columns, the only solution I'm aware of that works with CSS2 and accross all browsers is to use images. You could insert a 1px high transparent gif image in each column, and counting in the padding of the cells (TD), set a pixel width on each image (IMG), instead of on the columns (TH/TD). You could hide those in the TH for example. You can leave the images at 1 pixel wide and set percent widths on TDs, and when you open a new row, you would get each column width minus TD Padding, and set that to the corresponding IMG. I haven't tried! I just know that in many projects I've worked on, I've used small gif images to lock a minimum vertical spacing between columns, for example.
I had a similar problem when I was implementing a table with groups that could be toggled. I wanted the initial ratio between the columns to stay the same without fixing the widths of the columns. By default the browser would change the widths depending on the visibility of the table's rows, which was undesirable.
I went ahead and followed #faB's suggestion of applying percentages, but doing so using a small script that would calculate the percentages of the th elements and apply them after the initial render. This made my columns stay the same width, even with all rows hidden.
Here's the script, which uses jQuery:
(function($){
var lock_widths = function() {
var total_width = $('table').innerWidth();
var headers = $('table th');
var leftover = 100;
$.each(headers, function(ix, el) {
var header = $(el), width;
// on the last call use the leftover percentage
if (ix == headers.length - 1) {
width = leftover;
} else {
leftover -= width = header.outerWidth() / total_width * 100;
}
header.css({'width': width + '%'});
});
};
$(document).ready(lock_widths);
})(jQuery);
Tested in IE7+, Firefox and Chrome. This works for my special case because I have header columns as a reference, but it could be rewritten to measure some other columns.
You can display the details of the row beneath the clicked one in DIV and set its
style="overflow:auto";
so that details will wrap and scrollbar will be available to display entire text.
I don´t know if you´re familiar with jquery, but that´s what I would use - in combination with a separate class for the column that´s causing resizing in the new row - to:
Calculate / get the with of the column
Set the with of the afore mentioned class
Add the row
I haven´t tried it, but that should do it.
By the way, there are probably other ways to do it, I´m just more familiar with jquery (for point 1. and 2.).

Categories