ag-Grid - show buttons on row hover like in Gmail - ag-grid

In ag-Grid, I want to show action buttons when a row is hovered like in Gmail. The action buttons have to appear at the right end of grid irrespective of scroll position.
There is one approach mentioned at https://blog.ag-grid.com/build-email-client-with-ag-grid-like-gmail/. They have used a cellRenderer on the last column and showed buttons in it when "onCellMouseOver" happens. This approach would work only if the last column (which uses cellRenderer) is always in view. If that column goes out of view, action buttons will also go out of view.
I cannot use this approach since in my case, there are many columns and all columns in my grid do not fit on the screen at the same time. So, there can be any column at the right end depending on scroll position and thus we don't know which column to add cellRenderer on.
How will we achieve this?

Here is a plunk that demonstrates my solution: https://plnkr.co/edit/X4hCimLy6aL3j4eh
It turns out that this can be achieved using just CSS. Here is how I did it:
Add a column for showing action buttons. Use cellRenderer to render buttons in it. Pin it to right.
Using CSS,
absolute position the ag-pinned-right-cols-container to right
hide right header and spacer by setting their width 0
for rows which are not being hovered, hide action buttons cell in them by setting their padding & width 0
Here is complete CSS with explanation:
/* Hide right header and spacer */
.ag-pinned-right-header,
.ag-horizontal-right-spacer {
width: 0 !important;
min-width: 0 !important;
}
/* Add absolute position so that action buttons column will appear on top of other columns.
pointer-events: none to pass on mouse events to behind columns */
.ag-pinned-right-cols-container {
position: absolute !important;
right: 0;
pointer-events: none;
}
/* Reset pointer-events so that click can happen on action buttons */
.ag-pinned-right-cols-container * {
pointer-events: initial;
}
/* Hide border of right-cols-container */
.ag-pinned-right-cols-container .ag-cell {
border: none !important;
}
/* Show action buttons only for the row that is being hovered.
For rows which are not being hovered, hide them by setting their width and padding to 0. */
.ag-pinned-right-cols-container .ag-row:not(.ag-row-hover),
.ag-pinned-right-cols-container .ag-row:not(.ag-row-hover) .ag-cell {
width: 0 !important;
padding: 0 !important;
}
Ag-grid's default row hover and row selected colour has some transparency. Since our action buttons column is placed absolutely over other columns, its background looks darker because of the way those transparent colours blend.
So, it is better to use background colours with no transparency in this method like this:
.ag-theme-alpine {
--ag-row-hover-color: hsl(207, 90%, 94%);
--ag-selected-row-background-color: hsl(207, 87%, 86%);
}
Overall,
Pros:-
It's a drop-in solution. You can just drop above CSS in your code and you will get the button on hover functionality.
This approach is framework agnostic. I have tested it on React and Angular. (For Angular, you will have to use ng-deep to workaround style encapsulation)
Cons:-
This won't work if you already have one or more columns pinned to the right
A future version of ag-grid might use different class names. So this CSS might need to be updated while upgrading ag-grid

Related

Is there way to set detailRowHeight prop to 100% in ag-grid?

