Permalink
Browse files

Adding TabSwapper.Hash

  • Loading branch information...
1 parent 483a1d4 commit 4a89c1aa0774b9049128080e647cdd69e42736ed @anutron committed May 5, 2013
Showing with 118 additions and 13 deletions.
  1. +12 −0 Docs/Layout/TabSwapper.Hash.md
  2. +10 −13 Source/Behaviors/Behavior.Tabs.js
  3. +95 −0 Source/Layout/TabSwapper.Hash.js
  4. +1 −0 package.yml
@@ -0,0 +1,12 @@
+Class: TabSwapper.Hash {#TabSwapper.Hash}
+===============================
+
+Extends the TabSwapper class to store tab selection as a url querytring in the window.location.hash.
+
+# Extends
+
+Tabswapper
+
+# Options
+
+* hash - the query string in which to store the hash.
@@ -3,7 +3,7 @@
name: Behavior.Tabs
description: Adds a tab interface (TabSwapper instance) for elements with .css-tab_ui. Matched with tab elements that are .tabs and sections that are .tab_sections.
provides: [Behavior.Tabs]
-requires: [Behavior/Behavior, /TabSwapper, More/String.QueryString, More/Object.Extras]
+requires: [Behavior/Behavior, /TabSwapper.Hash]
script: Behavior.Tabs.js
...
@@ -26,19 +26,17 @@ Behavior.addGlobalFilters({
if (tabs.length != sections.length || tabs.length == 0) {
api.fail('warning; sections and sections are not of equal number. tabs: ' + tabs.length + ', sections: ' + sections.length);
}
- var getHash = function(){
- return window.location.hash.substring(1, window.location.hash.length).parseQueryString();
- };
- var ts = new TabSwapper(
+ var ts = new TabSwapper.Hash(
Object.merge(
{
tabs: tabs,
- sections: sections,
- initPanel: api.get('hash') ? getHash()[api.get('hash')] : null
+ sections: sections
},
Object.cleanValues(
api.getAs({
+ initPanel: Number,
+ hash: String,
cookieName: String,
smooth: Boolean,
smoothSize: Boolean,
@@ -51,15 +49,14 @@ Behavior.addGlobalFilters({
)
);
ts.addEvent('active', function(index){
- if (api.get('hash')) {
- var hash = getHash();
- hash[api.get('hash')] = index;
- window.location.hash = Object.cleanValues(Object.toQueryString(hash));
- }
api.fireEvent('layout:display', sections[0].getParent());
});
element.store('TabSwapper', ts);
+ api.onCleanup(function(){
+ ts.destroy();
+ element.eliminate('TabSwapper');
+ });
return ts;
}
}
-});
+});
@@ -0,0 +1,95 @@
+/*
+---
+
+name: TabSwapper.Hash
+
+description: Stores tab selection in the window.hash
+
+license: MIT-Style License
+
+requires: [/TabSwapper, More/String.QueryString, More/Object.Extras]
+
+provides: TabSwapper.Hash
+
+...
+*/
+
+var getHash = function(){
+ return window.location.hash.substring(1, window.location.hash.length).parseQueryString();
+};
+
+TabSwapper.Hash = new Class({
+ Extends: TabSwapper,
+ options: {
+ hash: null // the hash value to store the state in
+ },
+ initialize: function(options){
+ this.setOptions(options);
+ // delete the hash option on startup so that the call to show(0) doesn't change the location hash
+ if (this.options.hash){
+ hash = this.options.hash;
+ delete options.hash;
+ delete this.options.hash;
+ }
+ this.parent(options);
+ if (hash){
+ // put the hash back
+ this.options.hash = hash;
+ this.bound = {
+ showByHash: this.showByHash.bind(this)
+ };
+ // watch hashchange for changes
+ window.addEvent('hashchange', this.bound.showByHash);
+ this.showByHash();
+ }
+ },
+ // shows a section based on the window location hash value
+ showByHash: function(){
+ var i = this.getIndexByHash();
+ if (i !== null) this.show(i);
+ return this;
+ },
+ // gets the index to show based on an elementID
+ // returns NULL if nothing is found
+ getIndexById: function(id){
+ var target = document.id(id);
+ if (target && this.tabs.contains(target)) return this.tabs.indexOf(target);
+ else if (target && this.sections.contains(target)) return this.sections.indexOf(target);
+ return null;
+ },
+ // gets the hash value and returns the index to be shown
+ // returns UNDEFINED if there was no hash value
+ // returns NULL if no element was found and the value wasn't an int already
+ // NOTE: hash value may be an int or a string; int if the tab/section had no id
+ getIndexByHash: function(){
+ var hash = getHash();
+ if (!hash) return this;
+ var value = hash[this.options.hash];
+ if (isNaN(value.toInt())){
+ var i = this.getIndexById(value);
+ if (i !== null) value = i;
+ else return null;
+ }
+ return value;
+ },
+ // for optimization purposes, we store the sections, the base class doesn't do this
+ addTab: function(tab, section, clicker, index){
+ this.parent.apply(this, arguments);
+ this.sections[this.tabs.indexOf(tab)] = section;
+ },
+ // on show, update the hash
+ show: function(i){
+ this.parent.apply(this, arguments);
+ if (this.options.hash) {
+ var hash = getHash();
+ hash[this.options.hash] = this.tabs[i].get('id') || this.sections[i].get('id') || i;
+ window.location.hash = Object.cleanValues(Object.toQueryString(hash));
+ }
+ },
+ destroy: function(){
+ window.removeEvent('hashchange', this.bound.showByHash);
+ this.tabs.removeEvents();
+ this.tabs = null;
+ this.sections = null;
+ }
+});
View
@@ -29,6 +29,7 @@ sources: [
Source/Layout/MooScroller.js,
Source/Layout/MultipleOpenAccordion.js,
Source/Layout/TabSwapper.js,
+ Source/Layout/TabSwapper.Hash.js,
Source/UI/StickyWin.js,
Source/UI/StickyWin.Ajax.js,
Source/UI/StickyWin.Alert.js,

0 comments on commit 4a89c1a

Please sign in to comment.