i am new to vaadin , i created tabsheet with two tabs one with graphs and another with some info, my problem was how to add components(combobox, labels) at right corner(same row) of the tabs.
final TabSheet tabSheet = new TabSheet();
tabSheet.setSizeFull();
tabSheet.addTab(rightAndLowerPanels, "Graphs");
tabSheet.addTab(new Label("<b>Haiiiiiiiiiiiii</b>", ContentMode.HTML), "Message");
Ex;
tab1|tab2
I want to add here
i am not able to post image for this problem.
Thanks in advance
While the component itself doesn't support this, it is possible to accomplish this with setting the components absolute position with css so it hovers over the tabsheet in the correct position.
The div(layout) that contains the tabseet and the hovering component should be set position: relative; so that the absolute position is set from the corner of the component not the browser and then set the combobox's position to something like this: position:absolute; right: 3px; top: 3px;.
You can even use Vaadin's AbsoluteLayout or CssLayout if you want to add some checks for determining the components position.
AbsoluteLayout al = new AbsoluteLayout();
al.addStyleName("tab-sheet-layout"); // position: relative;
al.addComponent(new TabSheet(new Label("1"),new Label("2")));
al.addComponent(new ComboBox(), "right: 5px; top: 5px;");
or with CssLayout:
public static class TabSheetLayout extends CssLayout {
public TabSheetLayout() {
addStyleName("tab-sheet-layout"); // position: relative;
addComponent(new TabSheet(new Label("1"),new Label("2")));
addComponent(new ComboBox());
}
#Override
protected String getCss(Component c) {
if (c instanceof ComboBox) { // do some check here
return "position:absolute; right: 3px; top: 3px;";
}
return null;
}
}
You should note however that if you resize the screen small enough, the combobox will be hovering over the tabs, so you need to stop this by fixing the layout width or by some other method.
Related
I have been wasted hours and days trying to style the Vaadin Upload component. The goal is simple:
sometimes I need the component to show the uploaded file using its built-in file list with allows delete.
other times, I want to hide this list because I have another component such as Grid to show the file details.
Now comes the problem, I can never get it to consistently work using #CssImport with themeFor=vaadin-upload and themeFor=vaadin-upload-file. Vaadin seems to compile the shadow dom and the final result varies, it mixes up the two options and whichever comes last gets applied.
I then thought maybe because the #CssImport is in the #Route component. So, I created two custom upload components that extended the vaadin-upload component with the difference being the different #CssImport (see below). That (frustratingly) still doesn't work. I inspect the document and found that the inside the shadow-dom contains both even though I never use both on the same page.
#CssImport(value = "./css/vaadin-upload-show.css", themeFor = "vaadin-upload")
public class UploadShowFiles extends Upload {
private static final long serialVersionUID = -9198630843136885092L;
public UploadShowFiles(Receiver receiver) {
super(receiver);
}
}
#CssImport(value = "./css/vaadin-upload-hidefile.css", themeFor = "vaadin-upload")
public class UploadHideFiles extends Upload {
private static final long serialVersionUID = 2344860066834705807L;
public UploadHideFiles(Receiver receiver) {
super(receiver);
setClassName("hide-upload");
}
}
The css below will appear in the shadow dom. I expect only display: none or otherwise, not both.
[name="file-list"] {
display: none !important;
height: 0px !important;
}
[name="file-list"] div[part="file-list"] {
display: none !important;
}
[name="file-list"] {
display: block !important;
height: 1.5rem !important;
}
[name="file-list"] div[part="file-list"] {
display: block !important;
}
p/s: This is my first experience using Vaadin in a project and I probably never going to use it again. Customizing anything in Vaadin is so time-consuming and painful.
Styling in the shadow DOM can indeed be tricky. The simplified theming in Vaadin 19 helps a bit.
Where the #CssImport annotation is placed affects if the CSS should be included in the document, but not which components it affects. With themeFor, it will always be applied to all matching components.
What you can do is to use the :host selector to limit which upload components it applies to. Here I am using a class-based approach:
:host(.no-file-list) [name="file-list"] {
display: none !important;
height: 0px !important;
}
:host(.no-file-list) [name="file-list"] div[part="file-list"] {
display: none !important;
}
I can then hide the file list in an upload component by adding a class:
#Route
#CssImport(value = "./styles/upload-style.css", themeFor = "vaadin-upload")
public class FileUploadTest extends VerticalLayout {
public FileUploadTest() {
Upload uploadWithFileList = new Upload();
Upload uploadWithoutFileList = new Upload();
uploadWithoutFileList.addClassName("no-file-list");
add(uploadWithFileList, uploadWithoutFileList);
}
}
Having a small issue with tooltips in the editor, read the api but can't understand what it is saying and I can't seem to find examples anywhere that I can understand either.
I have set up a Classic Editor build, and all the buttons on the toolbar have tooltips with the default position below the button, I want to be able, just for this one instance of the editor, to change the tooltip position to above the buttons instead. The instance is set up like this:
ClassicEditor.create( document.querySelector( '#content' ) )
.then( editor => {
console.log( 'Editor was initialized', editor );
this.annEditorInstance = editor;
} )
.catch( err => {
console.error( err.stack );
} );
That creates an editor instance that is set up exactly as I want, except for the issue with the tooltip. How do I change this? Thanks in advance.
There are two approaches to the problem:
CSS
Tooltips elements have either .ck-tooltip_s or .ck-tooltip_n class. By default all CKEditor 5 tooltips have the former so you could override it in your styles and make it act like the later:
<style>
.ck.ck-tooltip.ck-tooltip_s {
bottom: auto;
top: calc(-1 * var(--ck-tooltip-arrow-size));
transform: translateY( -100% );
}
.ck.ck-tooltip.ck-tooltip_s .ck-tooltip__text::after {
top: auto;
bottom: calc(-1 * var(--ck-tooltip-arrow-size));
transform: translateX( -50% );
border-color: var(--ck-color-tooltip-background) transparent transparent transparent;
border-width: var(--ck-tooltip-arrow-size) var(--ck-tooltip-arrow-size) 0 var(--ck-tooltip-arrow-size);
}
</style>
JS
The UI of the editor is an MVC(VM) structure. The position of the tooltip can be controlled using the JS and the Button#tooltipPosition property ('s' or 'n').
E.g. you can access the toolbar UI elements using editor.ui.view.toolbar and change their properties:
editor.ui.view.toolbar.items.map( item => item.tooltipPosition = 'n' )
but note that not all toolbar items are buttons. Some, for instance, are dropdowns so you'd need to use item.buttonView.tooltipPosition = 'n' in that case. So unless you really want to use JS, I'd go with a simple CSS solution.
Currently I am using AbsoluteLayout, but because of some problems I would like to give CssLayout a try.
I would like to dynamically place image-, label- and button-components at specific positions in the layout.
AbsoluteLayout allows me to specify the position like so:
absoluteLayout.addComponent(component, "top:20px;left:20px")
Is something like this at all possible to achieve with CssLayout?
You can apply inline CSS for a component by overriding getCss on CssLayout, so the following should have the wanted result:
CssLayout cssLayout = new CssLayout() {
#Override
protected String getCss(Component component) {
// check the component here and return correct css. In this case only one component in the layout so this works..
return "position: relative; top: 10px; left: 10px";
}
};
cssLayout.setSizeFull();
cssLayout.addComponent(new Button("Hello"));
I'm trying to hide the horizontal scrollbar of a Angular ui-grid, but I can't find the right property. (Property enableScrollbars=false removes both.)
Is it possible to remove only the horizontal scrollbar?
With the latest version on Github v3.0.0-rc.16 you can disable horizontal and vertical Scrollbar separately.
Instead of
enableScrollbars = false;
use
enableHorizontalScrollbar = value;
enableVerticalScrollbar = value;
with
value = 0; /* NEVER */
value = 1; /* ALWAYS */
value = 2; /* WHEN_NEEDED */
UPDATE:
If you want to use constants instead of the integer-value, look at corresponding post:
Using ui-grid constants to disable scrollbars
UPDATE:
The option WHEN_NEEDED doesn't seem to be available at the moment.
Maybe this will be changed again, so please look for the available constants in the source code.
The Constants are defined in
https://github.com/angular-ui/ui-grid/blob/master/packages/core/src/js/constants.js
At now, the option WHEN_NEEDED doesn't seem to be available at the moment (ui-grid 3.1.1). So I have worked around by jQuery and CSS:
For simple, we just need do this:
.ui-grid .ui-grid-render-container-body .ui-grid-viewport {
overflow-x: auto !important;
/* or use: overflow-x: hide!important; */
}
To more flexible, we can use CSS class and jQuery. First, we add one more class:
.ui-grid-render-container-body .ui-grid-viewport.no-horizontal-bar {
overflow-x: hidden !important;
}
In controller, we will use this class by jQuery:
$timeout(function(){
if (!!$scope.gridOptions.data) {
$('.ui-grid-render-container-body .ui-grid-viewport').addClass("no-horizontal-bar");
}
});
To hide the blank gap when use selecting and grouping (http://i.imgur.com/veevhgQ.png), we use:
$timeout(function(){
if (!!$scope.gridOptions.data) {
/* To hide the blank gap when use selecting and grouping */
$('.ui-grid-render-container-left .ui-grid-viewport').height($('.ui-grid-render-container-left .ui-grid-viewport').height() + 17);
$('.ui-grid-render-container-body .ui-grid-viewport').addClass("no-horizontal-bar");
}
});
With 17px is height of the gap when we use selecting and grouping feature.
Demo: http://plnkr.co/edit/D9PKPkvuRy2xA6UNNXCp?p=preview
With this solution we can show the horizontal bar again easily.
If you are allowed to use flexboxes:
.ui-grid-render-container-body {
.ui-grid-header {
padding-right: 17px;
.ui-grid-header-viewport {
width: 100%;
.ui-grid-header-canvas {
width: 100%;
.ui-grid-header-cell-wrapper {
display: block;
width: 100%;
.ui-grid-header-cell-row {
display: flex;
min-width: 0;
.ui-grid-header-cell {
flex: 1 1 0;
min-width: #col-min-width;
}
}
}
}
}
}
.ui-grid-viewport {
overflow: auto !important;
display: flex;
.ui-grid-canvas {
flex: auto;
min-width: 0;
[role="row"] {
display: flex;
min-width: 0;
.ui-grid-cell {
flex: 1 1 0;
min-width: #col-min-width;
}
}
}
}
}
Where col-min-width is a minWidth that you would normally set in the gridOptions. Also you have to set the ui-grid-header's padding-right (which is 17px in this example) to the width of your browser's scrollbar with the javascript on certain events: number of rows changed, container resized etc. Scrollbar width = ui-grid-viewport's offsetWidth - clientWidth. Using a hardcoded value for scrollbar width is bad because different browsers have different (and even configurable) values for that.
I have a problem formatting toplevel-nodes in a Vaadin-Tree. I understand using the ItemStyleGenerator to set ccs-Style for particular nodes. I did this with following code:
this.setItemStyleGenerator(new Tree.ItemStyleGenerator() {
#Override
public String getStyle(Tree source, Object itemId) {
if (source.isRoot(itemId)) {
return "toplevel";
} else {
return null;
}
}
});
The CSS is as follows:
.v-tree-node-toplevel {
border: 1px solid #d8d9d9;
background: #fff;
#include border-radius(6px);
}
And the result is, that the root-node and all its child nodes have the same background-color and the border is around the toplevel- and all its child-nodes and the node icon is missing
My goal is to format just the root-node.
When i set the toplevel-style to a child node it is formatted as expected.
Can somebody help? Thanks.
Bernhard
Change your CSS to this:
.v-tree-node-caption-toplevel {
border: 1px solid #d8d9d9;
background: #fff;
#include border-radius(6px);
}
If you only want to style behind the text, and not the whole width of the tree, use this:
.v-tree-node-caption-toplevel span {
CSS stuff...
}
(The text part of the caption is contained within a span inside the v-tree-node-caption element.)
Here's a (not very detailed) explanation of what's occurring:
An expanded node inside a Vaadin tree (with children) is actually made up of about 3 distinct divs. First you have the container div, which is v-tree-node. Then you have the v-tree-node-caption which is an inner div that contains the name and icon of the node, this is probably what you want to style. Last, there is v-tree-node-children which contains all the child nodes underneath. The ItemStyleGenerator not only applies your style to the v-tree-node, but the v-tree-node-caption and v-tree-node-children as well.
This is basically how your HTML will look when you apply the toplevel style to an item:
<div class="v-tree-node v-tree-node-toplevel">
<div class="v-tree-node-caption v-tree-node-caption-toplevel">
node1, the best node!
</div> //end of caption
<div class="v-tree-node-children v-tree-node-children-toplevel">
...
Other divs (child nodes)
...
</div> //end of children
</div> // end of node
You were losing the arrow icon because it's the background image of the v-tree-node. Each v-tree-node (where canHaveChildren() == true) has a background style (transparent, with the arrow image).
.v-tree-node {
url("../reindeer/tree/img/arrows.png") no-repeat scroll 6px -10px transparent;
}
If you override the background style on a v-tree-node, you will lose the image (the arrow). What you could do instead is to use the background-color style to only override the transparent part, but as I pointed out earlier, the v-tree-node element contains both the caption and children elements, so your background color will be visible behind any child nodes (and slightly to the left, even if you style the background-color of the child node).