Recently started working on a master detail structure angular ag-grid. The structure has two levels of master-detail nesting. I need to fix the heights of inner - 2 grids such that they occupy all available real estate on the screen. Currently, ag-grid defaults it to 300 px and a lot of whitespace or unused space appears on a 1920x1200 screen resolution monitor. I also need to have fixed headers for all grids.
Any ideas or pointers would be appreciated...
Update: Referring to a forked version of plunker example from ag-grid here - https://next.plnkr.co/edit/yUzo4EqONEmgCmIw This is simple and basic set up for master-detail grid.
Note that: I haven't set any detail row height and have setup just one record to show up in the grid to test for the issue.
If you run the plunker code and view the result in separate window, notice that the inner / child grid doesn't occupy all the space available below it. In other words, it doesn't take as much as space/height available from parent container (master's detail row). The default 300px master detailRowHeight is making height fixed for inner grid. Also, from documentation, detailRowHeight prop doesn't seem to take something similar as 100% or 100vh and only takes fixed pixels number. Added a picture of the example below and the height / unused space I referred
We have different resolutions that users use to view data in grid and the heights of inner grids need to auto-adjust taking max. available space to show most information in the grids.
You could try something like this, I pulled it from the documentation:
In your component.ts file add this method. If it's a detail row it will apply different calculations than the other rows.
public rowHeight(params) {
if (params.node && params.node.detail) {
var offset = 80;
var allDetailRowHeight = params.data.callRecords.length * 28;
return allDetailRowHeight + offset;
} else {
// otherwise return fixed master row height
return 25;
}
};
In your template add the following: [getRowHeight]="rowHeight"
<ag-grid-angular
#agGrid
style="width: 100%; height: 100%;"
id="myGrid"
class="ag-theme-balham"
[columnDefs]="columnDefs"
[masterDetail]="true"
[detailCellRendererParams]="detailCellRendererParams"
[getRowHeight]="rowHeight"
[rowData]="rowData"
(gridReady)="onGridReady($event)"
></ag-grid-angular>
Hopefully this will get you moving forward. Good Luck!
https://www.ag-grid.com/javascript-grid-master-detail/#detail-row-height
So I don't have a great, full solution for you but as a starting point I would use CSS to override the styles ag-grid is setting - I don't think detailRowHeight is going to help.
Here's my plunk getting close to what you want with some simple CSS I put in index.html. You can use !important to override ag-grid styles, or you could use javascript to set the CSS after ag-grid does. I prefer !important in this case and don't have to worry about timing.
https://next.plnkr.co/edit/mmXBBJE5Wa1JrX7v
The problem I wasn't going to get into is getting it to dynamically fill up available space, depending on the row selected, scroll position, etc. I can't think of any simple way to achieve that - I do this type of thing in grid often and end up writing javascript to calculate the available space, and then set the CSS in javascript.
In ag-grid you have the possibility to set auto height for details.
Set grid property detailRowAutoHeight=true to have the detail grid to dynamically change it's height to fit it's rows.
const gridOptions = {
// dynamically set row height for all detail grids
detailRowAutoHeight: true,
// other grid options ...
}
However if you are providing your own detail component...
detailCellRenderer: 'MyOwnDetailsComponent',
then, it might not work and you will still need to provide an grid options height detail content through...
detailRowHeight: 560,
Please see the ag-grid documentation here

ExtJS Swap panels as items list

I need to swap panels in a list. I've tried to reorder rows in a grid but I need to put a little more informations in the item so a panel will be nicely to show.
Must be the classic drag icon (four arrows) like here http://examples1.ext.net/#/DragDrop/Panel/Swap_Dropable_Panel/
This example is very close that I want. I need only vertical swap like this one http://tof2k.com/ext/sortable/ ( this could be just what I need but seems it don't use ExtJS themes and I don't know if I can put more information inside the items - and it is a little ugly too).
Some ideas?
Perhaps using a grid with a templatecolumn and drag and drop resolve your issue.
FIDDLE: https://fiddle.sencha.com/#fiddle/1i7l
Also, you can use CSS to change row.
.customRow .x-grid-cell-inner {
margin: 5px 5px 5px 5px;
background-color: yellow;
}
Remove de comment
//cls: 'customRow'
on fiddle (line 58).

Twitter Bootstrap - Dropdown height too small

I am using bootstrap in an Ruby on Rails app. I use Firefox. I find that the height of the dropdown field (select tag) is too small.However the height of the text fields are appropriate. I had too add the below code to application.css to fix it:
select {
height: 38px !important;
}
Now dropdown shows its content properly though its overall height (box) is a bit bigger that text fields. Is there a neater way to fix the issue?
I found it more appropriate to remove styling from application.scss and modify the app/assets/stylesheets/custom.css.scss instead. custom.css.scss is generated by Bootstrap. The padding for all FORM elements was set to 10px in that file. I set padding for SELECT element to 2px and left the rest intact.

Change GWT SubMenu Popup Location

In menubar, normally submenu gets displayed on the right hand side. I want to change to Left hand side. Can anyone please let me know, how can I do it ?
Popup location of Sub menu is defined by CSS elements at rendering based on position of menu items.
Looking Via Firebug On Main Menu It produced:
element.style {
clip: rect(auto, auto, auto, auto);
left: 337px; // Change this to left:35px;
overflow: visible;
position: absolute;
top: 319px;
visibility: visible;
}
// This is main CSS for popup
.gwt-MenuBarPopup{
}
So, Give it a try by using setStyleName("css goes here") from code
I again advise you to override the default styles GWT:) I used this method on my project when I had to change some standard view of GWT-elements.
I was able to implement a solution by changing the css as well. Perhaps this isn't the most elegant way, but it works. Using a little help from GwtQuery's closest() method, here is a short example.
menuBar.addAttachHandler(new AttachEvent.Handler() {
#Override
public void onAttachOrDetach(AttachEvent event) {
if(event.isAttached()){
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
#Override
public void execute() {
Element e = $(menuBar).closest(".gwt-MenuBarPopup").get(0);
e.getStyle().setLeft(parentMenuBar.getAbsoluteLeft()-menuBar.getOffsetWidth() , Unit.PX);
}
});
}
}
});
So the idea being when the child sub menu is attached, you want to change the css. I use a deferred command so that it will change the css after GWT's default MenuBar implementation sets it.
This line, "$(menuBar).closest(".gwt-MenuBarPopup").get(0);" will search up the DOM tree until it finds the element with the class .gwt-MenuBarPopup, which is the one you want to change.
My solution is somewhat of a hybrid of those posted so far here, but I think it is cleaner/simpler than any of them.
Each vertical subMenu is itself a MenuBar, added as an item to the top-level
MenuBar. For whichever subMenu you want to drop to the left instead of the right, add a style class name to it using .addStyleName("myLeftDropDownStyleName") on that MenuBar Widget.
Define the selector rule for that style like this (these are the minimum attributes that were necessary for me to get the left dropping):
.myLeftDropDownStyleName{
position: absolute;
right: 0px;
}
Absolute positions relative to the first parent element with a position other than static; for my case at least, that parent position seemed to be horizontal place where the dropdown otherwise has its left edge without this solution. I wouldn't be suprised if Relative position might work better in some other people's cases.
The Right offset of 0px tells the absolute position's right to be at that horizontal place I mentioned above. And of course the pixel size can be > 0 to push further to the left by that much, or even < 0 to pull it back to the right by that much.
This works perfectly for me, is simple & clean, and does not force all of your MenuBars to have this style (as I think would be the case if you overrode one of the GWT MenuBar styles themself).

