New tags drop down

This commit is contained in:
aignatov-bio 2019-10-17 10:06:40 +02:00
parent 8fd4b46416
commit e7ad7ae969
5 changed files with 161 additions and 16 deletions

View file

@ -286,8 +286,57 @@ function initTagsSelector() {
return $('<div class="add-tags">' + result + '</div>'); return $('<div class="add-tags">' + result + '</div>');
} }
dropdownSelector.init('#module-tags-selector',{
tagClass: 'my-module-white-tags',
tagStyle: (data) => {
return `background: ${data.params.color}`
},
optionLabel: (data) => {
if (data.value > 0) {
return `<span class="my-module-tags-color" style="background:${data.params.color}"></span>${data.label}`
} else {
return `${data.label}<span class="my-module-tags-create-new"> (${I18n.t('my_modules.module_header.create_new_tag')})</span>`;
}
},
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, ajax: tagsAjaxQuery,
unlimitedSize: true, unlimitedSize: true,
colorField: 'color', colorField: 'color',
@ -349,7 +398,7 @@ function initTagsSelector() {
inputLine[0].disabled = false; inputLine[0].disabled = false;
inputLine.focus(); inputLine.focus();
return true; return true;
}); });*/
} }
applyTaskCompletedCallBack(); applyTaskCompletedCallBack();

View file

