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 this.className = ''; 14 this.self = false; 15 16 if(this.$el.length) { 17 Gumby.debug('Initializing Toggle', $el); 18 this.init(); 19 } 20 } 21 22 // Switch constructor 23 function Switch($el) { 24 this.$el = $($el); 25 this.targets = []; 26 this.on = ''; 27 this.className = ''; 28 this.self = false; 29 30 if(this.$el.length) { 31 Gumby.debug('Initializing Switch', $el); 32 this.init(); 33 } 34 } 35 36 // intialise toggles, switches will inherit method 37 Toggle.prototype.init = function() { 38 var scope = this; 39 40 // set up module based on attributes 41 this.setup(); 42 43 // bind to specified event and trigger 44 this.$el.on(this.on, function(e) { 45 e.preventDefault(); 46 scope.trigger(scope.triggered); 47 48 // listen for gumby.trigger to dynamically trigger toggle/switch 49 }).on('gumby.trigger', function() { 50 Gumby.debug('Trigger event triggered', scope.$el); 51 scope.trigger(scope.triggered); 52 // re-initialize module 53 }).on('gumby.initialize', function() { 54 Gumby.debug('Re-initializing '+scope.constructor, $el); 55 scope.setup(); 56 }); 57 }; 58 59 // set up module based on attributes 60 Toggle.prototype.setup = function() { 61 this.targets = this.parseTargets(); 62 this.on = Gumby.selectAttr.apply(this.$el, ['on']) || Gumby.click; 63 this.className = Gumby.selectAttr.apply(this.$el, ['classname']) || 'active'; 64 this.self = Gumby.selectAttr.apply(this.$el, ['self']) === 'false'; 65 }; 66 67 // parse data-for attribute, switches will inherit method 68 Toggle.prototype.parseTargets = function() { 69 var targetStr = Gumby.selectAttr.apply(this.$el, ['trigger']), 70 secondaryTargets = 0, 71 targets = []; 72 73 // no targets so return false 74 if(!targetStr) { 75 return false; 76 } 77 78 secondaryTargets = targetStr.indexOf('|'); 79 80 // no secondary targets specified so return single target 81 if(secondaryTargets === -1) { 82 if(!this.checkTargets([targetStr])) { 83 return false; 84 } 85 return [$(targetStr)]; 86 } 87 88 // return array of both targets, split and return 0, 1 89 targets = targetStr.split('|'); 90 if(!this.checkTargets(targets)) { 91 return false; 92 } 93 return targets.length > 1 ? [$(targets[0]), $(targets[1])] : [$(targets[0])]; 94 }; 95 96 Toggle.prototype.checkTargets = function(targets) { 97 var i = 0; 98 99 for(i; i < targets.length; i++) { 100 if(targets[i] && !$(targets[i]).length) { 101 Gumby.error('Cannot find '+this.constructor.name+' target: '+targets[i]); 102 return false; 103 } 104 } 105 106 return true; 107 }; 108 109 // call triggered event and pass target data 110 Toggle.prototype.triggered = function() { 111 // trigger gumby.onTrigger event and pass array of target status data 112 Gumby.debug('Triggering onTrigger event', this.$el); 113 this.$el.trigger('gumby.onTrigger', [this.$el.hasClass(this.className)]); 114 }; 115 116 // Switch object inherits from Toggle 117 Switch.prototype = new Toggle(); 118 Switch.prototype.constructor = Switch; 119 120 // Toggle specific trigger method 121 Toggle.prototype.trigger = function(cb) { 122 123 Gumby.debug('Triggering Toggle', this.$el); 124 125 var $target; 126 127 // no targets just toggle active class on toggle 128 if(!this.targets) { 129 this.$el.toggleClass(this.className); 130 131 // combine single target with toggle and toggle active class 132 } else if(this.targets.length == 1) { 133 this.$el.add(this.targets[0]).toggleClass(this.className); 134 135 // if two targets check active state of first 136 // always combine toggle and first target 137 } else if(this.targets.length > 1) { 138 if(this.targets[0].hasClass(this.className)) { 139 $target = this.targets[0]; 140 141 // add this element to it unless gumby-self set 142 if(!this.self) { 143 $target = $target.add(this.$el); 144 } 145 146 $target.removeClass(this.className); 147 this.targets[1].addClass(this.className); 148 } else { 149 $target = this.targets[0]; 150 151 // add this element to it unless gumby-self set 152 if(!this.self) { 153 $target = $target.add(this.$el); 154 } 155 156 $target.addClass(this.className); 157 this.targets[1].removeClass(this.className); 158 } 159 } 160 161 // call event handler here, applying scope of object Switch/Toggle 162 if(cb && typeof cb === 'function') { 163 cb.apply(this); 164 } 165 }; 166 167 // Switch specific trigger method 168 Switch.prototype.trigger = function(cb) { 169 170 Gumby.debug('Triggering Switch', this.$el); 171 172 var $target; 173 174 // no targets just add active class to switch 175 if(!this.targets) { 176 this.$el.addClass(this.className); 177 178 // combine single target with switch and add active class 179 } else if(this.targets.length == 1) { 180 $target = this.targets[0]; 181 182 // add this element to it unless gumby-self set 183 if(!this.self) { 184 $target = $target.add(this.$el); 185 } 186 187 $target.addClass(this.className); 188 189 // if two targets check active state of first 190 // always combine switch and first target 191 } else if(this.targets.length > 1) { 192 $target = this.targets[0]; 193 194 // add this element to it unless gumby-self set 195 if(!this.self) { 196 $target = $target.add(this.$el); 197 } 198 199 $target.addClass(this.className); 200 this.targets[1].removeClass(this.className); 201 } 202 203 // call event handler here, applying scope of object Switch/Toggle 204 if(cb && typeof cb === 'function') { 205 cb.apply(this); 206 } 207 }; 208 209 // add toggle initialisation 210 Gumby.addInitalisation('toggles', function(all) { 211 $('.toggle').each(function() { 212 var $this = $(this); 213 214 // this element has already been initialized 215 // and we're only initializing new modules 216 if($this.data('isToggle') && !all) { 217 return true; 218 219 // this element has already been initialized 220 // and we need to reinitialize it 221 } else if($this.data('isToggle') && all) { 222 $this.trigger('gumby.initialize'); 223 } 224 225 // mark element as initialized 226 $this.data('isToggle', true); 227 new Toggle($this); 228 }); 229 }); 230 231 // add switches initialisation 232 Gumby.addInitalisation('switches', function(all) { 233 $('.switch').each(function() { 234 var $this = $(this); 235 236 // this element has already been initialized 237 // and we're only initializing new modules 238 if($this.data('isSwitch') && !all) { 239 return true; 240 241 // this element has already been initialized 242 // and we need to reinitialize it 243 } else if($this.data('isSwitch') && all) { 244 $this.trigger('gumby.initialize'); 245 return true; 246 } 247 248 // mark element as initialized 249 $this.data('isSwitch', true); 250 new Switch($this); 251 }); 252 }); 253 254 // register UI module 255 Gumby.UIModule({ 256 module: 'toggleswitch', 257 events: ['initialize', 'trigger', 'onTrigger'], 258 init: function() { 259 // Run initialize methods 260 Gumby.initialize('switches'); 261 Gumby.initialize('toggles'); 262 } 263 }); 264}(jQuery); 265