How do I set themes for widgets in windows? - qooxdoo

with the tutorials on qooxdoo.org I found out how to theme my widgets. This works great for overall styling.
If I configure "label", all my labels become a yellow textcolor. If I configure "button/label", all labels on my buttons become a red textcolor while every other remains yellow. Good so far.
What's not working is if I try to set a textcolor for labels inside a window:
"window/label", "window/pane/label", "window/widget/label" With none of these keys I can change the style for label-widget inside my window.
What is the correct key to give labels as child-elements inside my window a different style?
Thanks a lot
Ricky

A qx.ui.window.Window is a container wich implements RemoteChildrenHandling. That means, that the chain of child controls stops when it comes to the window content.
Depending on what you want to achieve, you can:
add a Label to a Window and set the Label appearance directly
inherit from Window (i.e. a custom Dialog class of your own), add a content label as a childControl of your dialog and adjust the Label color in your theme by using the choosen child control path
The first option would lead to this code:
var win = new qx.ui.window.Window("My Title");
win.setLayout(new qx.ui.layout.VBox(10));
win.add(new qx.ui.basic.Label("My content").set({
appearance: 'custom-label-appearance'
}));
If you've just some appearances for Label objects and you don't want to add the appearance every time, you also could subclass it:
qx.Class.define("my.Label", {
extend: qx.ui.basic.Label,
properties: {
appearance: {
refine: true,
init: 'custom-label-appearance'
}
}
});
var win = new qx.ui.window.Window("My Title");
win.setLayout(new qx.ui.layout.VBox(10));
win.add(new my.Label("My content"));
Here is an example for the second option:
qx.Class.define("my.Dialog", {
extend: qx.ui.window.Window,
construct: function(title, label) {
this.base(arguments, title);
this.setLayout(new qx.ui.layout.Atom());
this.getChildControl('my-label').setValue(label);
},
members: {
//overridden
_createChildControlImpl : function(id)
{
var control;
switch (id)
{
case "my-label":
control = new qx.ui.basic.Label();
this.add(control);
break;
}
return control || this.base(arguments, id);
}
}
});
You can then set the appearance path window/my-label in this case.
Note that both solutions will not keep you away from setting appearances to all labels that you add to the window.

Related

Ext JS Progress Bar - text align to center

Just started using progressbarwidget, I want the text from my textTpl to be center aligned within the progress bar at all times regardless of what percentage the bar is at, when I mean centered I mean the center of the progress bar and not center of the progress value. See fiddle below and attached image
https://fiddle.sencha.com/#fiddle/1dm7
I seen a reference on another thread to set position : relative, this does set the text to the center of the bar but doing so means the bar does not show the progress anymore. I see when the progress bar is created it has 2 divs, containing the following classes, x-progress-text and x-progress-bar, both contain the text value.
Thanks in advance
You can extend ProgressBarWidget, and override the template, like:
Ext.define('Fiddle.view.ProgressBarWidget', {
extend: 'Ext.ProgressBarWidget',
xtype: 'fiddle-progressbarwidget',
template: [{
reference: 'backgroundEl'
}, {
reference: 'barEl'
}, {
reference: 'textEl',
style: {
left: 0,
right: 0
}
}],
});
Working example: https://fiddle.sencha.com/#fiddle/1dn4
The definitive solution is to add an onResize handler on the progress bar container:
onResize: function () {
var me = this,
progressBar = me.down('progressbarwidget');
// Set text width to element width so that it can be centered
progressBar.setWidth(progressBar.el.getWidth());
}
This idea is copied from what happens in Ext.grid.column.Widget.onResize().
The solution from user CD.. doesn't work (nor does the one in user2751034 comment)
in the case you have two-color-text, like in Classic theme:
even if you reproduce the template in Sencha sources (with textEl children of barEl):

Custome MessageBox under Tab(s) ExtJs

