From 04bd5269ec61fb6f220ab1d9a855014760a5c057 Mon Sep 17 00:00:00 2001 From: Anton Ignatov Date: Fri, 2 Aug 2019 15:57:41 +0200 Subject: [PATCH] Created new dropdown selector --- .../global_activities/side_pane.js | 4 +- .../javascripts/sitewide/dropdown_selector.js | 138 +++++++++++++++++ .../stylesheets/shared/dropdown_selector.scss | 139 ++++++++++++++++++ 3 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 app/assets/javascripts/sitewide/dropdown_selector.js create mode 100644 app/assets/stylesheets/shared/dropdown_selector.scss diff --git a/app/assets/javascripts/global_activities/side_pane.js b/app/assets/javascripts/global_activities/side_pane.js index 6d253aaff..b97c13757 100644 --- a/app/assets/javascripts/global_activities/side_pane.js +++ b/app/assets/javascripts/global_activities/side_pane.js @@ -52,7 +52,7 @@ function GlobalActivitiesFilterPrepareArray() { $(function() { var updateRunning = false; - var selectors = ['activity', 'user', 'team']; + var selectors = ['user', 'team']; // Ajax request for object search var subjectAjaxQuery = { url: '/global_activities/search_subjects', @@ -88,6 +88,8 @@ $(function() { return (state.label ? state.label + ': ' : '') + state.text; }; + dropdownSelector.init('.activity-selector #activity') + var ajaxQuery = {}; $.each(selectors, (index, e) => { var selector = $('.ga-side .' + e + '-selector select')[0]; diff --git a/app/assets/javascripts/sitewide/dropdown_selector.js b/app/assets/javascripts/sitewide/dropdown_selector.js new file mode 100644 index 000000000..ce29bc911 --- /dev/null +++ b/app/assets/javascripts/sitewide/dropdown_selector.js @@ -0,0 +1,138 @@ +var dropdownSelector = (function() { + function generateDropdown(selector){ + var selectElement = $(selector) + var dropdownContainer = selectElement.after('').next() + $(` +
+ + + `).appendTo(dropdownContainer) + + ps = new PerfectScrollbar(dropdownContainer.find('.dropdown-container')[0]) + activePSB.push(ps) + + dropdownContainer.find('.input-field').click(() => { + dropdownContainer.toggleClass("open") + if (dropdownContainer.hasClass("open")) { + loadData(selectElement , dropdownContainer) + updateDropdownDirection(dropdownContainer) + } + }) + $(window).resize(function(){ + updateDropdownDirection(dropdownContainer) + }) + + dropdownContainer.blur(function() { + console.log(1) + }) + + $(window).click(() => { + dropdownContainer.removeClass("open") + }); + dropdownContainer.click((e) => { + e.stopPropagation(); + }) + + selectElement.css('display', 'none') + } + + function updateDropdownDirection(container) { + var windowHeight = $(window).height() + var containerPosition = container[0].getBoundingClientRect().top + var containerHeight = container[0].getBoundingClientRect().height + var bottomSpace = windowHeight - containerPosition - containerHeight + if (bottomSpace < 232) { + container.addClass('inverse') + container.find('.dropdown-container').css('max-height', (containerPosition - 82) + 'px') + } else { + container.removeClass('inverse') + container.find('.dropdown-container').css('max-height', (bottomSpace - 32) + 'px') + } + } + + function loadData(selector, container) { + + container.find('.dropdown-container .dropdown-group').remove() + container.find('.dropdown-container .dropdown-option').remove() + + if (selector.data('select-by-group')){ + var groups = selector.find('optgroup') + $.each(groups, function(gi, group) { + var groupElement = $(` + + `) + $.each($(group).find('option'), function(oi, option) { + optionElement = $(` + " + `) + optionElement.click(function() { + $(this).toggleClass('select') + saveData(container) + }) + optionElement.appendTo(groupElement) + }) + groupElement.find('.group-name').click(function() { + var groupContainer = $(this).parent() + groupContainer.toggleClass('select') + if (groupContainer.hasClass('select')) { + groupContainer.find('.dropdown-option').addClass('select') + }else{ + groupContainer.find('.dropdown-option').removeClass('select') + } + saveData(container) + }) + groupElement.appendTo(container.find('.dropdown-container')) + }) + } else { + options = selector.find('option') + $.each(options, function(oi, option) { + optionElement = $(` + " + `) + optionElement.click(function() { + $(this).toggleClass('select') + saveData(container) + }) + optionElement.appendTo(container.find('.dropdown-container')) + }) + } + + PerfectSb().update_all() + + $.each(JSON.parse(container.find('.data-field').val()), function(i, selectedOption) { + container.find('.dropdown-container .dropdown-option[data-value="' + selectedOption + '"]').addClass('select') + }) + if (selector.data('select-by-group')){ + $.each(container.find('.dropdown-group'), function(gi, group) { + if ($(group).find('.dropdown-option').length === $(group).find('.dropdown-option.select').length) { + $(group).addClass('select') + } + }) + } + } + + function saveData(container) { + var selectArray = [] + $.each(container.find('.dropdown-container .dropdown-option.select'), function(oi ,option){ + selectArray.push(option.dataset.value) + }) + container.find('.data-field').val(JSON.stringify(selectArray)) + } + + + + return { + init: (selector) => { + generateDropdown(selector) + }, + update_dropdown_position: (selector) => { + updateDropdownDirection($(selector).next()) + } + }; +}()); \ No newline at end of file diff --git a/app/assets/stylesheets/shared/dropdown_selector.scss b/app/assets/stylesheets/shared/dropdown_selector.scss new file mode 100644 index 000000000..4d6b9fd9e --- /dev/null +++ b/app/assets/stylesheets/shared/dropdown_selector.scss @@ -0,0 +1,139 @@ +@import "constants"; + +.dropdown-selector-container { + display: inline-block; + position: relative; + width: 100%; + + .input-field { + background: $color-white; + border: 1px solid $color-alto; + border-radius: 4px; + min-height: 32px; + position: relative; + transition: .2s; + width: 100%; + z-index: 12; + } + + .dropdown-container { + background: $color-white; + border: 1px solid $color-alto; + border-radius: 0 0 4px 4px; + border-top: 0; + box-shadow: 0px 0px 0px 0px rgba(0,0,0, 0.2); + display: none; + min-height: 100px; + overflow: hidden; + position: absolute; + top: calc(100% - 30px); + transition: .2s; + width: 100%; + z-index: 10; + + .checkbox-icon { + &::before { + content: "\f0c8"; + font-family: "Font Awesome 5 Free"; + font-weight: 400; + margin: 2px 5px 0 0; + position: relative; + } + + &.select { + &::before { + content: "\f14a"; + } + } + } + + .dropdown-option { + align-items: center; + cursor: pointer; + display: flex; + min-height: 32px; + padding: 0 10px; + position: relative; + user-select: none; + + &.select { + background: $color-concrete; + } + + &:hover { + background: $brand-primary; + color: $color-white; + } + + + } + + .dropdown-group { + .group-name { + align-items: center; + cursor: pointer; + display: flex; + font-size: 14px; + font-weight: bold; + min-height: 32px; + padding: 0 10px; + user-select: none; + + &:hover { + background: $brand-primary !important; + color: $color-white; + } + } + + .dropdown-option { + padding-left: 20px; + } + + &.select { + .group-name.checkbox-icon { + background: $color-concrete; + &::before { + content: "\f14a"; + } + } + } + } + } + + &.inverse { + .dropdown-container { + bottom: calc(100% - 30px); + top: auto; + } + } + + &.open { + + .input-field { + border-radius: 4px 4px 0 0; + border-bottom: 1px solid $brand-primary + } + + .dropdown-container { + box-shadow: 0px 1px 2px 0px rgba(0,0,0, 0.2); + display: block; + top: 100%; + } + + &.inverse { + + .input-field { + border-radius: 0 0 4px 4px; + border-bottom: 1px solid $color-alto; + border-top: 1px solid $brand-primary + } + + .dropdown-container { + border-radius: 4px 4px 0 0; + bottom: 100%; + box-shadow: 0px -1px 2px 0px rgba(0,0,0, 0.2); + top: auto; + } + } + } +} \ No newline at end of file