gwt 2.4 DataGrid - auto set column width?

I have a problem with DataGrid in gwt 2.4. I made table with CellTable, and everything worked fine. But I needed fixed header, and then just replaced CellTable with DataGrid. I had problem with .css file, but than has been resolved.
Now, the problem is that every column have fixed width, and table put every row just in visible part of screen.
This is new and old screen shots, to make things more clear :)
http://img832.imageshack.us/img832/5026/oldscreenshot.jpg
http://img834.imageshack.us/img834/1489/newscreenshot.jpg
Can someone help to make old looking, but with fixed header.
You can set a fixed width for each column of the data grid:
dataGrid.setColumnWidth(sampleColumn, 40, Unit.PX);
and expand the total data grid width:
dataGrid.setWidth("100%"); // choose the most useful in your app
dataGrid.setWidth("1400px");
I'm not sure what the right answer is, but I don't think the previous responders understood the question.
Basically, you want dataGrid to use "table-layout: auto" instead of "fixed". This is what cellTable does. Table columns are auto-sized based on content.
This is easy for the content table, but to get the header-freeze, dataGrid is using a separate div/table for the header. Therefore, the header table's columns need to be explicitly sized based on the data table. They also need to be resized anytime the table changes (browser resizes, etc.). I plan on adding resizeable cols on a dataGrid, so I'll be hitting this same challenge soon I expect and will update when I have something more explicit if anyone is still tracking this thread...
need to wrap your content in your td with an inner div. and make sure the overflow-x is set to hidden.
table {
overflow: hidden;
white-space: nowrap;
table-layout: fixed;
}
td div{
overflow-x:hidden;
}