aboutsummaryrefslogtreecommitdiff
path: root/app/dispatch/static/materialize/js/dropdown.js
diff options
context:
space:
mode:
authorMitch Riedstra <Mitch@riedstra.us>2017-10-24 16:59:48 -0400
committerMitch Riedstra <Mitch@riedstra.us>2017-10-24 16:59:48 -0400
commit3e8b34be2fdeccf16c8b46f1ee518f970853768d (patch)
treeabcb7d0cb260790a2b4a746e3959f2e7ee3a33f7 /app/dispatch/static/materialize/js/dropdown.js
parent4ee5893fd9c82228c62306fc7f5babdfc602e4c4 (diff)
downloaddispatch-tracker-3e8b34be2fdeccf16c8b46f1ee518f970853768d.tar.gz
dispatch-tracker-3e8b34be2fdeccf16c8b46f1ee518f970853768d.tar.xz
Adding in materialize source and templates
Diffstat (limited to 'app/dispatch/static/materialize/js/dropdown.js')
-rw-r--r--app/dispatch/static/materialize/js/dropdown.js274
1 files changed, 274 insertions, 0 deletions
diff --git a/app/dispatch/static/materialize/js/dropdown.js b/app/dispatch/static/materialize/js/dropdown.js
new file mode 100644
index 0000000..6627e45
--- /dev/null
+++ b/app/dispatch/static/materialize/js/dropdown.js
@@ -0,0 +1,274 @@
+(function ($) {
+
+ // Add posibility to scroll to selected option
+ // usefull for select for example
+ $.fn.scrollTo = function(elem) {
+ $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
+ return this;
+ };
+
+ $.fn.dropdown = function (options) {
+ var defaults = {
+ inDuration: 300,
+ outDuration: 225,
+ constrainWidth: true, // Constrains width of dropdown to the activator
+ hover: false,
+ gutter: 0, // Spacing from edge
+ belowOrigin: false,
+ alignment: 'left',
+ stopPropagation: false
+ };
+
+ // Open dropdown.
+ if (options === "open") {
+ this.each(function() {
+ $(this).trigger('open');
+ });
+ return false;
+ }
+
+ // Close dropdown.
+ if (options === "close") {
+ this.each(function() {
+ $(this).trigger('close');
+ });
+ return false;
+ }
+
+ this.each(function(){
+ var origin = $(this);
+ var curr_options = $.extend({}, defaults, options);
+ var isFocused = false;
+
+ // Dropdown menu
+ var activates = $("#"+ origin.attr('data-activates'));
+
+ function updateOptions() {
+ if (origin.data('induration') !== undefined)
+ curr_options.inDuration = origin.data('induration');
+ if (origin.data('outduration') !== undefined)
+ curr_options.outDuration = origin.data('outduration');
+ if (origin.data('constrainwidth') !== undefined)
+ curr_options.constrainWidth = origin.data('constrainwidth');
+ if (origin.data('hover') !== undefined)
+ curr_options.hover = origin.data('hover');
+ if (origin.data('gutter') !== undefined)
+ curr_options.gutter = origin.data('gutter');
+ if (origin.data('beloworigin') !== undefined)
+ curr_options.belowOrigin = origin.data('beloworigin');
+ if (origin.data('alignment') !== undefined)
+ curr_options.alignment = origin.data('alignment');
+ if (origin.data('stoppropagation') !== undefined)
+ curr_options.stopPropagation = origin.data('stoppropagation');
+ }
+
+ updateOptions();
+
+ // Attach dropdown to its activator
+ origin.after(activates);
+
+ /*
+ Helper function to position and resize dropdown.
+ Used in hover and click handler.
+ */
+ function placeDropdown(eventType) {
+ // Check for simultaneous focus and click events.
+ if (eventType === 'focus') {
+ isFocused = true;
+ }
+
+ // Check html data attributes
+ updateOptions();
+
+ // Set Dropdown state
+ activates.addClass('active');
+ origin.addClass('active');
+
+ var originWidth = origin[0].getBoundingClientRect().width;
+
+ // Constrain width
+ if (curr_options.constrainWidth === true) {
+ activates.css('width', originWidth);
+
+ } else {
+ activates.css('white-space', 'nowrap');
+ }
+
+ // Offscreen detection
+ var windowHeight = window.innerHeight;
+ var originHeight = origin.innerHeight();
+ var offsetLeft = origin.offset().left;
+ var offsetTop = origin.offset().top - $(window).scrollTop();
+ var currAlignment = curr_options.alignment;
+ var gutterSpacing = 0;
+ var leftPosition = 0;
+
+ // Below Origin
+ var verticalOffset = 0;
+ if (curr_options.belowOrigin === true) {
+ verticalOffset = originHeight;
+ }
+
+ // Check for scrolling positioned container.
+ var scrollYOffset = 0;
+ var scrollXOffset = 0;
+ var wrapper = origin.parent();
+ if (!wrapper.is('body')) {
+ if (wrapper[0].scrollHeight > wrapper[0].clientHeight) {
+ scrollYOffset = wrapper[0].scrollTop;
+ }
+ if (wrapper[0].scrollWidth > wrapper[0].clientWidth) {
+ scrollXOffset = wrapper[0].scrollLeft;
+ }
+ }
+
+
+ if (offsetLeft + activates.innerWidth() > $(window).width()) {
+ // Dropdown goes past screen on right, force right alignment
+ currAlignment = 'right';
+
+ } else if (offsetLeft - activates.innerWidth() + origin.innerWidth() < 0) {
+ // Dropdown goes past screen on left, force left alignment
+ currAlignment = 'left';
+ }
+ // Vertical bottom offscreen detection
+ if (offsetTop + activates.innerHeight() > windowHeight) {
+ // If going upwards still goes offscreen, just crop height of dropdown.
+ if (offsetTop + originHeight - activates.innerHeight() < 0) {
+ var adjustedHeight = windowHeight - offsetTop - verticalOffset;
+ activates.css('max-height', adjustedHeight);
+ } else {
+ // Flow upwards.
+ if (!verticalOffset) {
+ verticalOffset += originHeight;
+ }
+ verticalOffset -= activates.innerHeight();
+ }
+ }
+
+ // Handle edge alignment
+ if (currAlignment === 'left') {
+ gutterSpacing = curr_options.gutter;
+ leftPosition = origin.position().left + gutterSpacing;
+ }
+ else if (currAlignment === 'right') {
+ // Material icons fix
+ activates
+ .stop(true, true)
+ .css({
+ opacity: 0,
+ left: 0
+ })
+
+ var offsetRight = origin.position().left + originWidth - activates.width();
+ gutterSpacing = -curr_options.gutter;
+ leftPosition = offsetRight + gutterSpacing;
+ }
+
+ // Position dropdown
+ activates.css({
+ position: 'absolute',
+ top: origin.position().top + verticalOffset + scrollYOffset,
+ left: leftPosition + scrollXOffset
+ });
+
+ // Show dropdown
+ activates
+ .slideDown({
+ queue: false,
+ duration: curr_options.inDuration,
+ easing: 'easeOutCubic',
+ complete: function() {
+ $(this).css('height', '');
+ }
+ })
+ .animate( {opacity: 1}, {queue: false, duration: curr_options.inDuration, easing: 'easeOutSine'});
+
+ // Add click close handler to document
+ setTimeout(function() {
+ $(document).on('click.'+ activates.attr('id'), function (e) {
+ hideDropdown();
+ $(document).off('click.'+ activates.attr('id'));
+ });
+ }, 0);
+ }
+
+ function hideDropdown() {
+ // Check for simultaneous focus and click events.
+ isFocused = false;
+ activates.fadeOut(curr_options.outDuration);
+ activates.removeClass('active');
+ origin.removeClass('active');
+ $(document).off('click.'+ activates.attr('id'));
+ setTimeout(function() { activates.css('max-height', ''); }, curr_options.outDuration);
+ }
+
+ // Hover
+ if (curr_options.hover) {
+ var open = false;
+ origin.off('click.' + origin.attr('id'));
+ // Hover handler to show dropdown
+ origin.on('mouseenter', function(e){ // Mouse over
+ if (open === false) {
+ placeDropdown();
+ open = true;
+ }
+ });
+ origin.on('mouseleave', function(e){
+ // If hover on origin then to something other than dropdown content, then close
+ var toEl = e.toElement || e.relatedTarget; // added browser compatibility for target element
+ if(!$(toEl).closest('.dropdown-content').is(activates)) {
+ activates.stop(true, true);
+ hideDropdown();
+ open = false;
+ }
+ });
+
+ activates.on('mouseleave', function(e){ // Mouse out
+ var toEl = e.toElement || e.relatedTarget;
+ if(!$(toEl).closest('.dropdown-button').is(origin)) {
+ activates.stop(true, true);
+ hideDropdown();
+ open = false;
+ }
+ });
+
+ // Click
+ } else {
+ // Click handler to show dropdown
+ origin.off('click.' + origin.attr('id'));
+ origin.on('click.'+origin.attr('id'), function(e){
+ if (!isFocused) {
+ if ( origin[0] == e.currentTarget &&
+ !origin.hasClass('active') &&
+ ($(e.target).closest('.dropdown-content').length === 0)) {
+ e.preventDefault(); // Prevents button click from moving window
+ if (curr_options.stopPropagation) {
+ e.stopPropagation();
+ }
+ placeDropdown('click');
+ }
+ // If origin is clicked and menu is open, close menu
+ else if (origin.hasClass('active')) {
+ hideDropdown();
+ $(document).off('click.'+ activates.attr('id'));
+ }
+ }
+ });
+
+ } // End else
+
+ // Listen to open and close event - useful for select component
+ origin.on('open', function(e, eventType) {
+ placeDropdown(eventType);
+ });
+ origin.on('close', hideDropdown);
+
+
+ });
+ }; // End dropdown plugin
+
+ $(document).ready(function(){
+ $('.dropdown-button').dropdown();
+ });
+}( jQuery ));