Set max height on dijit.Menu - javascript

I have one popup subMenu using dijit.menu that can be very long due to dynamic input. I want to set a max Height and overflow-y:auto to dijit.menu. So it will has a scroll bar when becoming too long.
var subMenu = new dijit.Menu({ parentMenu: this.mainMenu});
//....add a lots of submenu items here
this.mainMenu.addChild(new dijit.PopupMenuItem({label: "some label", popup: subMenu}));
The problem is the top level of dijit.menu is a <table>, and max-height won't work on it. Also, unlike dijit.form.select, the dijit.menu does not take maxHeight as a parameter.
I noticed there is a ticket describing this problem on dojo long time ago and marked as fixed. However, I still have no idea how to set maxheight on the menu.(The fix seems no longer exsits too)
Ticket #9086 (Allow CSS height on dijit.Menu)
Any hint on how I might able to do this would be apperciated.

As you noted, there is an issue with the way that Dojo handles the DOM creation of the dijit.Menu widget. The problem isn't that maxHeight isn't accepted as a parameter (as you can just pass it into the widget's style property as part of an Object or String), rather how the styling is applied.
You mentioned that the "top level" of a Menu widget is the <table> node. However, this is not the whole truth. That node is what Dojo presents to the client (you) as the "top level" domNode, but the Menu actually wrapped in another <div> that you cannot access directly from the widget, and it is this node that your styles should be applied to.
This <div> has the attribute class="dijitPopup dijitMenuPopup", but I doubt you want to set your styles to Dijit popups/menus globally. To avoid this, you can set the baseClass property on your widget as follows:
new Menu({
baseClass: "myCustomMenu",
targetNodeIds: ["myTarget"]
});
This will change that top level <div> attribute to read class="dijitPopup myCustomMenuPopup". This gives you a class that you can modify with the CSS styles you need to accomplish your goal:
.myCustomMenuPopup {
max-height: 200px;
overflow-y: auto;
overflow-x: hidden;
}
Here is a working example in jsfiddle.

Related

DHTMLX Scheduler timeline view - labels with longer text don't appear in tree mode

I have a question to which I can't find the answer for some time.
It's about DHTMLX scheduler timeline view in tree mode. The problem is that labels with longer text than the available space for the folder elements of the tree(these which have children) disappear, they are not shown in the first column of the timeline view. I can't understand why is this happening. Is there some kind of a setting on the scheduler, which I'm missing. It is important to note that styling of the scheduler has to be with the dhtmlxscheduler_material.css file or in other words material design.
Here is an image of the scheduler with the problem shown
I also provide a code sample which simulates the problem.
https://docs.dhtmlx.com/scheduler/snippet/9445edbf
This behavior can be fixed by the following style:
.dhx_scell_expand{
position:absolute!important;
}
Also in material skin, it requires some additional styling to make it look better, which may look like this fragment:
.dhx_scell_expand{
position:absolute!important;
}
.dhx_scell_name{
margin-left: 26px;
text-align: left !important;
}
Of cause, you can experiment with it to make appropriate for your project.
Also, in a case with long section names, you can change the default width of the section names column through the "dx" parameter:
scheduler.createTimelineView({
...
dx: 300, //200 by default
...
});
Here is an example with additional styling, and the resized names section :
http://snippet.dhtmlx.com/5/a3da39a40
Also, you can separate the section name using the </br> tag, change the height of the section through the "folder_dy" property, and align multiline text through CSS(line-height/ margin), like in the following example:
http://snippet.dhtmlx.com/5/87845739f

Rendering a Kendo Menu from an Ext JS Panel

I'm combining ExtJS and Kendo UI - I realise this I'm off the reservation here ;)
I'm rendering a Kendo Menu onto an Ext JS (4.2.1) generated Ext.form.Panel
Fiddle: http://jsfiddle.net/blackfrancis75/5e6Lgtaj/1/
The problem is that the drop-down items (on hover) get drawn only within the bounds of the Ext JS Panel. Is there a way to have the drop down items show 'in front' of everything (I tried changing some of the classes z-order)?
This is not z-index issue. It is parent overflow: hidden issue. If you have relatve container with overflow: hidden CSS property it will always work like that. Simple solution for kendo menu right now is to set all menu relative parents overflow to visible:
.x-panel,
.x-panel-body {
overflow: visible;
}
Like here:
http://jsfiddle.net/5e6Lgtaj/2/
But you must be beware that if you want to use it as scrollbars in them or actually hide overflow it will be a problem.
Other option would be append menu to body element, but you will face more problem then: like loose styling (cause it is moved from initial container with important classes), javascript functions to keep it in correct position and it will be more problems then it is worth.
This is first step how it could looks like:
http://jsfiddle.net/5e6Lgtaj/3/

Remove Bootstrap Collapse' inline height property set by JS

When using the Bootstrap collapse plugin, I notice in the Elements panel that there is an inline height property of the element animated. I would like to remove this (from the actual core Collapse.js / Transition.js plugin) as I'm using pure CSS3 animations/transitions.
the reason is two fold : a/ I don't need it, b/ it's conflicting with my own animation, the element firstly expands to the height calculated by the script, and then after a 15ms pause folds down to height: 100% (as I wish)
I emphasize: I don't want to override it, I want to remove it completely (please no answers with overriding)
Height is being set by anything that looks like:
this.$element[dimension](0)...
You'll need to hunt those down in both .hide and .show plugin methods.

How to use ScrollPanel with relative size