@ -83,6 +83,27 @@ var dropdownSelector = (function() {
updateTags(selector, container, { skipChange: true }); 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 /// // Private functions ///
// ///////////////////// // /////////////////////
@ -122,6 +143,12 @@ var dropdownSelector = (function() {
saveData(selectElement, dropdownContainer); saveData(selectElement, dropdownContainer);
}); });
} }
if (selectElement.data('ajax-url')) {
ajaxInitialValues(selectElement, dropdownContainer)
}
dropdownContainer.find('.search-field').keyup((e) => { dropdownContainer.find('.search-field').keyup((e) => {
e.stopPropagation(); e.stopPropagation();
loadData(selectElement, dropdownContainer); loadData(selectElement, dropdownContainer);
@ -152,6 +179,8 @@ var dropdownSelector = (function() {
loadData(selectElement, dropdownContainer); loadData(selectElement, dropdownContainer);
updateDropdownDirection(selectElement, dropdownContainer); updateDropdownDirection(selectElement, dropdownContainer);
dropdownContainer.find('.search-field').focus(); dropdownContainer.find('.search-field').focus();
} else {
dropdownContainer.find('.search-field').blur()
} }
}); });
$(window).resize(function() { updateDropdownDirection(selectElement, dropdownContainer); }); $(window).resize(function() { updateDropdownDirection(selectElement, dropdownContainer); });
@ -175,13 +204,17 @@ var dropdownSelector = (function() {
data = dataSource(selector, container); data = dataSource(selector, container);
} }
// Draw option object // 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 $(` return $(`
<div class="dropdown-option checkbox-icon" <div class="dropdown-option ${customClass}" style="${customStyle ? customStyle(option) : ''}"
data-params='${JSON.stringify(option.params)}'
data-label="${option.label}" data-label="${option.label}"
data-group="${group ? group.value : ''}" data-group="${group ? group.value : ''}"
data-value="${option.value}"> data-value="${option.value}">
${option.label} ${customLabel ? customLabel(option) : option.label}
</div>" </div>"
`); `);
} }
@ -209,7 +242,7 @@ var dropdownSelector = (function() {
$.each(data, function(gi, group) { $.each(data, function(gi, group) {
var groupElement = drawGroup(group); var groupElement = drawGroup(group);
$.each(group.options, function(oi, option) { $.each(group.options, function(oi, option) {
var optionElement = drawOption(option, group); var optionElement = drawOption(selector, option, group);
optionElement.click(clickOption); optionElement.click(clickOption);
optionElement.appendTo(groupElement); optionElement.appendTo(groupElement);
}); });
@ -226,7 +259,7 @@ var dropdownSelector = (function() {
}); });
} else { } else {
$.each(data, function(oi, option) { $.each(data, function(oi, option) {
var optionElement = drawOption(option); var optionElement = drawOption(selector, option);
optionElement.click(clickOption); optionElement.click(clickOption);
optionElement.appendTo(container.find('.dropdown-container')); optionElement.appendTo(container.find('.dropdown-container'));
}); });
@ -261,7 +294,8 @@ var dropdownSelector = (function() {
newOption = { newOption = {
label: option.dataset.label, label: option.dataset.label,
value: option.dataset.value, value: option.dataset.value,
group: option.dataset.group group: option.dataset.group,
params: JSON.parse(option.dataset.params)
}; };
selectArray.push(newOption); selectArray.push(newOption);
} }
@ -271,7 +305,7 @@ var dropdownSelector = (function() {
} }
}); });
updateCurrentData(container, selectArray); updateCurrentData(container, selectArray);
updateTags(selector, container); updateTags(selector, container, {select: true});
loadData(selector, container); loadData(selector, container);
} }
@ -283,7 +317,9 @@ var dropdownSelector = (function() {
// Draw tag and assign event // Draw tag and assign event
function drawTag(data) { function drawTag(data) {
var customLabel = selector.data('config').tagLabel; var customLabel = selector.data('config').tagLabel;
var tag = $(`<div class="ds-tags" > var customClass = selector.data('config').tagClass || '';
var customStyle = selector.data('config').tagStyle;
var tag = $(`<div class="ds-tags ${customClass}" style="${customStyle ? customStyle(data) : ''}" >
<div class="tag-label" <div class="tag-label"
data-ds-tag-group="${data.group}" data-ds-tag-group="${data.group}"
data-ds-tag-id="${data.value}"> data-ds-tag-id="${data.value}">
@ -308,7 +344,7 @@ var dropdownSelector = (function() {
)); ));
selectedOptions.splice(toDelete, 1); selectedOptions.splice(toDelete, 1);
updateCurrentData(container, selectedOptions); updateCurrentData(container, selectedOptions);
updateTags(selector, container); updateTags(selector, container, {unselect: true, tagId: tagLabel.data('ds-tag-id')});
} }
}, 350); }, 350);
}); });
@ -341,9 +377,18 @@ var dropdownSelector = (function() {
updateDropdownDirection(selector, container); updateDropdownDirection(selector, container);
refreshDropdownSelection(selector, container); refreshDropdownSelection(selector, container);
if (container.hasClass('open')) container.find('.search-field').focus(); 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) { if (selector.data('config').onChange && !config.skipChange) {
selector.data('config').onChange(); 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 // Convert local data or ajax data to same format
@ -466,6 +511,26 @@ var dropdownSelector = (function() {
disableEnableDropdown($(selector), $(selector).next(), true); disableEnableDropdown($(selector), $(selector).next(), true);
return this; 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
} }
}; };
}()); }());

View file

@ -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 { .select2-dropdown.module-tags-selector-dropdown {

View file

@ -119,7 +119,11 @@ class MyModuleTagsController < ApplicationController
false, false,
params[:query] params[:query]
).select(:id, :name, :color).limit(6) ).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 render json: tags
end end

View file

@ -10,18 +10,16 @@
[ [
i[:name], i[:name],
i[:id], i[:id],
{'data-color'=> i[:color]} {'data-params' => {color: i[:color]}.to_json}
] ]
}), }),
{ {
'data-select-all': 'true',
id: 'module-tags-selector', id: 'module-tags-selector',
'data-editable': editable,
'data-module-id': my_module.id , 'data-module-id': my_module.id ,
'data-project-id': my_module.experiment.project_id , 'data-project-id': my_module.experiment.project_id ,
'data-placeholder': t("my_modules.module_header.no_tags"), 'data-placeholder': t("my_modules.module_header.no_tags"),
'data-tags-create-url': project_tags_path(project_id: my_module.experiment.project_id), '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) 'data-update-module-tags-url': my_module_my_module_tags_path(@my_module)
} %> } %>