gumby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Gumby SkipLink
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ function SkipLink($el) {
9
+ this.$el = $el;
10
+ this.targetPos = 0;
11
+ this.duration = 0;
12
+ this.offset = false;
13
+ this.easing = '';
14
+ this.update = false;
15
+
16
+ // set up module based on attributes
17
+ this.setup();
18
+
19
+ var scope = this;
20
+
21
+ // skip to target element on click or trigger of gumby.skipTo event
22
+ this.$el.on(Gumby.click+' gumby.skip', function(e) {
23
+
24
+ e.stopImmediatePropagation();
25
+ e.preventDefault();
26
+
27
+ // calculate target on each click if update var set to true
28
+ if(scope.update) {
29
+ scope.calculateTarget(scope.skipTo);
30
+
31
+ // skip straight to target
32
+ } else {
33
+ scope.skipTo();
34
+ }
35
+ }).on('gumby.initialize', function() {
36
+ scope.setup();
37
+ });
38
+ }
39
+
40
+ // set up module based on attributes
41
+ SkipLink.prototype.setup = function() {
42
+ this.duration = Number(Gumby.selectAttr.apply(this.$el, ['duration'])) || 200;
43
+ this.offset = Gumby.selectAttr.apply(this.$el, ['offset']) || false;
44
+ this.easing = Gumby.selectAttr.apply(this.$el, ['easing']) || 'swing';
45
+ this.update = Gumby.selectAttr.apply(this.$el, ['update']) ? true : false;
46
+
47
+ this.calculateTarget();
48
+ };
49
+
50
+ // calculate target px point to skip to
51
+ SkipLink.prototype.calculateTarget = function(cb) {
52
+
53
+ var scope = this,
54
+ target = Gumby.selectAttr.apply(this.$el, ['goto']),
55
+ $target;
56
+
57
+ // 'top' specified so target is 0px
58
+ if(target == 'top') {
59
+ this.targetPos = 0;
60
+
61
+ // px point specified
62
+ } else if($.isNumeric(target)) {
63
+ this.targetPos = Number(target);
64
+ } else {
65
+
66
+ // check for element with target as selector
67
+ $target = $(target);
68
+
69
+ // target does not exist, we need a target
70
+ if(!$target) {
71
+ return false;
72
+ }
73
+
74
+ this.targetPos = $target.offset().top;
75
+ }
76
+
77
+ if(cb) {
78
+ cb.apply(this);
79
+ }
80
+ };
81
+
82
+ // animate body, html scrollTop value to target px point
83
+ SkipLink.prototype.skipTo = function() {
84
+ var scope = this;
85
+
86
+ // slide to position of target
87
+ $('html,body').animate({
88
+ 'scrollTop' : this.calculateOffset()
89
+ }, this.duration, this.easing).promise().done(function() {
90
+ scope.$el.trigger('gumby.onComplete');
91
+ });
92
+ };
93
+
94
+ // calculate offset with current target point
95
+ SkipLink.prototype.calculateOffset = function() {
96
+ // no offset so return target here
97
+ if(!this.offset) {
98
+ return this.targetPos;
99
+ }
100
+
101
+ // negative / positive
102
+ var op = this.offset.substr(0, 1),
103
+ off = Number(this.offset.substr(1, this.offset.length));
104
+
105
+ // subtract offset from target position
106
+ if(op === '-') {
107
+ return this.targetPos - off;
108
+ // add offset to target position
109
+ } else if(op === '+') {
110
+ return this.targetPos + off;
111
+ }
112
+ };
113
+
114
+ // add initialisation
115
+ Gumby.addInitalisation('skiplinks', function(all) {
116
+ $('.skiplink > a, .skip').each(function() {
117
+ var $this = $(this);
118
+
119
+ // this element has already been initialized
120
+ // and we're only initializing new modules
121
+ if($this.data('isSkipLink') && !all) {
122
+ return true;
123
+
124
+ // this element has already been initialized
125
+ // and we need to reinitialize it
126
+ } else if($this.data('isSkipLink') && all) {
127
+ $this.trigger('gumby.initialize');
128
+ return true;
129
+ }
130
+
131
+ // mark element as initialized
132
+ $this.data('isSkipLink', true);
133
+ new SkipLink($this);
134
+ });
135
+ });
136
+
137
+ // register UI module
138
+ Gumby.UIModule({
139
+ module: 'skiplink',
140
+ events: ['onComplete', 'skip'],
141
+ init: function() {
142
+ Gumby.initialize('skiplinks');
143
+ }
144
+ });
145
+ }();
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Gumby Tabs
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ function Tabs($el) {
9
+
10
+ this.$el = $el;
11
+ this.$nav = this.$el.find('ul.tab-nav > li');
12
+ this.$content = this.$el.find('.tab-content');
13
+
14
+ var scope = this;
15
+
16
+ // listen for click event on tab nav and custom gumby set event
17
+ this.$nav.children('a').on(Gumby.click, function(e) {
18
+ e.stopImmediatePropagation();
19
+ e.preventDefault();
20
+ scope.click($(this));
21
+ });
22
+
23
+ // listen for gumby.set value for dynamically set tabs
24
+ this.$el.on('gumby.set', function(e, index) {
25
+ scope.set(e, index);
26
+ });
27
+ }
28
+
29
+ // handle tab nav click event
30
+ Tabs.prototype.click = function($this) {
31
+ // index of item to activate
32
+ var index = $this.parent().index();
33
+
34
+ // deactivate other tab navigation and content
35
+ this.$nav.add(this.$content).removeClass('active');
36
+
37
+ // activate this tab nav link and content
38
+ this.$nav.eq(index).add(this.$content.eq(index)).addClass('active');
39
+
40
+ // trigger gumby.change event and pass current active tab index
41
+ this.$el.trigger('gumby.onChange', index);
42
+ };
43
+
44
+ // set specific tab
45
+ Tabs.prototype.set = function(e, index) {
46
+ this.$nav.eq(index).find('a').trigger(Gumby.click);
47
+ };
48
+
49
+ // add initialisation
50
+ Gumby.addInitalisation('tabs', function() {
51
+ $('.tabs').each(function() {
52
+ var $this = $(this);
53
+ // this element has already been initialized
54
+ if($this.data('isTabs')) {
55
+ return true;
56
+ }
57
+ // mark element as initialized
58
+ $this.data('isTabs', true);
59
+ new Tabs($this);
60
+ });
61
+ });
62
+
63
+ // register UI module
64
+ Gumby.UIModule({
65
+ module: 'tabs',
66
+ events: ['onChange', 'set'],
67
+ init: function() {
68
+ Gumby.initialize('tabs');
69
+ }
70
+ });
71
+ }();
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Gumby Toggles/Switches
3
+ */
4
+ !function() {
5
+
6
+ 'use strict';
7
+
8
+ // Toggle constructor
9
+ function Toggle($el) {
10
+ this.$el = $($el);
11
+ this.targets = [];
12
+ this.on = '';
13
+
14
+ if(this.$el.length) {
15
+ this.init();
16
+ }
17
+ }
18
+
19
+ // Switch constructor
20
+ function Switch($el) {
21
+ this.$el = $($el);
22
+ this.targets = [];
23
+ this.on = '';
24
+
25
+ if(this.$el.length) {
26
+ this.init();
27
+ }
28
+ }
29
+
30
+ // intialise toggles, switches will inherit method
31
+ Toggle.prototype.init = function() {
32
+ var scope = this;
33
+
34
+ // set up module based on attributes
35
+ this.setup();
36
+
37
+ // bind to specified event and trigger
38
+ this.$el.on(this.on, function(e) {
39
+ // stop propagation
40
+ e.stopImmediatePropagation();
41
+
42
+ // only disable default if <a>
43
+ if($(this).prop('tagName') === 'A') {
44
+ e.preventDefault();
45
+ }
46
+
47
+ scope.trigger(scope.triggered);
48
+
49
+ // listen for gumby.trigger to dynamically trigger toggle/switch
50
+ }).on('gumby.trigger', function() {
51
+ scope.trigger(scope.triggered);
52
+ // re-initialize module
53
+ }).on('gumby.initialize', function() {
54
+ scope.setup();
55
+ });
56
+ };
57
+
58
+ // set up module based on attributes
59
+ Toggle.prototype.setup = function() {
60
+ this.targets = this.parseTargets();
61
+ this.on = Gumby.selectAttr.apply(this.$el, ['on']) || Gumby.click;
62
+ this.className = Gumby.selectAttr.apply(this.$el, ['classname']) || 'active';
63
+ };
64
+
65
+ // parse data-for attribute, switches will inherit method
66
+ Toggle.prototype.parseTargets = function() {
67
+ var targetStr = Gumby.selectAttr.apply(this.$el, ['trigger']),
68
+ secondaryTargets = 0,
69
+ targets = [];
70
+
71
+ // no targets so return false
72
+ if(!targetStr) {
73
+ return false;
74
+ }
75
+
76
+ secondaryTargets = targetStr.indexOf('|');
77
+
78
+ // no secondary targets specified so return single target
79
+ if(secondaryTargets === -1) {
80
+ return [$(targetStr)];
81
+ }
82
+
83
+ // return array of both targets, split and return 0, 1
84
+ targets = targetStr.split('|');
85
+ return targets.length > 1 ? [$(targets[0]), $(targets[1])] : [$(targets[0])];
86
+ };
87
+
88
+ // call triggered event and pass target data
89
+ Toggle.prototype.triggered = function() {
90
+ // trigger gumby.onTrigger event and pass array of target status data
91
+ this.$el.trigger('gumby.onTrigger', [this.$el.hasClass(this.className)]);
92
+ };
93
+
94
+ // Switch object inherits from Toggle
95
+ Switch.prototype = new Toggle();
96
+
97
+ // Toggle specific trigger method
98
+ Toggle.prototype.trigger = function(cb) {
99
+ // no targets just toggle active class on toggle
100
+ if(!this.targets) {
101
+ this.$el.toggleClass(this.className);
102
+
103
+ // combine single target with toggle and toggle active class
104
+ } else if(this.targets.length == 1) {
105
+ this.$el.add(this.targets[0]).toggleClass(this.className);
106
+
107
+ // if two targets check active state of first
108
+ // always combine toggle and first target
109
+ } else if(this.targets.length > 1) {
110
+ if(this.targets[0].hasClass(this.className)) {
111
+ this.$el.add(this.targets[0]).removeClass(this.className);
112
+ this.targets[1].addClass(this.className);
113
+ } else {
114
+ this.targets[1].removeClass(this.className);
115
+ this.$el.add(this.targets[0]).addClass(this.className);
116
+ }
117
+ }
118
+
119
+ // call event handler here, applying scope of object Switch/Toggle
120
+ if(cb && typeof cb === 'function') {
121
+ cb.apply(this);
122
+ }
123
+ };
124
+
125
+ // Switch specific trigger method
126
+ Switch.prototype.trigger = function(cb) {
127
+ // no targets just add active class to switch
128
+ if(!this.targets) {
129
+ this.$el.addClass(this.className);
130
+
131
+ // combine single target with switch and add active class
132
+ } else if(this.targets.length == 1) {
133
+ this.$el.add(this.targets[0]).addClass(this.className);
134
+
135
+ // if two targets check active state of first
136
+ // always combine switch and first target
137
+ } else if(this.targets.length > 1) {
138
+ this.$el.add(this.targets[0]).addClass(this.className);
139
+ this.targets[1].removeClass(this.className);
140
+ }
141
+
142
+ // call event handler here, applying scope of object Switch/Toggle
143
+ if(cb && typeof cb === 'function') {
144
+ cb.apply(this);
145
+ }
146
+ };
147
+
148
+ // add toggle initialisation
149
+ Gumby.addInitalisation('toggles', function(all) {
150
+ $('.toggle').each(function() {
151
+ var $this = $(this);
152
+
153
+ // this element has already been initialized
154
+ // and we're only initializing new modules
155
+ if($this.data('isToggle') && !all) {
156
+ return true;
157
+
158
+ // this element has already been initialized
159
+ // and we need to reinitialize it
160
+ } else if($this.data('isToggle') && all) {
161
+ $this.trigger('gumby.initialize');
162
+ }
163
+
164
+ // mark element as initialized
165
+ $this.data('isToggle', true);
166
+ new Toggle($this);
167
+ });
168
+ });
169
+
170
+ // add switches initialisation
171
+ Gumby.addInitalisation('switches', function(all) {
172
+ $('.switch').each(function() {
173
+ var $this = $(this);
174
+
175
+ // this element has already been initialized
176
+ // and we're only initializing new modules
177
+ if($this.data('isSwitch') && !all) {
178
+ return true;
179
+
180
+ // this element has already been initialized
181
+ // and we need to reinitialize it
182
+ } else if($this.data('isSwitch') && all) {
183
+ $this.trigger('gumby.initialize');
184
+ return true;
185
+ }
186
+
187
+ // mark element as initialized
188
+ $this.data('isSwitch', true);
189
+ new Switch($this);
190
+ });
191
+ });
192
+
193
+ // register UI module
194
+ Gumby.UIModule({
195
+ module: 'toggleswitch',
196
+ events: ['trigger', 'onTrigger'],
197
+ init: function() {
198
+ // Run initialize methods
199
+ Gumby.initialize('switches');
200
+ Gumby.initialize('toggles');
201
+ }
202
+ });
203
+ }();
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Gumby jQuery Validation Plugin
3
+ */
4
+ !function($) {
5
+
6
+ 'use strict';
7
+
8
+ function Validation($this, req) {
9
+
10
+ // input and holder .field
11
+ this.$this = $this;
12
+ this.$field = this.$this.parents('.field');
13
+
14
+ // supplied validation function with default length check
15
+ this.req = req || function() {
16
+ return !!this.$this.val().length;
17
+ };
18
+
19
+ // reference to this class
20
+ var scope = this;
21
+
22
+ // checkboxes and radio buttons use gumby.onChange event to validate
23
+ if(this.$this.is('[type=checkbox], [type=radio]')) {
24
+ this.$field = this.$this.parent('label');
25
+ this.$field.on('gumby.onChange', function() {
26
+ scope.validate();
27
+ });
28
+
29
+ // selects validate on change
30
+ } else if(this.$this.is('select')) {
31
+ this.$field = this.$this.parents('.picker');
32
+ this.$field.on('change', function() {
33
+ scope.validate();
34
+ });
35
+
36
+ // others (text input, textarea) use blur
37
+ } else {
38
+ this.$this.on('blur', function(e) {
39
+ // ignore tab
40
+ if(e.which !== 9) {
41
+ scope.validate();
42
+ }
43
+ });
44
+ }
45
+ }
46
+
47
+ // validate field
48
+ Validation.prototype.validate = function() {
49
+
50
+ var result = this.req(this.$this);
51
+
52
+ // failed
53
+ if(!result) {
54
+ this.$field.removeClass('success').addClass('danger');
55
+
56
+ // passed
57
+ } else {
58
+ //} else if(this.$field.hasClass('danger')) {
59
+ this.$field.removeClass('danger').addClass('success');
60
+ }
61
+
62
+ return result;
63
+ };
64
+
65
+ // jQuery plugin definition
66
+ $.fn.validation = function(options) {
67
+
68
+ var // extend params with defaults
69
+ settings = $.extend({
70
+ submit : false,
71
+ fail: false,
72
+ required : []
73
+ }, options),
74
+ // store validation objects
75
+ validations = [];
76
+
77
+ // init each form plugin is called on
78
+ return this.each(function() {
79
+
80
+ // no required fields so plugin is pointless
81
+ if(!settings.required.length) {
82
+ return false;
83
+ }
84
+
85
+ var $this = $(this),
86
+ reqLength = settings.required.length,
87
+ i;
88
+
89
+ // loop round each required field and instantiate new validation object
90
+ for(i = 0; i < reqLength; i++) {
91
+ validations.push(new Validation(
92
+ $this.find('[name="'+settings.required[i].name+'"]'),
93
+ settings.required[i].validate || false
94
+ ));
95
+ }
96
+
97
+ // hijack submit event
98
+ $this.on('submit', function(e) {
99
+
100
+ // reference to whole form pass/fail
101
+ var failed = false;
102
+
103
+ // if no passed attribute found we should halt form submit
104
+ if(!$this.data('passed')) {
105
+ e.preventDefault();
106
+
107
+ // loop round validation objects and validate each
108
+ var reqLength = validations.length, i;
109
+ for(i = 0; i < reqLength; i++) {
110
+ if(!validations[i].validate()) {
111
+ failed = true;
112
+ }
113
+ }
114
+
115
+ // passed
116
+ if(!failed) {
117
+ // if submit method present call that otherwise submit form
118
+ if(settings.submit && typeof settings.submit === 'function') {
119
+ settings.submit($this.serializeArray());
120
+ return;
121
+ }
122
+
123
+ // store passed bool and re-submit
124
+ $this.data('passed', true).submit();
125
+
126
+ // failed
127
+ } else {
128
+ // call fail method if present
129
+ if(settings.fail && typeof settings.fail === 'function') {
130
+ settings.fail();
131
+ return;
132
+ }
133
+ }
134
+ }
135
+ });
136
+ });
137
+ };
138
+ }(jQuery);