PDA

View Full Version : Ext.ux.PanelCollapsedTitle - Cross-browser vertical text



joeri
10 Jan 2010, 12:07 PM
This plugin renders Ext.Panel collapsed title bar text, and rotates that text for west and east Panels. Go to the bottom of this post for the download and demo links, and for screenshot goodness.

----------------

The problem

The collapsed title thread (http://www.extjs.com/forum/showthread.php?t=18683) got me thinking about how to do vertical (rotated) text in a cross-browser way.

A quick recap of all the known ways text can be rotated in the browser:

CSS transform (http://snook.ca/archives/html_and_css/css-text-rotation)
Supported in newer webkit and gecko browsers, not supported in Opera or IE.
CSS writing-mode (http://www.thecssninja.com/css/real-text-rotation-with-css)
Supported in IE 5.5+, not supported anywhere else.
IE Rotate Filter (http://snook.ca/archives/html_and_css/css-text-rotation)
Supported in IE 5.5+, not supported anywhere else.


Sadly, none of those methods allow support for older gecko browsers, and none offer support for opera. Because of this, rotated text in the real world is still done with images, because that's the only known cross-browser method.

The solution: SVG

SVG supports rotated text. SVG is supported in Opera 8+, Firefox 2+, Safari 3+ and Chrome. Aside from IE, that's pretty much every browser out there. So, SVG provides a theoretical path to rotated text. The idea to try it had crossed my mind, but I hadn't taken it seriously. When Condor suggested the same thing, I felt obligated to at least try to make it work.

Using SVG to actually rotate text turns out to be tricky, mostly because browsers won't let you embed it as part of the DOM without using javascript. But, in the end the required code is pretty reasonable:

var SVGNS = 'http://www.w3.org/2000/svg';
var svg = document.createElementNS(SVGNS, 'svg');
// container is the DOM element to add the rotated text to
container.appendChild(svg);
var textBlock = document.createElementNS(SVGNS, 'text');
textBlock.setAttribute('transform', 'rotate(90)');
// SVG text nodes use 'fill' instead of 'color'
textBlock.setAttribute('style', 'fill:red;');
svg.appendChild(textBlock);
var text = document.createTextNode('rotated text');
textBlock.appendChild(text);


Combining this with SVG feature detection and fallback support for IE using CSS writing-mode, I arrived at a simple cross-browser rotated text example (http://sebrechts.net/demo/collapsedtitle/justtherotation.html):
http://sebrechts.net/demo/collapsedtitle/screenshot1.png

Then, it was just a matter of combining this knowledge with the code on the collapsed title thread, to get a generic Ext.Panel plugin. While a pure-css solution doesn't seem to be possible, javascript once again comes to the cross-browser rescue.

This solution works in Firefox 2+, Opera 8+, Safari 3+, IE 6+ and Chrome.

----------------

Plugin

Plugin code: Ext.ux.PanelCollapsedTitle.js (http://sebrechts.net/demo/collapsedtitle/Ext.ux.PanelCollapsedTitle.js)

Demo page (http://sebrechts.net/demo/collapsedtitle/collapsedtitle.html)

To use on an Ext.Panel, pass the following in the config object:

plugins: [Ext.ux.PanelCollapsedTitle]

The plugin also supports a collapsed title bar icon via the collapsedIconCls property, and patches the setTitle function so you can update the Panel title at run-time.

Demo screenshot:
http://sebrechts.net/demo/collapsedtitle/screenshot2.png

Licensed under http://www.gnu.org/licenses/lgpl-3.0.txt

History

1.0 (2009-01-10): First version
1.1 (2009-01-11): Fixed compatibility with complex layouts

elnove
10 Jan 2010, 3:51 PM
very cool man

elnove
10 Jan 2010, 4:01 PM
kaltxì ma joeri,

I wanted to point out that: "Aside from IE, that's pretty much every browser"...Well, whether we like it or not, IE is still 80% of the market. We developers mast take that into considuration.
Also, I checked it with IE 8 and IE8 in competability mode and it works fine.

Éywa ngáhu

joeri
10 Jan 2010, 11:58 PM
For IE, it uses a CSS fallback to rotate the text, using the writing-mode style. My point was that IE is pretty much the only browser actively used that doesn't support SVG. Even the older versions of popular browsers support it well enough for something like this.

Scorpie
12 Jan 2010, 9:57 AM
Nice, good work!

Stju
16 Feb 2010, 4:05 AM
Excellent work!

Alshten
18 Feb 2010, 8:46 AM
Excellent plugin ! So easy to use ! ;)

dawesi
1 Mar 2010, 4:14 PM
super cool... and useful!

chrismarx
8 Mar 2010, 6:36 AM
more praise, works great!

albeva
10 Mar 2010, 3:51 AM
Great plugin. only minor complaint - could you indent code properly? with each level nested? that would make it perfect :)

Yoris
10 Mar 2010, 12:19 PM
Great Work!! Thanks for sharing!!!!:D:D:D:D

wm003
30 Apr 2010, 5:42 AM
Just what i needed. Thank you very much for sharing! :)

MaximGB
30 Apr 2010, 5:58 AM
Thanks a lot.

Boxcopter
30 Apr 2010, 10:12 AM
Great plug-in works as you would hope it would. Fast too.

pdugas
21 Jun 2010, 9:04 AM
I wonder if this concept could be applied to grid column headings.

joeri
22 Jun 2010, 12:20 AM
pdugas, can you explain what you mean? This concept can be used to display any text vertically in the browser.

wm003
22 Jun 2010, 10:22 AM
i guess he wants to use very small grid columns but a column header with a much larger text

pdugas
22 Jun 2010, 10:27 AM
I'm wondering first if there's a way to override the default appearance of grid column headings and then, if this plugin could be converted into another that would allow the text of grid headings to be rotated. Think about displaying data where the values are narrow but the heading-text is pretty long. I expect this would be pretty messy to implement and I'm not sure how to deal with the controls (sort, group, show/hide, filter) that they can have.

wemerson.januario
22 Jun 2010, 1:31 PM
nice work

joeri
22 Jun 2010, 11:12 PM
I'm wondering first if there's a way to override the default appearance of grid column headings and then, if this plugin could be converted into another that would allow the text of grid headings to be rotated. Think about displaying data where the values are narrow but the heading-text is pretty long. I expect this would be pretty messy to implement and I'm not sure how to deal with the controls (sort, group, show/hide, filter) that they can have.

Just look in GridView.js. It's quite easy to change the behavior of the headers in a subclass. The hcell template defines the content of the header cell. The meat of the rendering is in renderHeaders and renderUI, and the event handling is in the handleHd... functions. If you get really creative, you could even do it with a plugin.

I am doubtful about the utility though. Vertical text is tall, and you run the risk of having a ridiculously tall header.

imran
12 Nov 2010, 7:29 AM
woah, nicely done!

gustavo21
30 May 2011, 4:27 PM
This is a GREAT plugin, and this post deserves to come alive. Thanks

gustavo21
9 Jun 2011, 7:00 PM
Hi, this doesn't work on adobe air... when i collapse the panel, just show the firtst char, not rotate. Any help??

Thanks.

joeri
9 Jun 2011, 11:17 PM
Adobe Air doesn't support SVG, so the fallback path for IE is triggered.

You could try adding something like this after the "writing-mode" style: -webkit-transform: rotate(90deg);

However, you may have issues with bad alignment if you do that, so you may have to toy around with the top and left styles in that case.

gustavo21
10 Jun 2011, 9:44 AM
Thanks! but i have a question... where should i write "style: -webkit-transform: rotate(90deg);"?? jeje

I do:

// use writing-mode for vertical text
titleElemStyle +=
'white-space: nowrap; writing-mode: tb-rl; top: 1px; left: 3px; style: -webkit-transform: rotate(90deg)';


And do nothing... any else??

Thks

gustavo21
10 Jun 2011, 2:46 PM
Soy Groosssooo jeje

Here is what i did:

In index.html:

.x-panel-header-rotated {
-webkit-transform: rotate(90deg) !important;
}

Gariq
4 Oct 2011, 6:40 AM
Very useful, thanks

zeraien
27 Nov 2011, 5:48 AM
Just implemented it with ext 3.4.0, works great! Thanks!

cgi-bin
21 Mar 2014, 12:24 PM
Was this ever updated to work with ExtJS 4?

joeri
23 Mar 2014, 11:56 PM
Was this ever updated to work with ExtJS 4?

No, I still haven't made the leap to ExtJS 4. Our whole team is dug in building two huge modules on top of our ExtJS 3 codebase so we don't have the manpower to move to ExtJS 4 without incurring huge delays. Maybe in fall after the systems are built we'll have an opportunity to make the switch. Ofcourse, by then we'll have several hundred thousand lines of ExtJS code to port, so that's going to be a lot of fun :((

cgi-bin
24 Mar 2014, 6:40 AM
No, I still haven't made the leap to ExtJS 4. Our whole team is dug in building two huge modules on top of our ExtJS 3 codebase so we don't have the manpower to move to ExtJS 4 without incurring huge delays. Maybe in fall after the systems are built we'll have an opportunity to make the switch. Ofcourse, by then we'll have several hundred thousand lines of ExtJS code to port, so that's going to be a lot of fun :((

I certainly understand that. My current code is still "stuck" in 3.4 as well, partially because 4 was released right in the middle of our development cycle. I took a quick attempt to convert to 4, but even using the compatibility/conversion tools, it really didn't work the same. And I am the only one on my team with really any JS (let alone ExtJS) experience to try to update our front-end UI. Since then the other member of my team had left, so I'm juggling both sides of the code, with no time to dedicate to upgrade. And as time goes by, I keep digging myself further and further in the hole by adding more code that will eventually need to be upgraded.

I'm not sure if I posted this anywhere before, but if anyone is interested, I did manage to implement having the collapsed region fly-out on hover (doesn't need to be a treePanel, any panel should work):
navPanel = new Ext.tree.TreePanel
({
id:'nav-tree'
,region:'west'
,header:true
,title:'Navigation'
,collapsible:true
,singleExpand:true
,width:200
,lines:false
,autoScroll:true
,margins:'0 3 3 3'
,loader:new Ext.tree.TreeLoader() // config removed for brevity
,rootVisible:false
,root:new Ext.tree.AsyncTreeNode() // config removed for brevity
,toggleTip:
{
text:'Collapse'
}
,listeners:
{
afterlayout:
{
fn:function(c, l)
{
var region = c.ownerCt.layout[c.region];

// have to call this so that the dom elements are created!
var ce = region.getCollapsedEl();

// enable the Collapse/Expand tool tips
c.toggleTip.target =
[
c.tools['toggle']
,region.expandToolEl
,region.miniSplitEl
,region.miniCollapsedEl
];
Ext.QuickTips.register(c.toggleTip);

// enable the slide-out on hover over collapsed area
ce.on
(
'mouseenter'
,function(e, t)
{
if (c.collapsed)
{
region.slideOut();
}
}
);
}
,single:true
}
,expand:function(p)
{
p.toggleTip.text = 'Collapse';
}
,collapse:function(p)
{
p.toggleTip.text = 'Expand';
}
,click:function(node, e)
{
// Hide the slide-out nav panel once we click on something within it
if (this.collapsed)
{
this.ownerCt.layout[this.region].slideIn();
}
}
}
,plugins:[Ext.ux.PanelCollapsedTitle]
});

wm003
26 Mar 2014, 1:00 AM
This is working out of the Box with Ext 4.2

http://docs.sencha.com/extjs/4.2.1/extjs-build/examples/layout/border.html