I like to separate MessageBox tab to tab. One MessageBox will shown in one particular tab and will hidden from all other tab(s). What is now show as global in application. Is there any way to show message under every tab(s) in application.
You cannot use a messagebox with different content on the separate tabs at the same time while messagebox is a singleton, but you can create your own messagebox, extending from Window and render each instance to the separate tab. Here is example with native Window, but it will work the same with extended component.
You cannot directly use Ext.window.MessageBox to achieve what you want. On the other hand, you can create a small utility class that extends Ext.window.Window, with a static function that makes it appear with the title, message, and buttons as parameters, and use the constrainTo option to make it belong to your tab.
This way, you have a window that can be "owned" by a tab instead of appearing globally
Here i create a function to show message as messagebox. And i can use it whatever i need.
ShowPrivateMessage: function(title, widthValue, heightValue, msgText, renderTabId){
Ext.create("Ext.window.Window",{
title : title,
width : widthValue,
height: heightValue,
html : '<span style="font-size: small">'+ msgText + '</span>',
renderTo: renderTabId,
resizable: false,
draggable: false,
bodyPadding: '10px',
listeners:{
afterrender: function(sender, eOpt){
var parentWindow = Ext.getCmp(renderTabId);
parentWindow.disable();
}
,close: {
fn:function(ctrl,opt){
var parentWindow = Ext.getCmp(renderTabId);
parentWindow.enable();
}
}
}
}).show();
}

How to create ExtJS5 draggable window?

I need to create a window that will be always visible unless it is made hidden by clicking on an icon. Clicking on that icon a second time will make the window re-appear. The icon needs to be stuck at the top left corner of the window and outside of the window. I am planning to create a window without title and with two items 1: Button to hide/show and 2: the actual panel. The fiddle can be found at: https://fiddle.sencha.com/#fiddle/bi7 I need to make the portion behind the button transparent. Is there a way to do that?
You would do this manually, ideally with CSS classes. The following is crude, using inline styling, but works. Add the following listeners attribute to your button
{
xtype: 'button',
...
listeners: {
click: function(){
var panel = Ext.getCmp("togglePanel");
if (panel.el.dom.style.display == "none") {
panel.el.dom.style.display = "block";
} else {
panel.el.dom.style.display = "none";
}
}
}
}
and include the id 'togglePanel to your green panel containing the slider
id: "togglePanel",
Clicking the button will show/hide your panel

Need to set class/id values on buttons in Extjs MessageBox

Our testing team require IDs or class values to be set on the HTML elements in our message popup boxes. This is for their automated tests.
I can pass in a class value for the dialog panel by passing in a cls value like so:
Ext.Msg.show({
title:'Reset Grid Layout',
msg: 'Are you sure that you want to reset the grid layout?',
cls:'Reset-Grid-Layout-Message',
buttons: Ext.Msg.YESNO,
fn: function (response) {
if (response == 'yes') {
}
},
icon: Ext.window.MessageBox.QUESTION
});
Now we also need it on the buttons, and also on the text being displayed. Is there some way of getting a cls value onto the buttons?
I was thinking it may be possible to expand the button parameter into something like :
buttons : [{name:'but1', cls:'asdf'}, {name:'but2', cls:'asdf2'}]
But google is not giving me back anything useful.
If your testing team uses Selenium for their automated test, adding ids/classes in every component could be difficult for both of you.
Overriding components in Ext is a good solution, but I don't recommend this because it will affect all your components. Unless you know what you're doing.
I suggest, extend Ext.window.MessageBox and generate classes for your buttons based on your parent cls.
// Put this somewhere like /custom/messagebox.js
Ext.define('App.MyMessageBox', {
extend: 'Ext.window.MessageBox'
,initConfig: function(config) {
this.callParent(arguments);
}
,makeButton: function(btnIdx) {
var me = this;
var btnId = me.buttonIds[btnIdx];
return new Ext.button.Button({
handler: me.btnCallback
,cls: me.cls + '-' + btnId
,itemId: btnId
,scope: me
,text: me.buttonText[btnId]
,minWidth: 75
});
}
});
To use:
App.Box = new App.MyMessageBox({
cls:'reset-grid-layout'
}).show({
title:'Reset Grid Layout'
,msg: 'Are you sure that you want to reset the grid layout?'
,buttons: Ext.Msg.YESNO
,icon: Ext.window.MessageBox.QUESTION
});
Your buttons will have reset-grid-layout-yes and reset-grid-layout-no class.
You can do the same with other components you have. Check out the Fiddle. https://fiddle.sencha.com/#fiddle/7qb
You should refer to the API
cls : String A CSS class string to apply to the button's main element.
Overrides: Ext.AbstractComponent.cls
You can also use the filter on right side (not the one in the right top corner). Just type cls and you will see all properties, methods and events containing cls (note that you see by default just public members, use the menu on the right of this searchfield to extend this)
Edit
If you just need it for testing purpose I would recommend to override the responsible method. This should work (untested!)
Ext.window.MessageBox.override({
buttonClasses: [
'okCls', 'yesCls', 'noCls', 'cancelCls'
],
makeButton: function(btnIdx) {
var btnId = this.buttonIds[btnIdx];
var btnCls = this.buttonClasses[btnIdx];
return new Ext.button.Button({
handler: this.btnCallback,
cls: btnCls,
itemId: btnId,
scope: this,
text: this.buttonText[btnId],
minWidth: 75
});
}
});