I'm trying to use a ScrollPanel of GWT in a page. Since most of the contents are in the ScrollPanel, I want it to take an as-large-as-possible part of the page and resize as the page may resize. Naturally I would want to set it a relative size, i.e. setSize("100%","100%"). However the document says it can only be set a size in absolute CSS units (e.g. "10px", "1em", but not "50%")
I cannot understand why ScrollPanel cannot take relative size in GWT. After searching and reading a lot, someone suggests just set the element's size to "100%" (see GWT Relative Width). I may give it a try but not sure if it will affect ScrollPanel's other function - as I will also control the scroll of the panel.
ScrollPanel myScrollPanel = new ScrollPanel();
myScrollPanel.setSize("2112px", "150px"); // Arbitrary width.
myScrollPanel.getElement().getStyle().setProperty("width", "100%");
So here's my questions:
(1) Why??? (this is driving me mad as I cannot understand, maybe someone with deeper understanding of the GWT inside mechanism can enlighten me)
(2) How to work around?
ScrollPanel implements RequiresResize interface, which means that it needs to get it size from its parent, or its size has to be set explicitly. Thus, you have two options.
(1) Use a parent widget that implements ProvidesResize interface - for example, LayoutPanel. It's important, however, that ProvidesResize - RequiresResize chain remains unbroken all the way from RootPanel to your ScrollPanel.
In a typical implementation, LayoutPanel (or its variant) represents your entire page. Then you can add various children to it, e.g. "header", "main view", "left menu", etc. For each child you can set the preferred size. For example:
myLayoutPanel.setWidgetTopBottom(myScrollPanel, 32, Unit.PX, 0, Unit.PX);
In this example your ScrollPanel will take all available space on a page starting from 32px at the top and all the way to the bottom. You can set its position in percentages or other units instead.
(2) You can accomplish the same layout with pure CSS. If you don't care about very old browsers, the best option is to use flexbox layout model. In this case you set display: flex on your parent widget, and flex-grow: 1 on your ScrollPanel - telling it to take all available space (unless there are other flex-grow siblings, in which case they will split the extra space).
The answer to your first question is very simple. When using the relative size for an element you are referring to the size of a parent element. So when you set height: 100% it means that your element should be 100% size of its parent.
And there are some ways to get what you want:
use the Viewport-percentage lengths - you can set height: 100vh which means 100% of the viewport height - this is the easiest way but may be not yet supported by all browsers
set both the html and body elements 100% height - this will allow you to use the relative height on child elements
use GWT DockLayoutPanel or DockPanel and add your scroll panel to the center pane - it will take all the remaining space
First, ScrollPanel is something not acting as other widget for reason I don't know why. Cannot set relative size (50%), and if I give it some style, it's lost somewhere and cannot be found from page.
My solution is to use a ResizeLayoutPanel. Andrei suggested using something ProvidesResize but requires the provide / require resize chain remain unbroken, which can be very tricky. I found this ResizeLayoutPanel "ProvidesResize to its one child, but does not RequiresResize", which is the perfect candidate for the root panel of my composite. Then, I just extend the ScrollPanel to resize itself in the "onResize" method whenever it's called by the parent ResizeLayoutPanel.
Still no answer to my first question: by ScrollPanel behave like this in the first place? I tried to find answer in its source code but was not successful (though I didn't spend enough time studying the source code).
public class My100PctScrollPanel extends ScrollPanel {
#Override
public void onResize() {
// Window.alert("on resize");
this.setWidth(this.getParent().getOffsetWidth()+"px");
this.setHeight(this.getParent().getOffsetHeight()+"px");
super.onResize();
}
}
........
compositeRoot = new ResizeLayoutPanel();
........
scrollPanel = new My100PctScrollPanel();
compositeRoot.clear();
compositeRoot.add(scrollPanel);

Saving off an element's CSS and reapply later

Is it possible to save off all CSS that is 'currently' applied to an element, then later reapply it? I am working on a sticking table header, and when I i change position:fixed it loses all the applied styles. I currently save off the column widths and reapply to the table header with:
$('#tableHeader').css({
position:'fixed',
width:$('#tablePanel').width(),
top:$('#top').height(),
});
$('.column1Value').width(col1Width);
$('#col1').width(col1Width);
$('.column2Value').width(col2Width);
$('#col2').width(col2Width);
$('.column3Value').width(col3Width);
$('#col3').width(col3Width);
$('.column4Value').width(col4Width);
$('#col4').width(col4Width);
$('.column5Value').width(col5Width);
$('#col5').width(col5Width);
$('.column6Value').width(col6Width);
$('#col6').width(col6Width);
$('.column7Value').width(col7Width);
$('#col7').width(col7Width);
This make the columns the correct size and line up closely, but there is extra padding or margin being applied from somewhere I can't completely figure out (bootstrap probably), and this makes the headers and columns not line up. I was hoping for something like:
var savedCSS = $('#table').css(); and retrieve it like $('#table').css(savedCSS)
You could save off the individual styles that you are interested in one by one and then re-apply them later using the jQuery("selector").css("styleName") method that you alluded to, but I don't think there's an easy way to do them all at once. It's not impossible, but wouldn't be very efficient and probably wouldn't actually give you the result you want, once the element is in its new position.
After the discussion, we found that the sizing issue wasn't really due to the styles, but due to the element that the width was being calculated from.
When the element is positioned normally in the page-flow, it uses its most recent positioned parent's width and then takes off margin to find the width of the child content.
When the element is removed from the page flow, its width is then independent of the parent. So to get the two to match up, record the parent's width rather than the element itself and set the width to match the parent, instead of trying to maintain the element's width.

Categories