Revision: 17542
Updated Code
at September 9, 2009 11:55 by pdswan
Updated Code
var Panels = Class.create({
initialize: function(){
this.element = $(arguments[0]);
this.element.identify();
if( !this.element ){
throw 'Panels: invalid contianer element'
}
this.element.setStyle({
overflow: 'hidden'
});
this.element.makePositioned();
this.options = Object.extend({
force_horizontal: false,
panel_selector: '.panel',
only_children: false,
start_index: 0,
active_class: 'active',
onInitialized: Prototype.emptyFunction,
animation_scope: 'Panels'+this.element.identify(),
animation: function(offsets){
return new Effect.Scroll( this.element, {
x: offsets.left,
y: offsets.top,
mode: 'absolute',
duration: 1.0,
queue: {scope: this.options.animation_scope}
});
}
}, arguments[1] || {});
this.width_calculated = false;
this.panels =
this.options.only_children ?
this.element.childElements().findAll( function(e){
return e.match(this.options.panel_selector);
}.bind(this) ) :
this.element.select(this.options.panel_selector);
this.controls = {
gotos: $H(),
previous: $A(),
next: $A()
}
this.initialize_controls();
if (this._calculate_width()) {
this._finish();
}
},
_finish: function(){
this._calculate_offsets();
this.goto_panel(this.options.start_index);
this.options.onInitialized.call(this);
},
_calculate_offsets: function(){
this.offsets = $H();
this.panels.each(function(p){
this.offsets.set(p.identify(), p.positionedOffset());
}, this);
},
_calculate_width: function(force){
if( this.options.force_horizontal && (!this.width_calculated || force) ){
if( !this.container ){
// find the largest panel height
this.force_horizontal_height = this.panels.map(function(p){
var position = p.getStyle('position');
p.setStyle({'position': 'absolute'});
var height = p.getHeight();
p.setStyle({'position': position});
return height;
}).max();
this.container = new Element('div').setStyle({overflow: 'hidden', width: '100000px'});
this.panels.each(function(e){
this.container.insert(e.remove().setStyle({'float': 'left'}));
}, this);
this.element.insert(this.container);
this.default_width = this.element.getWidth();
}
var temp = new Element('div').setStyle({'float': 'left', 'width': '1px', 'height': '1px'});
this.panels.last().insert({after: temp});
return this._set_width(temp);
}
return true;
},
_set_width: function( elm, finish){
var width = elm.positionedOffset()[0];
/*
* if the scroll height of the container is greater than the maximum panel height, then all of the panels have not yet
* been inserted into the container. or height container height has not been properly computed yet.
*/
if( (this.default_width && width <= this.default_width) || (this.force_horizontal_height && this.container.scrollHeight > this.force_horizontal_height)){
this._set_width.bind(this, elm, 1).defer();
return false;
}else{
this.container.setStyle({width: width + 'px'});
this.width_calculated = true;
elm.remove();
if( finish ){
this._finish();
}else{
return true;
}
}
},
initialize_controls: function(){
var find = arguments[0] ? $(arguments[0]).select : $$;
this.panels.each(function(p){
var gotos = find('a[href=#' + p.identify() + ']').invoke('observe', 'click', this.goto_panel.bindAsEventListener(this, p));
this.controls.gotos.set(p.identify(), (this.controls.gotos.get(p.identify) || $A()).concat(gotos));
}, this);
var next = $$('a[href=#next].' + this.element.identify() + '_control[href=#next]').invoke('observe', 'click', this.next.bindAsEventListener(this));
this.controls.next = this.controls.next.concat(next);
var previous = $$('a.' + this.element.identify() + '_control[href=#previous]').invoke('observe', 'click', this.previous.bindAsEventListener(this));
this.controls.previous = this.controls.previous.concat(previous);
},
goto_panel: function(){
var elm = null;
if( arguments.length > 1 ){
arguments[0].stop();
elm = arguments[1];
}else{
elm = arguments[0];
}
var id = null;
if (!Object.isString(elm)) {
if( Object.isNumber(elm)){
elm = this.panels[parseInt(elm)];
}
id = elm.identify();
}else{
id = elm;
elm = $(id);
}
if( elm === this.current_panel ){
return;
}
var offsets = this.offsets.get(id);
if( offsets ){
if (this.current_panel) {
this.current_panel.removeClassName(this.options.active_class);
this.controls.gotos.get(this.current_panel.identify()).invoke('removeClassName', this.options.active_class);
}
this.current_panel = elm;
this.current_panel.addClassName(this.options.active_class);
this.controls.gotos.get(this.current_panel.identify()).invoke('addClassName', this.options.active_class);
try {
this.options.animation.call(this, offsets);
}catch(ex){
this.element.scrollTop = offsets.top;
this.element.scrollLeft = offsets.left;
}
}
},
next: function(){
if( arguments.length ){
arguments[0].stop();
}
var index = this.panels.indexOf(this.current_panel) + 1;
index = index > this.panels.length - 1 ? 0 : index;
this.fire('panels:next', {panels: this.panels, index: index});
this.goto_panel(index);
},
previous: function(){
if( arguments.length ){
arguments[0].stop();
}
var index = this.panels.indexOf(this.current_panel) - 1;
index = index < 0 ? this.panels.length - 1 : index;
this.fire('panels:previous', {panels: this.panels, index: index});
this.goto_panel(index);
},
observe: function(){
this.element.observe.apply(this.element, arguments);
},
fire: function(){
this.element.fire.apply(this.element, arguments);
},
destroy: function(){
this.controls.previous.concat(this.controls.next).concat(this.controls.gotos.values().flatten()).invoke('stopObserving');
}
});
Revision: 17541
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at September 9, 2009 10:51 by pdswan
Initial Code
var Panels = Class.create({
initialize: function(){
this.element = $(arguments[0]);
this.element.identify();
if( !this.element ){
throw 'Panels: invalid contianer element'
}
this.element.setStyle({
overflow: 'hidden'
});
this.element.makePositioned();
this.options = Object.extend({
force_horizontal: false,
panel_selector: '.panel',
only_children: false,
start_index: 0,
active_class: 'active',
onInitialized: Prototype.emptyFunction,
animation_scope: 'Panels'+this.element.identify(),
animation: function(offsets){
return new Effect.Scroll( this.element, {
x: offsets.left,
y: offsets.top,
mode: 'absolute',
duration: 1.0,
queue: {scope: this.options.animation_scope}
});
}
}, arguments[1] || {});
this.width_calculated = false;
this.panels =
this.options.only_children ?
this.element.childElements().findAll( function(e){
return e.match(this.options.panel_selector);
}.bind(this) ) :
this.element.select(this.options.panel_selector);
this.controls = {
gotos: $H(),
previous: $A(),
next: $A()
}
this.initialize_controls();
if (this._calculate_width()) {
this._finish();
}
},
_finish: function(){
this._calculate_offsets();
this.goto_panel(this.options.start_index);
this.options.onInitialized.call(this);
},
_calculate_offsets: function(){
this.offsets = $H();
this.panels.each(function(p){
this.offsets.set(p.identify(), p.positionedOffset());
}, this);
},
_calculate_width: function(force){
if( this.options.force_horizontal && (!this.width_calculated || force) ){
if( !this.container ){
// find the largest panel height
this.force_horizontal_height = this.panels.map(function(p){
var position = p.getStyle('position');
p.setStyle({'position': 'absolute'});
var height = p.getHeight();
p.setStyle({'position': position});
return height;
}).max();
this.container = new Element('div').setStyle({overflow: 'hidden', width: '100000px'});
this.panels.each(function(e){
this.container.insert(e.remove().setStyle({'float': 'left'}));
}, this);
this.element.insert(this.container);
this.default_width = this.element.getWidth();
this.force_horizontal_height
}
var temp = new Element('div').setStyle({'float': 'left', 'width': '1px', 'height': '1px'});
this.panels.last().insert({after: temp});
return this._set_width(temp);
}
return true;
},
_set_width: function( elm, finish){
var width = elm.positionedOffset()[0];
/*
* if the scroll height of the container is greater than the maximum panel height, then all of the panels have not yet
* been inserted into the container. or height container height has not been properly computed yet.
*/
if( (this.default_width && width <= this.default_width) || (this.force_horizontal_height && this.container.scrollHeight > this.force_horizontal_height)){
this._set_width.bind(this, elm, 1).defer();
return false;
}else{
this.container.setStyle({width: width + 'px'});
this.width_calculated = true;
elm.remove();
if( finish ){
this._finish();
}else{
return true;
}
}
},
initialize_controls: function(){
var find = arguments[0] ? $(arguments[0]).select : $$;
this.panels.each(function(p){
var gotos = find('a[href=#' + p.identify() + ']').invoke('observe', 'click', this.goto_panel.bindAsEventListener(this, p));
this.controls.gotos.set(p.identify(), (this.controls.gotos.get(p.identify) || $A()).concat(gotos));
}, this);
var next = $$('a[href=#next].' + this.element.identify() + '_control[href=#next]').invoke('observe', 'click', this.next.bindAsEventListener(this));
this.controls.next = this.controls.next.concat(next);
var previous = $$('a.' + this.element.identify() + '_control[href=#previous]').invoke('observe', 'click', this.previous.bindAsEventListener(this));
this.controls.previous = this.controls.previous.concat(previous);
},
goto_panel: function(){
var elm = null;
if( arguments.length > 1 ){
arguments[0].stop();
elm = arguments[1];
}else{
elm = arguments[0];
}
var id = null;
if (!Object.isString(elm)) {
if( Object.isNumber(elm)){
elm = this.panels[parseInt(elm)];
}
id = elm.identify();
}else{
id = elm;
elm = $(id);
}
if( elm === this.current_panel ){
return;
}
var offsets = this.offsets.get(id);
if( offsets ){
if (this.current_panel) {
this.current_panel.removeClassName(this.options.active_class);
this.controls.gotos.get(this.current_panel.identify()).invoke('removeClassName', this.options.active_class);
}
this.current_panel = elm;
this.current_panel.addClassName(this.options.active_class);
this.controls.gotos.get(this.current_panel.identify()).invoke('addClassName', this.options.active_class);
try {
this.options.animation.call(this, offsets);
}catch(ex){
this.element.scrollTop = offsets.top;
this.element.scrollLeft = offsets.left;
}
}
},
next: function(){
if( arguments.length ){
arguments[0].stop();
}
var index = this.panels.indexOf(this.current_panel) + 1;
index = index > this.panels.length - 1 ? 0 : index;
this.fire('panels:next', {panels: this.panels, index: index});
this.goto_panel(index);
},
previous: function(){
if( arguments.length ){
arguments[0].stop();
}
var index = this.panels.indexOf(this.current_panel) - 1;
index = index < 0 ? this.panels.length - 1 : index;
this.fire('panels:previous', {panels: this.panels, index: index});
this.goto_panel(index);
},
observe: function(){
this.element.observe.apply(this.element, arguments);
},
fire: function(){
this.element.fire.apply(this.element, arguments);
},
destroy: function(){
this.controls.previous.concat(this.controls.next).concat(this.controls.gotos.values().flatten()).invoke('stopObserving');
}
});
Initial URL
Initial Description
Initial Title
Prototype.js Panels
Initial Tags
Initial Language
JavaScript