diff --git a/app/assets/javascripts/my_modules.js b/app/assets/javascripts/my_modules.js index 6b93043c1..a39619412 100644 --- a/app/assets/javascripts/my_modules.js +++ b/app/assets/javascripts/my_modules.js @@ -286,8 +286,57 @@ function initTagsSelector() { return $('
' + result + '
'); } + dropdownSelector.init('#module-tags-selector',{ + tagClass: 'my-module-white-tags', + tagStyle: (data) => { + return `background: ${data.params.color}` + }, + optionLabel: (data) => { + if (data.value > 0) { + return `${data.label}` + } else { + return `${data.label} (${I18n.t('my_modules.module_header.create_new_tag')})`; + } + }, + onSelect: function() { + var selectElement = $('#module-tags-selector'); + var lastTag = selectElement.next().find('.ds-tags').last(); + var lastTagId = lastTag.find('.tag-label').data('ds-tag-id'); - $('#module-tags-selector').select2Multiple({ + if (lastTagId > 0) { + newTag = { my_module_tag: { tag_id: lastTagId } }; + $.post(selectElement.data('update-module-tags-url'), newTag) + .fail(function() { + lastTag.remove(); + }); + } else { + newTag = { + tag: { + name: lastTag.find('.tag-label').html(), + project_id: selectElement.data('project-id'), + color: null + }, + my_module_id: selectElement.data('module-id'), + simple_creation: true + }; + $.post(selectElement.data('tags-create-url'), newTag, function(result) { + var selectedValues = dropdownSelector.getData(selectElement) + lastTag.css('background', result.tag.color) + lastTag.find('.tag-label')[0].dataset.dsTagId = result.tag.id + selectedValues[selectedValues.length - 1].value = result.tag.id + selectedValues[selectedValues.length - 1].params.color = result.tag.color + dropdownSelector.setData(selectElement, selectedValues) + }); + } + dropdownSelector.closeDropdown('#module-tags-selector') + }, + onUnSelect: (id) => { + $.post(`${$('#module-tags-selector').data('update-module-tags-url')}/${id}/destroy_by_tag_id`); + dropdownSelector.closeDropdown('#module-tags-selector'); + } + }).getContainer('#module-tags-selector').addClass('my-module-tags-container'); + + /*$('#module-tags-selector').select2Multiple({ ajax: tagsAjaxQuery, unlimitedSize: true, colorField: 'color', @@ -349,7 +398,7 @@ function initTagsSelector() { inputLine[0].disabled = false; inputLine.focus(); return true; - }); + });*/ } applyTaskCompletedCallBack(); diff --git a/app/assets/javascripts/sitewide/dropdown_selector.js b/app/assets/javascripts/sitewide/dropdown_selector.js index 53394b46c..3ba2130d4 100644 --- a/app/assets/javascripts/sitewide/dropdown_selector.js +++ b/app/assets/javascripts/sitewide/dropdown_selector.js @@ -83,6 +83,27 @@ var dropdownSelector = (function() { updateTags(selector, container, { skipChange: true }); } } + + // Read option to JSON + function convertOptionToJson(option) { + return { + label: option.innerHTML, + value: option.value, + group: option.dataset.group, + params: JSON.parse(option.dataset.params) + } + } + + // Ajax intial values, we will use default options // + function ajaxInitialValues(selector, container) { + var intialData = [] + $(selector).find('option').each((i, option) => { + intialData.push(convertOptionToJson(option)) + }) + updateCurrentData(container, intialData) + updateTags(selector, container, { skipChange: true }); + } + // ////////////////////// // Private functions /// // ///////////////////// @@ -122,6 +143,12 @@ var dropdownSelector = (function() { saveData(selectElement, dropdownContainer); }); } + + if (selectElement.data('ajax-url')) { + ajaxInitialValues(selectElement, dropdownContainer) + } + + dropdownContainer.find('.search-field').keyup((e) => { e.stopPropagation(); loadData(selectElement, dropdownContainer); @@ -152,6 +179,8 @@ var dropdownSelector = (function() { loadData(selectElement, dropdownContainer); updateDropdownDirection(selectElement, dropdownContainer); dropdownContainer.find('.search-field').focus(); + } else { + dropdownContainer.find('.search-field').blur() } }); $(window).resize(function() { updateDropdownDirection(selectElement, dropdownContainer); }); @@ -175,13 +204,17 @@ var dropdownSelector = (function() { data = dataSource(selector, container); } // Draw option object - function drawOption(option, group = null) { + function drawOption(selector, option, group = null) { + var customLabel = selector.data('config').optionLabel; + var customClass = selector.data('config').optionClass || ''; + var customStyle = selector.data('config').optionStyle; return $(` - " `); } @@ -209,7 +242,7 @@ var dropdownSelector = (function() { $.each(data, function(gi, group) { var groupElement = drawGroup(group); $.each(group.options, function(oi, option) { - var optionElement = drawOption(option, group); + var optionElement = drawOption(selector, option, group); optionElement.click(clickOption); optionElement.appendTo(groupElement); }); @@ -226,7 +259,7 @@ var dropdownSelector = (function() { }); } else { $.each(data, function(oi, option) { - var optionElement = drawOption(option); + var optionElement = drawOption(selector, option); optionElement.click(clickOption); optionElement.appendTo(container.find('.dropdown-container')); }); @@ -261,7 +294,8 @@ var dropdownSelector = (function() { newOption = { label: option.dataset.label, value: option.dataset.value, - group: option.dataset.group + group: option.dataset.group, + params: JSON.parse(option.dataset.params) }; selectArray.push(newOption); } @@ -271,7 +305,7 @@ var dropdownSelector = (function() { } }); updateCurrentData(container, selectArray); - updateTags(selector, container); + updateTags(selector, container, {select: true}); loadData(selector, container); } @@ -283,7 +317,9 @@ var dropdownSelector = (function() { // Draw tag and assign event function drawTag(data) { var customLabel = selector.data('config').tagLabel; - var tag = $(`
+ var customClass = selector.data('config').tagClass || ''; + var customStyle = selector.data('config').tagStyle; + var tag = $(`
@@ -308,7 +344,7 @@ var dropdownSelector = (function() { )); selectedOptions.splice(toDelete, 1); updateCurrentData(container, selectedOptions); - updateTags(selector, container); + updateTags(selector, container, {unselect: true, tagId: tagLabel.data('ds-tag-id')}); } }, 350); }); @@ -341,9 +377,18 @@ var dropdownSelector = (function() { updateDropdownDirection(selector, container); refreshDropdownSelection(selector, container); if (container.hasClass('open')) container.find('.search-field').focus(); + + if (selector.data('config').onSelect && !config.skipChange && config.select) { + selector.data('config').onSelect(); + } + if (selector.data('config').onChange && !config.skipChange) { selector.data('config').onChange(); } + + if (selector.data('config').onUnSelect && !config.skipChange && config.unselect) { + selector.data('config').onUnSelect(config.tagId); + } } // Convert local data or ajax data to same format @@ -466,6 +511,26 @@ var dropdownSelector = (function() { disableEnableDropdown($(selector), $(selector).next(), true); return this; + }, + + // close dropdown + closeDropdown: function(selector) { + var dropdownContainer; + + if ($(selector).length === 0) return false; + dropdownContainer = $(selector).next() + if (dropdownContainer.hasClass('open')) { + dropdownContainer.find('.input-field').click() + } + + return this; + }, + + // get dropdown container + getContainer: function(selector) { + if ($(selector).length === 0) return false; + dropdownContainer = $(selector).next(); + return dropdownContainer } }; }()); diff --git a/app/assets/stylesheets/my_modules/protocols/index.scss b/app/assets/stylesheets/my_modules/protocols/index.scss index 8f5146eca..2c4dd130d 100644 --- a/app/assets/stylesheets/my_modules/protocols/index.scss +++ b/app/assets/stylesheets/my_modules/protocols/index.scss @@ -205,6 +205,35 @@ } } +.my-module-white-tags { + color: $color-white; +} + +.my-module-tags-container.dropdown-selector-container { + + + .my-module-tags-color { + border-radius: 8px; + display: inline-block; + height: 16px; + margin-right: 5px; + width: 16px; + } + + .my-module-tags-create-new { + opacity: .6; + } + + .input-field { + border: 1px solid transparent; + } + + &.open { + .input-field { + border: 1px solid $color-alto; + } + } +} .select2-dropdown.module-tags-selector-dropdown { diff --git a/app/controllers/my_module_tags_controller.rb b/app/controllers/my_module_tags_controller.rb index 2523bc1a9..5aada03c7 100644 --- a/app/controllers/my_module_tags_controller.rb +++ b/app/controllers/my_module_tags_controller.rb @@ -119,7 +119,11 @@ class MyModuleTagsController < ApplicationController false, params[:query] ).select(:id, :name, :color).limit(6) - tags = [{ id: 0, name: params[:query], color: nil }] if tags.count.zero? + if tags.count.zero? + tags = [{ value: 0, label: params[:query], params: {color: nil} }] + else + tags = tags.map{|i| {value: i.id, label: i.name, params: {color: i.color}}} + end render json: tags end diff --git a/app/views/my_modules/_tags.html.erb b/app/views/my_modules/_tags.html.erb index d7d3eccc6..8d9e5a7fa 100644 --- a/app/views/my_modules/_tags.html.erb +++ b/app/views/my_modules/_tags.html.erb @@ -10,18 +10,16 @@ [ i[:name], i[:id], - {'data-color'=> i[:color]} + {'data-params' => {color: i[:color]}.to_json} ] }), { - 'data-select-all': 'true', id: 'module-tags-selector', - 'data-editable': editable, 'data-module-id': my_module.id , 'data-project-id': my_module.experiment.project_id , 'data-placeholder': t("my_modules.module_header.no_tags"), 'data-tags-create-url': project_tags_path(project_id: my_module.experiment.project_id), - 'data-search-tag-url': search_tags_my_module_my_module_tags_path(@my_module), + 'data-ajax-url': search_tags_my_module_my_module_tags_path(@my_module), 'data-update-module-tags-url': my_module_my_module_tags_path(@my_module) } %>