From ad6e5733d5b6cea6a1e8ccde859db5e0bfe7cf6d Mon Sep 17 00:00:00 2001 From: Radomir Dopieralski Date: Thu, 22 May 2014 15:18:54 +0200 Subject: [PATCH] Version 1.0.0 of JQuery.Bootstrap.Wizard --- .gitignore | 9 + MANIFEST.in | 8 + README.txt | 14 + setup.py | 27 ++ xstatic/__init__.py | 1 + xstatic/pkg/__init__.py | 1 + .../pkg/jquery_bootstrap_wizard/__init__.py | 49 ++++ .../data/jquery.bootstrap.wizard.js | 255 ++++++++++++++++++ 8 files changed, 364 insertions(+) create mode 100644 .gitignore create mode 100644 MANIFEST.in create mode 100644 README.txt create mode 100644 setup.py create mode 100644 xstatic/__init__.py create mode 100644 xstatic/pkg/__init__.py create mode 100644 xstatic/pkg/jquery_bootstrap_wizard/__init__.py create mode 100755 xstatic/pkg/jquery_bootstrap_wizard/data/jquery.bootstrap.wizard.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b3085b8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.pyc +*.sw? +*.sqlite3 +.DS_STORE +*.egg-info +.venv +.tox +build +dist diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..7b6b822 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,8 @@ +include README.txt +recursive-include xstatic/pkg/jquery_bootstrap_wizard * + +global-exclude *.pyc +global-exclude *.pyo +global-exclude *.orig +global-exclude *.rej + diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..ee108b1 --- /dev/null +++ b/README.txt @@ -0,0 +1,14 @@ +XStatic-JQuery.Bootstrap.Wizard +-------------- + +JQuery.Bootstrap.Wizard JavaScript library packaged for setuptools (easy_install) / pip. + + +This package is intended to be used by **any** project that needs these files. + +It intentionally does **not** provide any extra code except some metadata +**nor** has any extra requirements. You MAY use some minimal support code from +the XStatic base package, if you like. + +You can find more info about the xstatic packaging way in the package `XStatic`. + diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..01890b1 --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from xstatic.pkg import jquery_bootstrap_wizard as xs + +# The README.txt file should be written in reST so that PyPI can use +# it to generate your project's PyPI page. +long_description = open('README.txt').read() + +from setuptools import setup, find_packages + +setup( + name=xs.PACKAGE_NAME, + version=xs.PACKAGE_VERSION, + description=xs.DESCRIPTION, + long_description=long_description, + classifiers=xs.CLASSIFIERS, + keywords=xs.KEYWORDS, + maintainer=xs.MAINTAINER, + maintainer_email=xs.MAINTAINER_EMAIL, + license=xs.LICENSE, + url=xs.HOMEPAGE, + platforms=xs.PLATFORMS, + packages=find_packages(), + namespace_packages=['xstatic', 'xstatic.pkg', ], + include_package_data=True, + zip_safe=False, + install_requires=[], # nothing! :) + # if you like, you MAY use the 'XStatic' package. +) diff --git a/xstatic/__init__.py b/xstatic/__init__.py new file mode 100644 index 0000000..de40ea7 --- /dev/null +++ b/xstatic/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/xstatic/pkg/__init__.py b/xstatic/pkg/__init__.py new file mode 100644 index 0000000..de40ea7 --- /dev/null +++ b/xstatic/pkg/__init__.py @@ -0,0 +1 @@ +__import__('pkg_resources').declare_namespace(__name__) diff --git a/xstatic/pkg/jquery_bootstrap_wizard/__init__.py b/xstatic/pkg/jquery_bootstrap_wizard/__init__.py new file mode 100644 index 0000000..69ad7e5 --- /dev/null +++ b/xstatic/pkg/jquery_bootstrap_wizard/__init__.py @@ -0,0 +1,49 @@ +""" +XStatic resource package + +See package 'XStatic' for documentation and basic tools. +""" + +DISPLAY_NAME = 'JQuery.Bootstrap.Wizard' # official name, upper/lowercase allowed, no spaces +PACKAGE_NAME = 'XStatic-%s' % DISPLAY_NAME # name used for PyPi + +NAME = __name__.split('.')[-1] # package name (e.g. 'foo' or 'foo_bar') + # please use a all-lowercase valid python + # package name + +VERSION = '1.0.0' # version of the packaged files, please use the upstream + # version number +BUILD = '1' # our package build number, so we can release new builds + # with fixes for xstatic stuff. +PACKAGE_VERSION = VERSION + '.' + BUILD # version used for PyPi + +DESCRIPTION = "%s %s (XStatic packaging standard)" % (DISPLAY_NAME, VERSION) + +PLATFORMS = 'any' +CLASSIFIERS = [] +KEYWORDS = '%s xstatic' % NAME + +# XStatic-* package maintainer: +MAINTAINER = 'Radomir Dopieralski' +MAINTAINER_EMAIL = 'openstack@sheep.art.pl' + +# this refers to the project homepage of the stuff we packaged: +HOMEPAGE = 'http://github.com/VinceG/twitter-bootstrap-wizard' + +# this refers to all files: +LICENSE = '(same as %s)' % DISPLAY_NAME + +from os.path import join, dirname +BASE_DIR = join(dirname(__file__), 'data') +# linux package maintainers just can point to their file locations like this: +#BASE_DIR = '/usr/share/javascript/jquery_bootstrap_wizard' + +LOCATIONS = { + # CDN locations (if no public CDN exists, use an empty dict) + # if value is a string, it is a base location, just append relative + # path/filename. if value is a dict, do another lookup using the + # relative path/filename you want. + # your relative path/filenames should usually be without version + # information, because either the base dir/url is exactly for this + # version or the mapping will care for accessing this version. +} diff --git a/xstatic/pkg/jquery_bootstrap_wizard/data/jquery.bootstrap.wizard.js b/xstatic/pkg/jquery_bootstrap_wizard/data/jquery.bootstrap.wizard.js new file mode 100755 index 0000000..fd9ffc0 --- /dev/null +++ b/xstatic/pkg/jquery_bootstrap_wizard/data/jquery.bootstrap.wizard.js @@ -0,0 +1,255 @@ +/*! + * jQuery twitter bootstrap wizard plugin + * Examples and documentation at: http://github.com/VinceG/twitter-bootstrap-wizard + * version 1.0 + * Requires jQuery v1.3.2 or later + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * Authors: Vadim Vincent Gabriel (http://vadimg.com), Jason Gill (www.gilluminate.com) + */ +;(function($) { +var bootstrapWizardCreate = function(element, options) { + var element = $(element); + var obj = this; + + // Merge options with defaults + var $settings = $.extend({}, $.fn.bootstrapWizard.defaults, options); + var $activeTab = null; + var $navigation = null; + + this.rebindClick = function(selector, fn) + { + selector.unbind('click', fn).bind('click', fn); + } + + this.fixNavigationButtons = function() { + // Get the current active tab + if(!$activeTab.length) { + // Select first one + $navigation.find('a:first').tab('show'); + $activeTab = $navigation.find('li:first'); + } + + // See if we're currently in the first/last then disable the previous and last buttons + $($settings.previousSelector, element).toggleClass('disabled', (obj.firstIndex() >= obj.currentIndex())); + $($settings.nextSelector, element).toggleClass('disabled', (obj.currentIndex() >= obj.navigationLength())); + + // We are unbinding and rebinding to ensure single firing and no double-click errors + obj.rebindClick($($settings.nextSelector, element), obj.next); + obj.rebindClick($($settings.previousSelector, element), obj.previous); + obj.rebindClick($($settings.lastSelector, element), obj.last); + obj.rebindClick($($settings.firstSelector, element), obj.first); + + if($settings.onTabShow && typeof $settings.onTabShow === 'function' && $settings.onTabShow($activeTab, $navigation, obj.currentIndex())===false){ + return false; + } + }; + + this.next = function(e) { + + // If we clicked the last then dont activate this + if(element.hasClass('last')) { + return false; + } + + if($settings.onNext && typeof $settings.onNext === 'function' && $settings.onNext($activeTab, $navigation, obj.nextIndex())===false){ + return false; + } + + // Did we click the last button + $index = obj.nextIndex(); + if($index > obj.navigationLength()) { + } else { + $navigation.find('li:eq('+$index+') a').tab('show'); + } + }; + + this.previous = function(e) { + + // If we clicked the first then dont activate this + if(element.hasClass('first')) { + return false; + } + + if($settings.onPrevious && typeof $settings.onPrevious === 'function' && $settings.onPrevious($activeTab, $navigation, obj.previousIndex())===false){ + return false; + } + + $index = obj.previousIndex(); + if($index < 0) { + } else { + $navigation.find('li:eq('+$index+') a').tab('show'); + } + }; + + this.first = function(e) { + if($settings.onFirst && typeof $settings.onFirst === 'function' && $settings.onFirst($activeTab, $navigation, obj.firstIndex())===false){ + return false; + } + + // If the element is disabled then we won't do anything + if(element.hasClass('disabled')) { + return false; + } + $navigation.find('li:eq(0) a').tab('show'); + + }; + this.last = function(e) { + if($settings.onLast && typeof $settings.onLast === 'function' && $settings.onLast($activeTab, $navigation, obj.lastIndex())===false){ + return false; + } + + // If the element is disabled then we won't do anything + if(element.hasClass('disabled')) { + return false; + } + $navigation.find('li:eq('+obj.navigationLength()+') a').tab('show'); + }; + this.currentIndex = function() { + return $navigation.find('li').index($activeTab); + }; + this.firstIndex = function() { + return 0; + }; + this.lastIndex = function() { + return obj.navigationLength(); + }; + this.getIndex = function(e) { + return $navigation.find('li').index(e); + }; + this.nextIndex = function() { + return $navigation.find('li').index($activeTab) + 1; + }; + this.previousIndex = function() { + return $navigation.find('li').index($activeTab) - 1; + }; + this.navigationLength = function() { + return $navigation.find('li').length - 1; + }; + this.activeTab = function() { + return $activeTab; + }; + this.nextTab = function() { + return $navigation.find('li:eq('+(obj.currentIndex()+1)+')').length ? $navigation.find('li:eq('+(obj.currentIndex()+1)+')') : null; + }; + this.previousTab = function() { + if(obj.currentIndex() <= 0) { + return null; + } + return $navigation.find('li:eq('+parseInt(obj.currentIndex()-1)+')'); + }; + this.show = function(index) { + return element.find('li:eq(' + index + ') a').tab('show'); + }; + this.disable = function(index) { + $navigation.find('li:eq('+index+')').addClass('disabled'); + }; + this.enable = function(index) { + $navigation.find('li:eq('+index+')').removeClass('disabled'); + }; + this.hide = function(index) { + $navigation.find('li:eq('+index+')').hide(); + }; + this.display = function(index) { + $navigation.find('li:eq('+index+')').show(); + }; + this.remove = function(args) { + var $index = args[0]; + var $removeTabPane = typeof args[1] != 'undefined' ? args[1] : false; + var $item = $navigation.find('li:eq('+$index+')'); + + // Remove the tab pane first if needed + if($removeTabPane) { + var $href = $item.find('a').attr('href'); + $($href).remove(); + } + + // Remove menu item + $item.remove(); + }; + + $navigation = element.find('ul:first', element); + $activeTab = $navigation.find('li.active', element); + + if(!$navigation.hasClass($settings.tabClass)) { + $navigation.addClass($settings.tabClass); + } + + // Load onInit + if($settings.onInit && typeof $settings.onInit === 'function'){ + $settings.onInit($activeTab, $navigation, 0); + } + + // Load onShow + if($settings.onShow && typeof $settings.onShow === 'function'){ + $settings.onShow($activeTab, $navigation, obj.nextIndex()); + } + + // Work the next/previous buttons + obj.fixNavigationButtons(); + + $('a[data-toggle="tab"]', $navigation).on('click', function (e) { + // Get the index of the clicked tab + var clickedIndex = $navigation.find('li').index($(e.currentTarget).parent('li')); + if($settings.onTabClick && typeof $settings.onTabClick === 'function' && $settings.onTabClick($activeTab, $navigation, obj.currentIndex(), clickedIndex)===false){ + return false; + } + }); + + $('a[data-toggle="tab"]', $navigation).on('shown', function (e) { // use shown instead of show to help prevent double firing + $element = $(e.target).parent(); + var nextTab = $navigation.find('li').index($element); + + // If it's disabled then do not change + if($element.hasClass('disabled')) { + return false; + } + + if($settings.onTabChange && typeof $settings.onTabChange === 'function' && $settings.onTabChange($activeTab, $navigation, obj.currentIndex(), nextTab)===false){ + return false; + } + + $activeTab = $element; // activated tab + obj.fixNavigationButtons(); + }); +}; +$.fn.bootstrapWizard = function(options) { + //expose methods + if (typeof options == 'string') { + var args = Array.prototype.slice.call(arguments, 1) + if(args.length === 1) { + args.toString(); + } + return this.data('bootstrapWizard')[options](args); + } + return this.each(function(index){ + var element = $(this); + // Return early if this element already has a plugin instance + if (element.data('bootstrapWizard')) return; + // pass options to plugin constructor + var wizard = new bootstrapWizardCreate(element, options); + // Store plugin object in this element's data + element.data('bootstrapWizard', wizard); + }); +}; + +// expose options +$.fn.bootstrapWizard.defaults = { + tabClass: 'nav nav-pills', + nextSelector: '.wizard li.next', + previousSelector: '.wizard li.previous', + firstSelector: '.wizard li.first', + lastSelector: '.wizard li.last', + onShow: null, + onInit: null, + onNext: null, + onPrevious: null, + onLast: null, + onFirst: null, + onTabChange: null, + onTabClick: null, + onTabShow: null +}; + +})(jQuery);