diff options
Diffstat (limited to 'js/core/dropdown.js')
| -rwxr-xr-x | js/core/dropdown.js | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/js/core/dropdown.js b/js/core/dropdown.js new file mode 100755 index 0000000..1fa7035 --- /dev/null +++ b/js/core/dropdown.js | |||
| @@ -0,0 +1,525 @@ | |||
| 1 | /*! UIkit 2.26.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ | ||
| 2 | (function(UI) { | ||
| 3 | |||
| 4 | "use strict"; | ||
| 5 | |||
| 6 | var active = false, hoverIdle, flips = { | ||
| 7 | 'x': { | ||
| 8 | "bottom-left" : 'bottom-right', | ||
| 9 | "bottom-right" : 'bottom-left', | ||
| 10 | "bottom-center" : 'bottom-center', | ||
| 11 | "top-left" : 'top-right', | ||
| 12 | "top-right" : 'top-left', | ||
| 13 | "top-center" : 'top-center', | ||
| 14 | "left-top" : 'right-top', | ||
| 15 | "left-bottom" : 'right-bottom', | ||
| 16 | "left-center" : 'right-center', | ||
| 17 | "right-top" : 'left-top', | ||
| 18 | "right-bottom" : 'left-bottom', | ||
| 19 | "right-center" : 'left-center' | ||
| 20 | }, | ||
| 21 | 'y': { | ||
| 22 | "bottom-left" : 'top-left', | ||
| 23 | "bottom-right" : 'top-right', | ||
| 24 | "bottom-center" : 'top-center', | ||
| 25 | "top-left" : 'bottom-left', | ||
| 26 | "top-right" : 'bottom-right', | ||
| 27 | "top-center" : 'bottom-center', | ||
| 28 | "left-top" : 'left-bottom', | ||
| 29 | "left-bottom" : 'left-top', | ||
| 30 | "left-center" : 'left-center', | ||
| 31 | "right-top" : 'right-bottom', | ||
| 32 | "right-bottom" : 'right-top', | ||
| 33 | "right-center" : 'right-center' | ||
| 34 | }, | ||
| 35 | 'xy': { | ||
| 36 | "bottom-left" : 'top-right', | ||
| 37 | "bottom-right" : 'top-left', | ||
| 38 | "bottom-center" : 'top-center', | ||
| 39 | "top-left" : 'bottom-right', | ||
| 40 | "top-right" : 'bottom-left', | ||
| 41 | "top-center" : 'bottom-center', | ||
| 42 | "left-top" : 'right-bottom', | ||
| 43 | "left-bottom" : 'right-top', | ||
| 44 | "left-center" : 'right-center', | ||
| 45 | "right-top" : 'left-bottom', | ||
| 46 | "right-bottom" : 'left-top', | ||
| 47 | "right-center" : 'left-center' | ||
| 48 | } | ||
| 49 | }; | ||
| 50 | |||
| 51 | UI.component('dropdown', { | ||
| 52 | |||
| 53 | defaults: { | ||
| 54 | 'mode' : 'hover', | ||
| 55 | 'pos' : 'bottom-left', | ||
| 56 | 'offset' : 0, | ||
| 57 | 'remaintime' : 800, | ||
| 58 | 'justify' : false, | ||
| 59 | 'boundary' : UI.$win, | ||
| 60 | 'delay' : 0, | ||
| 61 | 'dropdownSelector': '.uk-dropdown,.uk-dropdown-blank', | ||
| 62 | 'hoverDelayIdle' : 250, | ||
| 63 | 'preventflip' : false | ||
| 64 | }, | ||
| 65 | |||
| 66 | remainIdle: false, | ||
| 67 | |||
| 68 | boot: function() { | ||
| 69 | |||
| 70 | var triggerevent = UI.support.touch ? "click" : "mouseenter"; | ||
| 71 | |||
| 72 | // init code | ||
| 73 | UI.$html.on(triggerevent+".dropdown.uikit", "[data-uk-dropdown]", function(e) { | ||
| 74 | |||
| 75 | var ele = UI.$(this); | ||
| 76 | |||
| 77 | if (!ele.data("dropdown")) { | ||
| 78 | |||
| 79 | var dropdown = UI.dropdown(ele, UI.Utils.options(ele.attr("data-uk-dropdown"))); | ||
| 80 | |||
| 81 | if (triggerevent=="click" || (triggerevent=="mouseenter" && dropdown.options.mode=="hover")) { | ||
| 82 | dropdown.element.trigger(triggerevent); | ||
| 83 | } | ||
| 84 | |||
| 85 | if (dropdown.element.find(dropdown.options.dropdownSelector).length) { | ||
| 86 | e.preventDefault(); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | }); | ||
| 90 | }, | ||
| 91 | |||
| 92 | init: function() { | ||
| 93 | |||
| 94 | var $this = this; | ||
| 95 | |||
| 96 | this.dropdown = this.find(this.options.dropdownSelector); | ||
| 97 | this.offsetParent = this.dropdown.parents().filter(function() { | ||
| 98 | return UI.$.inArray(UI.$(this).css('position'), ['relative', 'fixed', 'absolute']) !== -1; | ||
| 99 | }).slice(0,1); | ||
| 100 | |||
| 101 | this.centered = this.dropdown.hasClass('uk-dropdown-center'); | ||
| 102 | this.justified = this.options.justify ? UI.$(this.options.justify) : false; | ||
| 103 | |||
| 104 | this.boundary = UI.$(this.options.boundary); | ||
| 105 | |||
| 106 | if (!this.boundary.length) { | ||
| 107 | this.boundary = UI.$win; | ||
| 108 | } | ||
| 109 | |||
| 110 | // legacy DEPRECATED! | ||
| 111 | if (this.dropdown.hasClass('uk-dropdown-up')) { | ||
| 112 | this.options.pos = 'top-left'; | ||
| 113 | } | ||
| 114 | if (this.dropdown.hasClass('uk-dropdown-flip')) { | ||
| 115 | this.options.pos = this.options.pos.replace('left','right'); | ||
| 116 | } | ||
| 117 | if (this.dropdown.hasClass('uk-dropdown-center')) { | ||
| 118 | this.options.pos = this.options.pos.replace(/(left|right)/,'center'); | ||
| 119 | } | ||
| 120 | //-- end legacy | ||
| 121 | |||
| 122 | // Init ARIA | ||
| 123 | this.element.attr('aria-haspopup', 'true'); | ||
| 124 | this.element.attr('aria-expanded', this.element.hasClass("uk-open")); | ||
| 125 | |||
| 126 | if (this.options.mode == "click" || UI.support.touch) { | ||
| 127 | |||
| 128 | this.on("click.uk.dropdown", function(e) { | ||
| 129 | |||
| 130 | var $target = UI.$(e.target); | ||
| 131 | |||
| 132 | if (!$target.parents($this.options.dropdownSelector).length) { | ||
| 133 | |||
| 134 | if ($target.is("a[href='#']") || $target.parent().is("a[href='#']") || ($this.dropdown.length && !$this.dropdown.is(":visible")) ){ | ||
| 135 | e.preventDefault(); | ||
| 136 | } | ||
| 137 | |||
| 138 | $target.blur(); | ||
| 139 | } | ||
| 140 | |||
| 141 | if (!$this.element.hasClass('uk-open')) { | ||
| 142 | |||
| 143 | $this.show(); | ||
| 144 | |||
| 145 | } else { | ||
| 146 | |||
| 147 | if (!$this.dropdown.find(e.target).length || $target.is(".uk-dropdown-close") || $target.parents(".uk-dropdown-close").length) { | ||
| 148 | $this.hide(); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | }); | ||
| 152 | |||
| 153 | } else { | ||
| 154 | |||
| 155 | this.on("mouseenter", function(e) { | ||
| 156 | |||
| 157 | $this.trigger('pointerenter.uk.dropdown', [$this]); | ||
| 158 | |||
| 159 | if ($this.remainIdle) { | ||
| 160 | clearTimeout($this.remainIdle); | ||
| 161 | } | ||
| 162 | |||
| 163 | if (hoverIdle) { | ||
| 164 | clearTimeout(hoverIdle); | ||
| 165 | } | ||
| 166 | |||
| 167 | if (active && active == $this) { | ||
| 168 | return; | ||
| 169 | } | ||
| 170 | |||
| 171 | // pseudo manuAim | ||
| 172 | if (active && active != $this) { | ||
| 173 | |||
| 174 | hoverIdle = setTimeout(function() { | ||
| 175 | hoverIdle = setTimeout($this.show.bind($this), $this.options.delay); | ||
| 176 | }, $this.options.hoverDelayIdle); | ||
| 177 | |||
| 178 | } else { | ||
| 179 | |||
| 180 | hoverIdle = setTimeout($this.show.bind($this), $this.options.delay); | ||
| 181 | } | ||
| 182 | |||
| 183 | }).on("mouseleave", function() { | ||
| 184 | |||
| 185 | if (hoverIdle) { | ||
| 186 | clearTimeout(hoverIdle); | ||
| 187 | } | ||
| 188 | |||
| 189 | $this.remainIdle = setTimeout(function() { | ||
| 190 | if (active && active == $this) $this.hide(); | ||
| 191 | }, $this.options.remaintime); | ||
| 192 | |||
| 193 | $this.trigger('pointerleave.uk.dropdown', [$this]); | ||
| 194 | |||
| 195 | }).on("click", function(e){ | ||
| 196 | |||
| 197 | var $target = UI.$(e.target); | ||
| 198 | |||
| 199 | if ($this.remainIdle) { | ||
| 200 | clearTimeout($this.remainIdle); | ||
| 201 | } | ||
| 202 | |||
| 203 | if (active && active == $this) { | ||
| 204 | if (!$this.dropdown.find(e.target).length || $target.is(".uk-dropdown-close") || $target.parents(".uk-dropdown-close").length) { | ||
| 205 | $this.hide(); | ||
| 206 | } | ||
| 207 | return; | ||
| 208 | } | ||
| 209 | |||
| 210 | if ($target.is("a[href='#']") || $target.parent().is("a[href='#']")){ | ||
| 211 | e.preventDefault(); | ||
| 212 | } | ||
| 213 | |||
| 214 | $this.show(); | ||
| 215 | }); | ||
| 216 | } | ||
| 217 | }, | ||
| 218 | |||
| 219 | show: function(){ | ||
| 220 | |||
| 221 | UI.$html.off("click.outer.dropdown"); | ||
| 222 | |||
| 223 | if (active && active != this) { | ||
| 224 | active.hide(true); | ||
| 225 | } | ||
| 226 | |||
| 227 | if (hoverIdle) { | ||
| 228 | clearTimeout(hoverIdle); | ||
| 229 | } | ||
| 230 | |||
| 231 | this.trigger('beforeshow.uk.dropdown', [this]); | ||
| 232 | |||
| 233 | this.checkDimensions(); | ||
| 234 | this.element.addClass('uk-open'); | ||
| 235 | |||
| 236 | // Update ARIA | ||
| 237 | this.element.attr('aria-expanded', 'true'); | ||
| 238 | |||
| 239 | this.trigger('show.uk.dropdown', [this]); | ||
| 240 | |||
| 241 | UI.Utils.checkDisplay(this.dropdown, true); | ||
| 242 | active = this; | ||
| 243 | |||
| 244 | this.registerOuterClick(); | ||
| 245 | }, | ||
| 246 | |||
| 247 | hide: function(force) { | ||
| 248 | |||
| 249 | this.trigger('beforehide.uk.dropdown', [this, force]); | ||
| 250 | |||
| 251 | this.element.removeClass('uk-open'); | ||
| 252 | |||
| 253 | if (this.remainIdle) { | ||
| 254 | clearTimeout(this.remainIdle); | ||
| 255 | } | ||
| 256 | |||
| 257 | this.remainIdle = false; | ||
| 258 | |||
| 259 | // Update ARIA | ||
| 260 | this.element.attr('aria-expanded', 'false'); | ||
| 261 | |||
| 262 | this.trigger('hide.uk.dropdown', [this, force]); | ||
| 263 | |||
| 264 | if (active == this) active = false; | ||
| 265 | }, | ||
| 266 | |||
| 267 | registerOuterClick: function(){ | ||
| 268 | |||
| 269 | var $this = this; | ||
| 270 | |||
| 271 | UI.$html.off("click.outer.dropdown"); | ||
| 272 | |||
| 273 | setTimeout(function() { | ||
| 274 | |||
| 275 | UI.$html.on("click.outer.dropdown", function(e) { | ||
| 276 | |||
| 277 | if (hoverIdle) { | ||
| 278 | clearTimeout(hoverIdle); | ||
| 279 | } | ||
| 280 | |||
| 281 | var $target = UI.$(e.target); | ||
| 282 | |||
| 283 | if (active == $this && !$this.element.find(e.target).length) { | ||
| 284 | $this.hide(true); | ||
| 285 | UI.$html.off("click.outer.dropdown"); | ||
| 286 | } | ||
| 287 | }); | ||
| 288 | }, 10); | ||
| 289 | }, | ||
| 290 | |||
| 291 | checkDimensions: function() { | ||
| 292 | |||
| 293 | if (!this.dropdown.length) return; | ||
| 294 | |||
| 295 | // reset | ||
| 296 | this.dropdown.removeClass('uk-dropdown-top uk-dropdown-bottom uk-dropdown-left uk-dropdown-right uk-dropdown-stack').css({ | ||
| 297 | 'top-left':'', | ||
| 298 | 'left':'', | ||
| 299 | 'margin-left' :'', | ||
| 300 | 'margin-right':'' | ||
| 301 | }); | ||
| 302 | |||
| 303 | if (this.justified && this.justified.length) { | ||
| 304 | this.dropdown.css("min-width", ""); | ||
| 305 | } | ||
| 306 | |||
| 307 | var $this = this, | ||
| 308 | pos = UI.$.extend({}, this.offsetParent.offset(), {width: this.offsetParent[0].offsetWidth, height: this.offsetParent[0].offsetHeight}), | ||
| 309 | posoffset = this.options.offset, | ||
| 310 | dropdown = this.dropdown, | ||
| 311 | offset = dropdown.show().offset() || {left: 0, top: 0}, | ||
| 312 | width = dropdown.outerWidth(), | ||
| 313 | height = dropdown.outerHeight(), | ||
| 314 | boundarywidth = this.boundary.width(), | ||
| 315 | boundaryoffset = this.boundary[0] !== window && this.boundary.offset() ? this.boundary.offset(): {top:0, left:0}, | ||
| 316 | dpos = this.options.pos; | ||
| 317 | |||
| 318 | var variants = { | ||
| 319 | "bottom-left" : {top: 0 + pos.height + posoffset, left: 0}, | ||
| 320 | "bottom-right" : {top: 0 + pos.height + posoffset, left: 0 + pos.width - width}, | ||
| 321 | "bottom-center" : {top: 0 + pos.height + posoffset, left: 0 + pos.width / 2 - width / 2}, | ||
| 322 | "top-left" : {top: 0 - height - posoffset, left: 0}, | ||
| 323 | "top-right" : {top: 0 - height - posoffset, left: 0 + pos.width - width}, | ||
| 324 | "top-center" : {top: 0 - height - posoffset, left: 0 + pos.width / 2 - width / 2}, | ||
| 325 | "left-top" : {top: 0, left: 0 - width - posoffset}, | ||
| 326 | "left-bottom" : {top: 0 + pos.height - height, left: 0 - width - posoffset}, | ||
| 327 | "left-center" : {top: 0 + pos.height / 2 - height / 2, left: 0 - width - posoffset}, | ||
| 328 | "right-top" : {top: 0, left: 0 + pos.width + posoffset}, | ||
| 329 | "right-bottom" : {top: 0 + pos.height - height, left: 0 + pos.width + posoffset}, | ||
| 330 | "right-center" : {top: 0 + pos.height / 2 - height / 2, left: 0 + pos.width + posoffset} | ||
| 331 | }, | ||
| 332 | css = {}, | ||
| 333 | pp; | ||
| 334 | |||
| 335 | pp = dpos.split('-'); | ||
| 336 | css = variants[dpos] ? variants[dpos] : variants['bottom-left']; | ||
| 337 | |||
| 338 | // justify dropdown | ||
| 339 | if (this.justified && this.justified.length) { | ||
| 340 | justify(dropdown.css({left:0}), this.justified, boundarywidth); | ||
| 341 | } else { | ||
| 342 | |||
| 343 | if (this.options.preventflip !== true) { | ||
| 344 | |||
| 345 | var fdpos; | ||
| 346 | |||
| 347 | switch(this.checkBoundary(pos.left + css.left, pos.top + css.top, width, height, boundarywidth)) { | ||
| 348 | case "x": | ||
| 349 | if(this.options.preventflip !=='x') fdpos = flips['x'][dpos] || 'right-top'; | ||
| 350 | break; | ||
| 351 | case "y": | ||
| 352 | if(this.options.preventflip !=='y') fdpos = flips['y'][dpos] || 'top-left'; | ||
| 353 | break; | ||
| 354 | case "xy": | ||
| 355 | if(!this.options.preventflip) fdpos = flips['xy'][dpos] || 'right-bottom'; | ||
| 356 | break; | ||
| 357 | } | ||
| 358 | |||
| 359 | if (fdpos) { | ||
| 360 | |||
| 361 | pp = fdpos.split('-'); | ||
| 362 | css = variants[fdpos] ? variants[fdpos] : variants['bottom-left']; | ||
| 363 | |||
| 364 | // check flipped | ||
| 365 | if (this.checkBoundary(pos.left + css.left, pos.top + css.top, width, height, boundarywidth)) { | ||
| 366 | pp = dpos.split('-'); | ||
| 367 | css = variants[dpos] ? variants[dpos] : variants['bottom-left']; | ||
| 368 | } | ||
| 369 | } | ||
| 370 | } | ||
| 371 | } | ||
| 372 | |||
| 373 | if (width > boundarywidth) { | ||
| 374 | dropdown.addClass("uk-dropdown-stack"); | ||
| 375 | this.trigger('stack.uk.dropdown', [this]); | ||
| 376 | } | ||
| 377 | |||
| 378 | dropdown.css(css).css("display", "").addClass('uk-dropdown-'+pp[0]); | ||
| 379 | }, | ||
| 380 | |||
| 381 | checkBoundary: function(left, top, width, height, boundarywidth) { | ||
| 382 | |||
| 383 | var axis = ""; | ||
| 384 | |||
| 385 | if (left < 0 || ((left - UI.$win.scrollLeft())+width) > boundarywidth) { | ||
| 386 | axis += "x"; | ||
| 387 | } | ||
| 388 | |||
| 389 | if ((top - UI.$win.scrollTop()) < 0 || ((top - UI.$win.scrollTop())+height) > window.innerHeight) { | ||
| 390 | axis += "y"; | ||
| 391 | } | ||
| 392 | |||
| 393 | return axis; | ||
| 394 | } | ||
| 395 | }); | ||
| 396 | |||
| 397 | |||
| 398 | UI.component('dropdownOverlay', { | ||
| 399 | |||
| 400 | defaults: { | ||
| 401 | 'justify' : false, | ||
| 402 | 'cls' : '', | ||
| 403 | 'duration': 200 | ||
| 404 | }, | ||
| 405 | |||
| 406 | boot: function() { | ||
| 407 | |||
| 408 | // init code | ||
| 409 | UI.ready(function(context) { | ||
| 410 | |||
| 411 | UI.$("[data-uk-dropdown-overlay]", context).each(function() { | ||
| 412 | var ele = UI.$(this); | ||
| 413 | |||
| 414 | if (!ele.data("dropdownOverlay")) { | ||
| 415 | UI.dropdownOverlay(ele, UI.Utils.options(ele.attr("data-uk-dropdown-overlay"))); | ||
| 416 | } | ||
| 417 | }); | ||
| 418 | }); | ||
| 419 | }, | ||
| 420 | |||
| 421 | init: function() { | ||
| 422 | |||
| 423 | var $this = this; | ||
| 424 | |||
| 425 | this.justified = this.options.justify ? UI.$(this.options.justify) : false; | ||
| 426 | this.overlay = this.element.find('uk-dropdown-overlay'); | ||
| 427 | |||
| 428 | if (!this.overlay.length) { | ||
| 429 | this.overlay = UI.$('<div class="uk-dropdown-overlay"></div>').appendTo(this.element); | ||
| 430 | } | ||
| 431 | |||
| 432 | this.overlay.addClass(this.options.cls); | ||
| 433 | |||
| 434 | this.on({ | ||
| 435 | |||
| 436 | 'beforeshow.uk.dropdown': function(e, dropdown) { | ||
| 437 | $this.dropdown = dropdown; | ||
| 438 | |||
| 439 | if ($this.justified && $this.justified.length) { | ||
| 440 | justify($this.overlay.css({'display':'block', 'margin-left':'','margin-right':''}), $this.justified, $this.justified.outerWidth()); | ||
| 441 | } | ||
| 442 | }, | ||
| 443 | |||
| 444 | 'show.uk.dropdown': function(e, dropdown) { | ||
| 445 | |||
| 446 | var h = $this.dropdown.dropdown.outerHeight(true); | ||
| 447 | |||
| 448 | $this.dropdown.element.removeClass('uk-open'); | ||
| 449 | |||
| 450 | $this.overlay.stop().css('display', 'block').animate({height: h}, $this.options.duration, function() { | ||
| 451 | |||
| 452 | $this.dropdown.dropdown.css('visibility', ''); | ||
| 453 | $this.dropdown.element.addClass('uk-open'); | ||
| 454 | |||
| 455 | UI.Utils.checkDisplay($this.dropdown.dropdown, true); | ||
| 456 | }); | ||
| 457 | |||
| 458 | $this.pointerleave = false; | ||
| 459 | }, | ||
| 460 | |||
| 461 | 'hide.uk.dropdown': function() { | ||
| 462 | $this.overlay.stop().animate({height: 0}, $this.options.duration); | ||
| 463 | }, | ||
| 464 | |||
| 465 | 'pointerenter.uk.dropdown': function(e, dropdown) { | ||
| 466 | clearTimeout($this.remainIdle); | ||
| 467 | }, | ||
| 468 | |||
| 469 | 'pointerleave.uk.dropdown': function(e, dropdown) { | ||
| 470 | $this.pointerleave = true; | ||
| 471 | } | ||
| 472 | }); | ||
| 473 | |||
| 474 | |||
| 475 | this.overlay.on({ | ||
| 476 | |||
| 477 | 'mouseenter': function() { | ||
| 478 | if ($this.remainIdle) { | ||
| 479 | clearTimeout($this.dropdown.remainIdle); | ||
| 480 | clearTimeout($this.remainIdle); | ||
| 481 | } | ||
| 482 | }, | ||
| 483 | |||
| 484 | 'mouseleave': function(){ | ||
| 485 | |||
| 486 | if ($this.pointerleave && active) { | ||
| 487 | |||
| 488 | $this.remainIdle = setTimeout(function() { | ||
| 489 | if(active) active.hide(); | ||
| 490 | }, active.options.remaintime); | ||
| 491 | } | ||
| 492 | } | ||
| 493 | }) | ||
| 494 | } | ||
| 495 | |||
| 496 | }); | ||
| 497 | |||
| 498 | |||
| 499 | function justify(ele, justifyTo, boundarywidth, offset) { | ||
| 500 | |||
| 501 | ele = UI.$(ele); | ||
| 502 | justifyTo = UI.$(justifyTo); | ||
| 503 | boundarywidth = boundarywidth || window.innerWidth; | ||
| 504 | offset = offset || ele.offset(); | ||
| 505 | |||
| 506 | if (justifyTo.length) { | ||
| 507 | |||
| 508 | var jwidth = justifyTo.outerWidth(); | ||
| 509 | |||
| 510 | ele.css("min-width", jwidth); | ||
| 511 | |||
| 512 | if (UI.langdirection == 'right') { | ||
| 513 | |||
| 514 | var right1 = boundarywidth - (justifyTo.offset().left + jwidth), | ||
| 515 | right2 = boundarywidth - (ele.offset().left + ele.outerWidth()); | ||
| 516 | |||
| 517 | ele.css("margin-right", right1 - right2); | ||
| 518 | |||
| 519 | } else { | ||
| 520 | ele.css("margin-left", justifyTo.offset().left - offset.left); | ||
| 521 | } | ||
| 522 | } | ||
| 523 | } | ||
| 524 | |||
| 525 | })(UIkit); | ||
