scinote-web/app/assets/javascripts/sitewide/atwho_res.js.erb

581 lines
17 KiB
Plaintext
Raw Normal View History

2017-01-10 00:16:39 +08:00
var SmartAnnotation = (function() {
2017-01-05 17:52:00 +08:00
'use strict';
2017-01-09 18:33:28 +08:00
// utilities
var Util = (function() {
// helper method that binds show/hidden action
function showHideBinding() {
$.each(['show', 'hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
return el.apply(this, arguments);
};
});
}
var publicApi = {
showHideBinding: showHideBinding
};
return publicApi;
})();
2017-01-10 00:16:39 +08:00
function setAtWho(field) {
2017-01-11 00:05:32 +08:00
var dataUserUrl,
dataTaskUrl,
dataProjectUrl,
dataExperimentUrl,
dataSampleUrl,
dataMenuItemsUrl;
dataUserUrl = $(document.body).attr('data-atwho-users-url');
dataTaskUrl = $(document.body).attr('data-atwho-task-url');
dataProjectUrl = $(document.body).attr('data-atwho-project-url');
dataExperimentUrl = $(document.body).attr('data-atwho-experiment-url');
dataSampleUrl = $(document.body).attr('data-atwho-sample-url');
dataMenuItemsUrl = $(document.body).attr('data-atwho-menu-items').freeze;
2017-01-05 17:52:00 +08:00
2017-01-09 18:33:28 +08:00
// helper methods for AtWho callback
function _templateEval(_tpl, map) {
var res;
try {
res = generateTemplate(map);
} catch (_error) {
res = '';
}
return res;
}
2017-01-05 20:29:21 +08:00
2017-01-10 00:16:39 +08:00
function _matchHighlighter(li, query, search_filter) {
2017-01-09 18:33:28 +08:00
var re, li2, prevVal, newVal;
if (!query) {
return li;
}
2017-01-10 00:16:39 +08:00
resourcesChecker(query, search_filter);
2017-01-09 18:33:28 +08:00
li2 = $(li);
re = new RegExp(query, 'gi');
prevVal =
li2
.find('[data-val=name]')
.html();
newVal =
prevVal
.replace(re, '<strong>$&</strong>');
li2.find('[data-val=name]').html(newVal);
newVal =
prevVal
.replace(re, '<strong>$&</strong>');
li2.find('[data-val=email]').html(newVal);
return li2[0].outerHTML;
}
function _genrateInputTag(value, li) {
var res = '';
res += '[#' + li.attr('data-name');
res += '~' + li.attr('data-type');
res += '~' + li.attr('data-id') + ']';
return res;
}
// check if query has some hits and disables the buttons without it
function resourcesChecker(query, search_filter) {
2017-01-10 00:16:39 +08:00
var src_btn, $element;
2017-01-09 18:33:28 +08:00
switch (search_filter) {
case 'task#':
src_btn = 'tsk';
break;
case 'project#':
src_btn = 'prj';
break;
case 'experiment#':
src_btn = 'exp';
break;
default:
src_btn = 'sam';
break;
}
2017-01-05 20:29:21 +08:00
$.getJSON(
2017-01-11 00:05:32 +08:00
dataMenuItemsUrl,
2017-01-09 18:33:28 +08:00
{query: query},
function(data){
if(data) {
2017-01-11 00:05:32 +08:00
_.each($('.atwho-header-res .title .btn'), function(el) {
2017-01-10 00:16:39 +08:00
$element = $(el);
if(data[$element.data('filter')].length === 0) {
$element.prop('disabled', true);
$element
2017-01-09 18:33:28 +08:00
.removeClass('btn-primary')
.addClass('btn-default');
$('[data-filter="' + src_btn +'"]')
.removeClass('btn-default')
.addClass('btn-primary');
} else {
2017-01-10 00:16:39 +08:00
$element.prop('disabled', false);
if($element.data('filter') == src_btn) {
$element
.removeClass('btn-default')
.addClass('btn-primary');
} else {
$element
.removeClass('btn-primary')
.addClass('btn-default');
}
2017-01-09 18:33:28 +08:00
}
});
}
});
}
// reset the dropdown
function reinitializeOnListHide() {
Util.showHideBinding();
_.map($('.atwho-view'), function(el) {
$(el).off('hide');
$(el).on('hide', function() {
$(field).atwho('destroy');
init();
});
2017-01-05 20:29:21 +08:00
});
}
// initialise dropdown dismiss button
function initDismissButton() {
2017-01-11 00:05:32 +08:00
$('.atwho-header-res .dismiss').off('click');
$('.atwho-header-res .dismiss').on('click', function() {
$(field).atwho('destroy');
init();
});
}
// Initialize filter buttons
function initButtons(query, search_filter) {
$('.atwho-header-res query_obj button').off();
$('.atwho-header-res .dismiss').off('click');
initDismissButton();
2017-01-09 18:33:28 +08:00
resourcesChecker(query, search_filter);
2017-01-11 00:05:32 +08:00
$('.atwho-header-res .title button').on('click', function(e) {
2017-01-09 18:33:28 +08:00
var $button, $prevButton;
e.stopPropagation();
2017-01-10 21:13:37 +08:00
2017-01-09 18:33:28 +08:00
$button = $(this);
2017-01-11 00:05:32 +08:00
$prevButton = $button.closest('.title').children('.btn-primary');
2017-01-05 20:29:21 +08:00
switch ($button.attr('data-filter')) {
case 'prj':
2017-01-11 00:05:32 +08:00
generateNewQuery(dataProjectUrl,
2017-01-10 21:13:37 +08:00
$prevButton,
$button);
2017-01-05 20:29:21 +08:00
break;
case 'exp':
2017-01-11 00:05:32 +08:00
generateNewQuery(dataExperimentUrl,
2017-01-10 21:13:37 +08:00
$prevButton,
$button);
2017-01-05 20:29:21 +08:00
break;
case 'tsk':
2017-01-11 00:05:32 +08:00
generateNewQuery(dataTaskUrl,
2017-01-10 21:13:37 +08:00
$prevButton,
$button);
2017-01-05 20:29:21 +08:00
break;
case 'sam':
2017-01-11 00:05:32 +08:00
generateNewQuery(dataSampleUrl,
2017-01-10 21:13:37 +08:00
$prevButton,
$button);
2017-01-05 20:29:21 +08:00
break;
}
});
2017-01-09 18:33:28 +08:00
}
// Generates new query when user filters the results
function generateNewQuery(link, prevBtn, selectedBtn) {
2017-01-10 21:13:37 +08:00
var regexp, _a, _y, new_query, query_obj, field_selected;
2017-01-09 18:33:28 +08:00
_a = decodeURI("%C3%80");
_y = decodeURI("%C3%BF");
regexp = new RegExp("(#|task#|project#|sample#|experiment#)([A-Za-z" +
_a + "-" + _y + "0-9_ \'\.\+\-]*)$|" +
"(#|task#|project#|sample#|experiment#)([^\\x00-\\xff]*)$", 'gi');
2017-01-10 21:13:37 +08:00
// filters field if multiple input fields on the page
_.each($(field), function(e) {
if($(e).atwho('isSelecting')){
field_selected = e;
}});
if(field_selected) {
query_obj = regexp.exec($(field_selected).val());
2017-01-11 00:05:32 +08:00
if(query_obj) {
$.getJSON(
link,
{query: query_obj[2]},
function(data) {
if(data.res.length > 0 && field_selected) {
$(field_selected)
.atwho('load', query_obj[0], data.res)
.atwho('run');
prevBtn
.removeClass('btn-primary')
.addClass('btn-default');
selectedBtn
.removeClass('btn-default')
.addClass('btn-primary');
2017-01-09 18:33:28 +08:00
2017-01-11 00:05:32 +08:00
reinitializeOnListHide();
initButtons(query_obj[2],
selectedBtn.html());
} else {
$(field).atwho('destroy');
init();
}
});
}
}
2017-01-09 18:33:28 +08:00
}
// Generates suggestion dropdown filter
function generateFilterMenu(active, res_data) {
2017-01-11 00:05:32 +08:00
var header = '<div class="atwho-header-res">' +
'<div class="title">' +
'<button data-filter="prj" class="btn btn-xs ' +
2017-01-10 00:16:39 +08:00
(active === 'prj' ? 'btn-primary' : 'btn-default') + '">project#</button>' +
2017-01-11 00:05:32 +08:00
'<button data-filter="exp" class="btn btn-xs ' +
2017-01-10 00:16:39 +08:00
(active === 'exp' ? 'btn-primary' : 'btn-default') + '">experiment#</button>' +
2017-01-11 00:05:32 +08:00
'<button data-filter="tsk" class="btn btn-xs ' +
2017-01-10 00:16:39 +08:00
(active === 'tsk' ? 'btn-primary' : 'btn-default') + '">task#</button>' +
2017-01-11 00:05:32 +08:00
'<button data-filter="sam" class="btn btn-xs ' +
2017-01-10 00:16:39 +08:00
(active === 'sam' ? 'btn-primary' : 'btn-default') + '">sample#</button>' +
2017-01-11 00:05:32 +08:00
'</div>' +
2017-01-09 18:33:28 +08:00
'<div class="help">' +
'<div>' +
'<strong><%= I18n.t("atwho.users.navigate_1") %></strong> ' +
'<%= I18n.t("atwho.users.navigate_2") %>' +
'</div>' +
'<div><strong><%= I18n.t("atwho.users.confirm_1") %></strong> ' +
'<%= I18n.t("atwho.users.confirm_2") %>' +
'</div>' +
'<div>' +
'<strong><%= I18n.t("atwho.users.dismiss_1") %></strong> ' +
'<%= I18n.t("atwho.users.dismiss_2") %>' +
'</div>' +
'<div class="dismiss">' +
'<span class="glyphicon glyphicon-remove"></span>' +
'</div>' +
'</div>' +
'</div>';
2017-01-05 20:29:21 +08:00
2017-01-09 18:33:28 +08:00
return header;
2017-01-05 20:29:21 +08:00
}
2017-01-05 17:52:00 +08:00
// Generates resources list items
function generateTemplate(map) {
var res = '';
2017-01-09 18:33:28 +08:00
res += '<li class="atwho-li atwho-li-res" data-name="' +
map.name + '" data-id="' + map.id + '" data-type="' +
map.type + '">';
2017-01-05 17:52:00 +08:00
switch(map.type) {
case 'tsk':
res += '<span data-type class="res-type">' + map.type + '</span>';
break;
case 'prj':
res += '<span data-type class="res-type">' + map.type + '</span>';
break;
case 'exp':
res += '<span data-type class="res-type">' + map.type + '</span>';
break;
case 'sam':
res += '<span class="glyphicon glyphicon-tint"></span>';
break;
}
res += '&nbsp;';
2017-01-11 00:05:32 +08:00
res += '<span data-val="name" class="res-name">';
2017-01-05 17:52:00 +08:00
res += map.name;
res += '</span>';
2017-01-10 21:13:37 +08:00
if(map.archived) {
res += '<%= I18n.t("atwho.res.archived") %></span>';
2017-01-11 00:05:32 +08:00
} else {
res += '</span>';
2017-01-10 21:13:37 +08:00
}
2017-01-05 17:52:00 +08:00
res += '&nbsp;';
switch (map.type) {
case 'tsk':
2017-01-10 21:13:37 +08:00
2017-01-11 00:05:32 +08:00
res += '<span class="res-description">&lt; ' + map.experimentName +
2017-01-05 17:52:00 +08:00
' &lt; ' + map.projectName + '</span>';
break;
case 'exp':
2017-01-11 00:05:32 +08:00
res += '<span class="res-description">&lt; ' + map.projectName + '</span>';
2017-01-05 17:52:00 +08:00
break;
case 'sam':
2017-01-11 00:05:32 +08:00
res += '<span class="res-description">' + map.description + '</span>';
2017-01-05 17:52:00 +08:00
break;
}
res += '</li>';
return res;
}
function init() {
2017-01-09 18:33:28 +08:00
$(field)
2017-01-11 00:05:32 +08:00
.atwho({
at: '@',
callbacks: {
remoteFilter: function(query, callback) {
$.getJSON(
dataUserUrl,
{query: query},
function(data) {
callback(data.users);
initDismissButton();
2017-01-11 00:05:32 +08:00
}
);
},
sorter: function(query, items, _searchKey) {
// Sorting is already done on server-side
return items;
},
tplEval: function(_tpl, map) {
var res;
try {
res = '';
res += '<li class="atwho-li atwho-li-user" ';
res += 'data-id="' + map.id + '" ';
res += 'data-full-name="' + map.full_name + '">';
res += '<img src="' + map.img_url + '" class="avatar" />';
res += '<span data-val="full-name">';
res += map.full_name;
res += '</span>';
res += '<small>';
res += '&nbsp;';
res += '&#183;';
res += '&nbsp;';
res += '<span data-val="email">';
res += map.email;
res += '</span>';
res += '</small>';
res += '</li>';
} catch (_error) {
res = '';
}
return res;
},
highlighter: function(li, query) {
function highlight(el, sel, re) {
var prevVal = el.find(sel).html();
var newVal = prevVal.replace(re, '<strong>$&</strong>');
el.find(sel).html(newVal);
}
if (!query) {
return li;
}
var $li = $(li);
var re = new RegExp(query, 'gi');
highlight($li, '[data-val=full-name]', re);
highlight($li, '[data-val=email]', re);
return $li[0].outerHTML;
},
beforeInsert: function(value, li) {
var res = '';
res += '[@' + li.attr('data-full-name');
res += '~' + li.attr('data-id') + ']';
return res;
}
},
headerTpl:
'<div class="atwho-header-res">' +
'<div class="title title-user"><%= I18n.t("atwho.users.title") %></div>' +
2017-01-11 00:05:32 +08:00
'<div class="help">' +
'<div>' +
'<strong><%= I18n.t("atwho.users.navigate_1") %></strong> ' +
'<%= I18n.t("atwho.users.navigate_2") %>' +
'</div>' +
'<div>' +
'<strong><%= I18n.t("atwho.users.confirm_1") %></strong> ' +
'<%= I18n.t("atwho.users.confirm_2") %>' +
'</div>' +
'<div>' +
'<strong><%= I18n.t("atwho.users.dismiss_1") %></strong> ' +
'<%= I18n.t("atwho.users.dismiss_2") %>' +
'</div>' +
'<div class="dismiss">' +
'<span class="glyphicon glyphicon-remove"></span>' +
'</div>' +
'</div>' +
'</div>',
limit: <%= Constants::ATWHO_SEARCH_LIMIT %>,
startsWithSpace: true,
acceptSpaceBar: true,
displayTimeout: 120000
})
2017-01-09 18:33:28 +08:00
.atwho({
at: '#',
callbacks: {
remoteFilter: function(query, callback) {
$.getJSON(
2017-01-11 00:05:32 +08:00
dataSampleUrl,
2017-01-09 18:33:28 +08:00
{query: query},
function(data) {
callback(data.res);
initButtons(query);
2017-01-05 17:52:00 +08:00
}
2017-01-09 18:33:28 +08:00
);
},
tplEval: function(_tpl, map) {
return _templateEval(_tpl, map);
2017-01-05 17:52:00 +08:00
},
2017-01-09 18:33:28 +08:00
highlighter: function(li, query) {
2017-01-10 00:16:39 +08:00
return _matchHighlighter(li, query, '#');
2017-01-09 18:33:28 +08:00
},
beforeInsert: function(value, li) {
return _genrateInputTag(value, li);
}
},
headerTpl: generateFilterMenu('sam'),
2017-01-11 00:05:32 +08:00
limit: <%= Constants::ATWHO_SEARCH_LIMIT %>,
2017-01-09 18:33:28 +08:00
startWithSpace: true,
acceptSpaceBar: true,
displayTimeout: 120000
})
.atwho({
at: 'task#',
callbacks: {
remoteFilter: function(query, callback) {
$.getJSON(
2017-01-11 00:05:32 +08:00
dataTaskUrl,
2017-01-09 18:33:28 +08:00
{query: query},
function(data) {
callback(data.res);
initButtons(query, 'task#');
2017-01-05 17:52:00 +08:00
}
2017-01-09 18:33:28 +08:00
);
},
tplEval: function(_tpl, map) {
return _templateEval(_tpl, map);
2017-01-05 17:52:00 +08:00
},
2017-01-09 18:33:28 +08:00
highlighter: function(li, query) {
2017-01-10 00:16:39 +08:00
return _matchHighlighter(li, query, 'task#');
2017-01-09 18:33:28 +08:00
},
beforeInsert: function(value, li) {
return _genrateInputTag(value, li);
}
},
headerTpl: generateFilterMenu('tsk'),
2017-01-11 00:05:32 +08:00
limit: <%= Constants::ATWHO_SEARCH_LIMIT %>,
2017-01-09 18:33:28 +08:00
startWithSpace: true,
acceptSpaceBar: true,
displayTimeout: 120000
})
.atwho({
at: 'project#',
callbacks: {
remoteFilter: function(query, callback) {
$.getJSON(
2017-01-11 00:05:32 +08:00
dataProjectUrl,
2017-01-09 18:33:28 +08:00
{query: query},
function(data) {
callback(data.res);
initButtons(query, 'project#');
2017-01-05 17:52:00 +08:00
}
2017-01-09 18:33:28 +08:00
);
2017-01-05 17:52:00 +08:00
},
2017-01-09 18:33:28 +08:00
tplEval: function(_tpl, map) {
return _templateEval(_tpl, map);
},
highlighter: function(li, query) {
2017-01-10 00:16:39 +08:00
return _matchHighlighter(li, query, 'project#');
2017-01-09 18:33:28 +08:00
},
beforeInsert: function(value, li) {
return _genrateInputTag(value, li);
}
},
headerTpl: generateFilterMenu('prj'),
2017-01-11 00:05:32 +08:00
limit: <%= Constants::ATWHO_SEARCH_LIMIT %>,
2017-01-09 18:33:28 +08:00
startWithSpace: true,
acceptSpaceBar: true,
displayTimeout: 120000
})
.atwho({
at: 'experiment#',
callbacks: {
remoteFilter: function(query, callback) {
$.getJSON(
2017-01-11 00:05:32 +08:00
dataExperimentUrl,
2017-01-09 18:33:28 +08:00
{query: query},
function(data) {
callback(data.res);
initButtons(query, 'experiment#');
2017-01-05 17:52:00 +08:00
}
2017-01-09 18:33:28 +08:00
);
},
tplEval: function(_tpl, map) {
return _templateEval(_tpl, map);
},
highlighter: function(li, query) {
2017-01-10 00:16:39 +08:00
return _matchHighlighter(li, query, 'experiment#');
2017-01-05 17:52:00 +08:00
},
2017-01-09 18:33:28 +08:00
beforeInsert: function(value, li) {
return _genrateInputTag(value, li);
}
},
headerTpl: generateFilterMenu('exp'),
2017-01-11 00:05:32 +08:00
limit: <%= Constants::ATWHO_SEARCH_LIMIT %>,
2017-01-09 18:33:28 +08:00
startWithSpace: true,
acceptSpaceBar: true,
displayTimeout: 120000
})
.atwho({
at: 'sample#',
callbacks: {
remoteFilter: function(query, callback) {
$.getJSON(
2017-01-11 00:05:32 +08:00
dataSampleUrl,
2017-01-09 18:33:28 +08:00
{query: query},
function(data) {
callback(data.res);
initButtons(query);
2017-01-05 17:52:00 +08:00
}
2017-01-09 18:33:28 +08:00
);
2017-01-05 17:52:00 +08:00
},
2017-01-09 18:33:28 +08:00
tplEval: function(_tpl, map) {
return _templateEval(_tpl, map);
},
highlighter: function(li, query) {
2017-01-10 00:16:39 +08:00
return _matchHighlighter(li, query, 'sample#');
2017-01-09 18:33:28 +08:00
},
beforeInsert: function(value, li) {
return _genrateInputTag(value, li);
}
},
headerTpl: generateFilterMenu('sam'),
2017-01-11 00:05:32 +08:00
limit: <%= Constants::ATWHO_SEARCH_LIMIT %>,
2017-01-09 18:33:28 +08:00
startWithSpace: true,
acceptSpaceBar: true,
displayTimeout: 120000
});
2017-01-05 17:52:00 +08:00
}
2017-01-09 18:33:28 +08:00
return {
init: init
};
2017-01-05 17:52:00 +08:00
}
2017-01-10 00:16:39 +08:00
function initialize(field) {
var atWho = new setAtWho(field);
atWho.init();
}
2017-01-05 17:52:00 +08:00
2017-01-10 00:16:39 +08:00
var publicApi = {
init: initialize
};
2017-01-05 17:52:00 +08:00
2017-01-10 00:16:39 +08:00
return publicApi;
2017-01-05 17:52:00 +08:00
})();