Auto-size Ext JS Window based on content, up to maxHeight

Using Ext JS 4.0.2, I'm trying to open a window that automatically sizes itself big enough to fit its content, until it hits a height limit, at which point it stops getting bigger and shows a scroll bar.
Here's what I'm doing
Ext.create('widget.window', {
maxHeight: 300,
width: 250,
html: someReallyBigContent,
autoScroll: true,
autoShow: true
});
When the window is first rendered, it's sized big enough for the really big content--bigger than the maxHeight should allow. If I attempt to resize it, then snaps down to the maxHeight of 300px.
How do I constrain the window to its maxHeight when it's initially rendered?
I have exactly the same problem and for now I'm doing a litle dirty hack :)
this.on('afterrender', function() {
if (this.getHeight() > this.maxHeight) {
this.setHeight(this.maxHeight);
}
this.center();
}, this);
Depending on the content of the window, you must use the afterlayout event. Instead of using this.maxHeight, to use the whole viewport, use Ext.getBody().getViewSize().height or in vanilla JS use window.innerHeight.
This version will work even if the windows contains other components and not only huge html:
listeners: {afterlayout: function() {
var height = Ext.getBody().getViewSize().height;
if (this.getHeight() > height) {
this.setHeight(height);
}
this.center();
}}
This can be better :
bodyStyle: { maxHeight: '100px' }, autoScroll: true,
I don't see an out-of-the-box way to do this. However, you might try this approach:
Place the contents of the window into a container inside the window (i.e. make someReallyBigContent be inside a container.) On afterrender, get the height of that inner container and then proceed to set the height of the outer window based on that.
How I ended up displaying a window with an unknown amount of fields on a form (constrain = body.el):
prefForm.itemId = 'prefForm';
win = Ext.create('Ext.window.Window', {
layout : {
type : 'vbox',
align : 'center'
},
buttons : buttons,
maxHeight : constrain.dom.clientHeight - 50,
title : title,
items : prefForm,
listeners : {
afterrender : {
fn : function(win) {
var f = win.down('#prefForm');
f.doLayout();
var h = f.body.dom.scrollHeight;
if (f.getHeight() > h)
h = f.getHeight();
win.setHeight(h + 61);
win.center();
},
single : true
}
}
});
You can add this config on your window
maximizable: true
if you want you could programmatically 'click' that button :)
Now I see what you are trying to do. I think the only thing missing from your config is the height parameter. Set it to the same number as maxheight. That should do it, you won't need to call setHeight().
This is just like Ivan Novakov answer, except I prefer it when you override the onRender class for these types of classes.
This is for a couple of reasons. Removes an additional event listener, and in the case you have multiple things that need to occur at afterrender time. You can control the synchronization of these tasks.
onRender: function(ct,pos) {
//Call superclass
this.callParent(arguments);
if (this.getHeight() > this.maxHeight) {
this.setHeight(this.maxHeight);
}
this.center();
}
I had the little bit different problem. In my case ExtJS code there inside the HTML popup windows. And I had to achieve:
change the size of panel when we change the size of popup windows.
Ivan Novakov's solution worked for me.
Ext.EventManager.onWindowResize(function () {
var width = Ext.getBody().getViewSize().width - 20;
var height = Ext.getBody().getViewSize().height - 20;
myPanel.setSize(width, height);
});

Resources