PDA

View Full Version : Ext.ux.ScrollPanel



hakonvik
25 Jul 2009, 6:47 AM
Hi all

Inspired by the new scroll arrows in Ext 3.0 menus I've tried to create a similar behaviour in an regular Ext.Panel if regular scrollbars is unvanted.

There might be better ways to implement this as this is my first extension attempt :-? Any comments and suggestions are of course appreciated!

Here's the code I've got so far:

CSS:


/* scrollers from /Ext/resources/images/default/layout/ */
.x-panel-scroller-top {
background:transparent url('mini-top.gif') no-repeat center center !important;
top: 0px;
}

.x-panel-scroller-bottom {
background:transparent url('mini-bottom.gif') no-repeat center center !important;
bottom: 0px;
}

.x-panel-scroller
{
position: absolute;
cursor: pointer;
z-index: 9000;
height:5px;
width:100%;
opacity: .5;
-moz-opacity: .5;
filter: alpha(opacity=50);
}

.x-panel-scroller-active
{
opacity: 1;
-moz-opacity: 1;
filter: alpha(opacity=100);
}
.x-plain-body
{
overflow: visible;
}
.x-plain-bwrap
{
overflow: visible;
}



Javascript:



Ext.ux.ScrollPanel = Ext.extend(Ext.Panel, {
initComponent: function () {
if (Ext.isArray(this.initialConfig)) {
Ext.apply(this, {
items: this.initialConfig
});
}
Ext.ux.ScrollPanel.superclass.initComponent.call(this);
this.on('collapse',this.constrainScrollers,this);
},
scrollIncrement: 15,
currentTop:0,
enableScrolling: true,
onScroll: function (e, t) {
if (e) {
e.stopEvent();
}
this.doScroll(Ext.fly(t).is('.x-panel-scroller-top'));
},
onWheel: function (e) {
if (e) {
e.stopEvent();
}
this.doScroll(e.getWheelDelta() > -1);
},
doScroll: function (t) {
if(this.el.scroll(t ? 't': 'b', this.scrollIncrement)){
this.currentTop = (t ? this.currentTop - 1 : this.currentTop + 1);
}else if(t){
this.el.dom.scrollTop = 0;
this.currentTop = 0;
}
},
onScrollerIn: function (e, t) {
Ext.fly(t).addClass(['x-panel-scroller-active']);
},
onScrollerOut: function (e, t) {
Ext.fly(t).removeClass(['x-panel-scroller-active']);
},
onRender: function (ct, position) {
Ext.ux.ScrollPanel.superclass.onRender.call(this, ct, position);
if (this.enableScrolling) {
if (!this.scroller) {
this.scroller = {
pos: 0,
top: this.container.insertFirst({
tag: 'div',
cls: 'x-panel-scroller x-panel-scroller-top',
html: ' '
}),
bottom: this.container.createChild({
tag: 'div',
cls: 'x-panel-scroller x-panel-scroller-bottom',
html: ' '
})
};

this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
listeners: {
click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
}
});
this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
listeners: {
click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
}
});
}

this.mon(this.container, {
scope: this,
delegate: '.x-panel-scroller',
click: this.onScroll
});

this.items.each(function(item){
item.on('collapse',this.constrainScrollers,this);
item.on('expand',this.constrainScrollers,this);
item.on('move',this.constrainScrollers,this);
}, this);

this.el.on('mousewheel', this.onWheel, this);
}
},
constrainScrollers: function () {
if(this.scroller){
if (this.collapsed || !this.el || (this.el.dom.scrollHeight - this.el.dom.clientHeight) <= 0) {
if(this.collapsed || this.currentTop == 0)
this.scroller.top.hide();
this.scroller.bottom.hide();
} else {
this.scroller.top.show();
this.scroller.bottom.show();
}
}
},
onResize: function (w, h) {
Ext.ux.ScrollPanel.superclass.onResize.call(this, w, h);
if(this.scroller){
this.scroller.top.setWidth(w);
this.scroller.bottom.setWidth(w);
this.scroller.top.setY(this.el.getXY()[1]);

this.constrainScrollers();
}
}
});

Example usage:


Ext.onReady(function() {
var scrollPanel = new Ext.ux.ScrollPanel({
split: true,
collapsible: true,
collapseMode: 'mini',
region:'west',
border: false,
split: true,
collapsible: true,
collapseMode: 'mini',
stateful:true,
baseCls: 'x-plain',
items: [{
frame: true,
title: 'Panel',
collapsible: true,
width: '100%',
html:'<br/><br/><br/><br/><br/>'
},{
frame: true,
title: 'Panel',
collapsible: true,
width: '100%',
html:'<br/><br/><br/><br/><br/>'
},{
frame: true,
title: 'Panel',
collapsible: true,
width: '100%',
html:'<br/><br/><br/><br/><br/>'
},{
frame: true,
title: 'Panel',
collapsible: true,
width: '100%',
html:'<br/><br/><br/><br/><br/>'
}]
});

var viewport = new Ext.Viewport({
layout: 'border',
items: [actionPanel, {
xtype:'panel',
region:'center',
html:''
}]
});

viewport.render(Ext.getBody());
actionPanel.constrainScrollers();
});