frontend/app/assets/javascripts/utils.js
//= require trimpath-template-1.0.38
//= require bootstrap-datepicker
//= require bootstrap-combobox
var AS = {}; // eslint-disable-line
// initialise ajax modal
$(function () {
AS.openAjaxModal = function (href) {
$('body').append('<div class="modal" id="tempAjaxModal"></div>');
var $modal = $('#tempAjaxModal');
$.ajax({
url: href,
async: false,
success: function (html) {
if ($(html).hasClass('modal')) {
$modal.remove();
$modal = $(html);
$('body').append($modal);
} else {
$modal.append(html);
}
$modal
.on('shown.bs.modal', function () {
$modal.find('input[type!=hidden]:first').focus();
})
.on('hidden.bs.modal', function () {
$modal.remove();
});
$modal.modal('show');
},
});
return $modal;
};
$('body').on('click', '[data-toggle=modal-ajax]', function (e) {
e.preventDefault();
AS.openAjaxModal($(this).attr('href'));
});
});
// add four part indentifier behaviour
$(function () {
var initIdentifierFields = function (scope) {
scope = scope || $(document.body);
$('form:not(.navbar-form) .identifier-fields:not(.initialised)', scope).on(
'keyup',
':input',
function (event) {
$(this).addClass('initialised');
var currentInputIndex = $(event.target).index();
$(event.target)
.parents('.identifier-fields:first')
.find(':input:eq(' + (currentInputIndex + 1) + ')')
.each(function () {
if (
$(event.target).val().length === 0 &&
$(this).val().length === 0
) {
$(this).attr('disabled', 'disabled');
} else {
$(this).removeAttr('disabled');
}
});
}
);
};
$(document).bind('loadedrecordform.aspace', function (event, $container) {
initIdentifierFields($container);
});
initIdentifierFields();
});
// sidebar action
$(function () {
var getSubMenuHTML = function (numberOfRecords) {
if (numberOfRecords < 1) {
return '';
} else {
return $(
"<span class='nav-list-record-count badge'>" +
numberOfRecords +
'</span>'
);
}
};
var refreshSidebarSubMenus = function () {
if ($('.readonly-context:first').length > 0) {
// this could be a read only page... so don't
// show the sub record bits
return;
}
$('.nav-list-record-count').remove();
$('#archivesSpaceSidebar .as-nav-list > li:not(.sidebar-heading)').each(
function () {
var $nav = $(this);
var $link = $('a', $nav);
var $section = $($link.attr('href'));
var $items = $('.subrecord-form-list:first > li', $section);
// Do not add a badge count to sidebar heading items (with class .sidebar-heading) -- only to entry items (with class .sidebar-entry-XXX)
if (!$nav.hasClass('sidebar-heading')) {
var $submenu = getSubMenuHTML($items.length);
$link.append($submenu);
}
}
);
};
var clearSelected = function () {
$('#archivesSpaceSidebar .as-nav-list > li:not(.sidebar-heading)').each(
function () {
$(this).attr('aria-selected', 'false');
}
);
};
var initSidebar = function () {
$('#archivesSpaceSidebar:not(.initialised)').each(function () {
$(this).affix({
offset: {
top: function () {
return $('#archivesSpaceSidebar').parent().offset().top;
},
bottom: 100,
},
});
$('a', $(this)).click(function (e) {
clearSelected();
$(this).parent().attr('aria-selected', 'true');
});
$(this).addClass('initialised');
});
refreshSidebarSubMenus();
};
initSidebar();
$(document).bind('loadedrecordform.aspace', function (event, $container) {
initSidebar();
});
$(document).bind(
'subrecordcreated.aspace subrecorddeleted.aspace formerrorready.aspace',
function () {
if ($('#archivesSpaceSidebar .nav-list.initialised').length > 0) {
refreshSidebarSubMenus();
// refresh scrollspy offsets.. as they are probably wrong now that things have changed in the form
$('[data-spy="scroll"]').scrollspy('refresh');
}
}
);
$(document).bind('resize.tree', function () {
// refresh scrollspy offsets.. as they are probably wrong now that things have changed in the form
$('[data-spy="scroll"]').scrollspy('refresh');
});
});
// date fields and datepicker initialisation
$.fn.combobox.defaults.template =
'<div class="combobox-container input-group"><input type="hidden" /><input type="text" autocomplete="off"/><span class="input-group-btn btn dropdown-toggle" data-dropdown="dropdown"><span class="caret"/><span class="combobox-clear"><span class="icon-remove"></span></span></span></div>';
$(function () {
var initDateFields = function (scope) {
scope = scope || $(document.body);
$('.date-field:not(.initialised)', scope).each(function () {
var $dateInput = $(this);
if ($dateInput.parent().is('.input-group')) {
$dateInput.parent().addClass('date');
} else {
$dateInput.wrap("<div class='input-group date'></div>");
}
$dateInput.addClass('initialised');
// ANW-170, ANW-490: Opt-in to datepicker
var $datepickerToggle = $(`
<span class="input-group-btn">
<button
class="btn btn-default"
type="button"
title="${$(this).data('label')}"
>
<i class='glyphicon glyphicon-calendar'></i>
</button>
</span>
`);
$dateInput.after($datepickerToggle);
let enableDatepicker = false;
$datepickerToggle.on('click', function () {
enableDatepicker = !enableDatepicker;
if (enableDatepicker) {
$(this).addClass('datepicker-enabled');
$dateInput.datepicker($dateInput.data());
$dateInput.trigger('focus').trigger('select');
} else {
$(this).removeClass('datepicker-enabled');
$dateInput.datepicker('destroy');
}
});
});
};
initDateFields();
$(document).bind('loadedrecordform.aspace', function (event, $container) {
initDateFields($container);
});
$(document).bind(
'subrecordcreated.aspace',
function (event, object_name, subform) {
initDateFields(subform);
}
);
$(document).bind('initdatefields.aspace', function (event, container) {
initDateFields(container);
});
});
// select fields and combobox initialisation
$(function () {
var initComboboxFields = function (scope) {
scope = scope || $(document.body);
$('select[data-combobox]:not(.initialised)', scope).each(function () {
var $selectInput = $(this);
$selectInput.data('combobox', null).addClass('initialised');
$selectInput.combobox();
});
};
initComboboxFields();
$(document).bind('loadedrecordform.aspace', function (event, $container) {
initComboboxFields($container);
});
$(document).bind(
'subrecordcreated.aspace',
function (event, object_name, subform) {
initComboboxFields(subform);
}
);
$(document).bind('initcomboboxfields.aspace', function (event, container) {
initComboboxFields(container);
});
});
// any element with a popover!
$(function () {
var initPopovers = function (scope) {
scope = scope || $(document.body);
$('.has-popover:not(.initialised)', scope).each(function () {
var $this = $(this);
// ANW-1325: Ensure tooltip content is focusable/hoverable by inserting in the DOM
// right after the triggering element.
var popoverOptions = {
delay: { show: 0, hide: 200 }, // if the popover contains a link, allow a few moments for that click to count
container: $this,
};
$this.popover(popoverOptions).addClass('initialised');
// ANW-1325: hide popovers if escape key pressed
$('.has-popover.initialised').on('show.bs.popover', function () {
$(document).keydown(function (e) {
if (e.keyCode === 27) $this.popover('hide');
});
});
});
};
initPopovers();
$(document).bind(
'loadedrecordform.aspace init.popovers',
function (event, $container) {
initPopovers($container);
}
);
$(document).bind(
'subrecordcreated.aspace',
function (event, object_name, subform) {
initPopovers(subform);
}
);
});
// any element with a tooltip!
$(function () {
var initTooltips = function (scope) {
scope = scope || $(document.body);
$('.has-tooltip:not(.initialised)', scope).each(function () {
var $this = $(this);
var helpTooltips =
$this.data('trigger') === 'manual' &&
($this.is('label.control-label') ||
$this.is('.btn-with-tooltip') ||
$this.is('.subrecord-form-heading-label'));
// ANW-1325: Ensure tooltip content is focusable/hoverable by inserting in the DOM
// right after the triggering element. Skipping `helpTooltips`, since those are
// made sticky in the block below.
var tooltipOptions = {
container: !helpTooltips ? $this : 'body',
};
$this.tooltip(tooltipOptions).addClass('initialised');
// ANW-1325: hide popovers if escape key pressed
$('.has-tooltip.initialised').on('show.bs.tooltip', function () {
$(document).keydown(function (e) {
if (e.keyCode === 27) $this.tooltip('hide');
});
});
// for manual ArchiveSpace help tooltips
if (helpTooltips) {
var openedViaClick = false;
var showTimeout, hideTimeout;
var onMouseEnter = function () {
if (openedViaClick) return;
clearTimeout(hideTimeout);
showTimeout = setTimeout(function () {
showTimeout = null;
$this.tooltip('show');
}, $this.data('delay') || 500);
$this.off('mouseleave').on('mouseleave', onMouseLeave);
};
var onMouseLeave = function () {
if (showTimeout) {
clearTimeout(showTimeout);
} else {
hideTimeout = setTimeout(function () {
$this.tooltip('hide');
}, 100);
}
};
var onClick = function () {
clearTimeout(showTimeout);
if (openedViaClick) {
$this.tooltip('hide');
openedViaClick = false;
return;
}
$this.off('mouseleave');
$this.tooltip('show');
$('.tooltip-inner', $this.data('bs.tooltip').$tip).prepend(
'<span class="tooltip-close glyphicon glyphicon-remove-circle icon-white"></span>'
);
$('.tooltip-close', $this.data('bs.tooltip').$tip).click(function () {
$this.trigger('click');
});
openedViaClick = true;
};
// bind event callbacks
$this.bind('mouseenter', onMouseEnter).click(onClick);
}
});
};
initTooltips();
$(document).bind('loadedrecordform.aspace', function (event, $container) {
initTooltips($container);
});
$(document).bind(
'subrecordcreated.aspace',
function (event, object_name, subform) {
initTooltips(subform);
}
);
$(document).bind('shown.bs.modal', function (events) {
$('.modal-content').delegate($('.has-tooltip'), 'mouseenter', function () {
initTooltips($(this));
$('a.has-tooltip', $(this)).on('click', function () {
window.open($(this).attr('href'));
});
});
});
});
// allow click of a submenu link
$(function () {
var initSubmenuLink = function (scope) {
scope = scope || $(document.body);
$(scope)
.on(
'click',
".dropdown-submenu > a[href*='javascript:void']:not(.initialised)",
function (e) {
e.preventDefault();
e.stopImmediatePropagation();
$(this).focus();
}
)
.addClass('initialised');
};
initSubmenuLink();
$(document).bind('loadedrecordform.aspace', function (event, $container) {
initSubmenuLink($container);
});
$(document).bind(
'subrecordcreated.aspace init.popovers',
function (event, object_name, subform) {
initSubmenuLink(subform);
}
);
});
// templates as defined in app/views/_model_/_template.html.erb are added to the DOM as HTML comments wrapped in a div. This method queries for the template we are looking for, uncomments it, and returns it for insertion back into the DOM.
AS.templateCache = [];
AS.renderTemplate = function (templateId, data, cb) {
if (!AS.templateCache[templateId]) {
var templateNode = $('#' + templateId).get(0);
if (templateNode) {
var firstNode = templateNode.firstChild;
var template = null;
// Check whether the template is wrapped in <!-- -->
if (firstNode && (firstNode.nodeType === 8 || firstNode.nodeType === 4)) {
template = firstNode.data.toString();
} else {
template = templateNode.innerHTML.toString();
}
// Parse the template through TrimPath and add the parsed template to the template cache
AS.templateCache[templateId] = TrimPath.parseTemplate(
template,
templateId
);
}
}
return AS.templateCache[templateId].process(data);
};
AS.quickTemplate = function (templateHTML, data) {
return TrimPath.parseTemplate(templateHTML).process(data);
};
AS.stripHTML = function (string) {
if (string === null || string === undefined) {
return '';
}
var rex = /(<([^>]+)>)/gi;
return $.trim(string.replace(rex, ''));
};
AS.encodeForAttribute = function (string) {
if (string === null || string === undefined) {
return '';
}
return $.trim(string.replace(/"/g, '"').replace(/(\r\n|\n|\r)/gm, ''));
};
AS.openQuickModal = function (title, message) {
AS.openCustomModal(
'quickModal',
title,
AS.renderTemplate('modal_quick_template', { message: message })
);
};
/* AS.openCustomModal
* id : String - id of the modal element
* title : String - to be applied as the modal header
* contents : String/HTML - the contents of the modal
* size : String/false - 'full'-98% of screen, 'large' - larger modal, 'container' - match the container width, false-standard modal size
* modalOpts : object - any twitter bootstrap options to pass on the modal dialog upon init.
* initiatedBy : Element - the link/button that initiated the modal. This element will be focused again upon close.
*/
AS.openCustomModal = function (
id,
title,
contents,
modalSize,
modalOpts,
initiatedBy
) {
var templateData = {
id: id,
title: title,
content: '',
};
// phase out the class on .modal in favor of .modal-dialog
if (modalSize === 'large') {
templateData.dialogClass = 'modal-lg';
templateData.fill = false;
} else if (modalSize == 'full') {
templateData.dialogClass = 'modal-jumbo';
templateData.fill = false;
} else {
templateData.fill = modalSize;
templateData.dialogClass = false;
}
$('body').append(AS.renderTemplate('modal_custom_template', templateData));
var $modal = $('#' + id);
$modal.find('.modal-content').append(contents);
$modal.on('hidden.bs.modal', function () {
$modal.remove();
$(window).unbind('resize', resizeModal);
if (initiatedBy) {
$(initiatedBy).focus();
}
});
var resizeModal = function () {
var height;
if (modalSize === 'full' || modalSize === 'large') {
height = $(window).height() - $(window).height() * 0.03;
} else {
height = $(window).height() - $(window).height() * 0.2;
}
$modal.height(height); // -20% for 10% top and bottom margins
var modalBodyHeight =
$modal.height() -
$('.modal-header', $modal).outerHeight() -
$('.modal-footer', $modal).outerHeight() -
95;
$('.modal-body', $modal).height(modalBodyHeight);
// $modal.css("marginLeft", -$modal.width() / 2);
};
if (modalSize) {
$modal.on('shown resize', resizeModal);
$(window).resize(resizeModal);
}
if (modalOpts) {
$modal.modal(modalOpts);
}
// reset the tab index within the modal
$modal.attr('tabindex', 0).focus();
$modal.modal('show');
$('.linker:not(.initialised)', $modal).linker();
return $modal;
};
$.fn.serializeObject = function () {
var o = {};
$(this).each(function () {
if ($(this).is('form')) {
var a = $(this).serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
} else {
// NOTE: THIS DOESN'T WORK FOR RADIO ELEMENTS (YET)
$(':input', this).each(function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push($(this).val() || '');
} else {
o[this.name] = $(this).val() || '';
}
});
}
});
return o;
};
$.fn.setValuesFromObject = function (obj) {
// NOTE: THIS DOESN'T WORK FOR RADIO ELEMENTS (YET)
var $this = this;
$.each(obj, function (name, value) {
$("[name='" + name + "']", $this).val(value);
});
};
AS.addControlGroupHighlighting = function (parent) {
$('.form-group :input', parent)
.on('focus', function () {
$(this).parents('.form-group:first').addClass('active');
})
.on('blur', function () {
$(this).parents('.form-group:first').removeClass('active');
});
};
// confirmation behaviour for subform-remove actions
AS.confirmSubFormDelete = function (subformRemoveButtonEl, onConfirmCallback) {
// Hide any others that were selected first
$('.cancel-removal:visible').trigger('click');
var confirmationEl = $(
AS.renderTemplate('subform_remove_confirmation_template')
);
confirmationEl.hide();
subformRemoveButtonEl.hide();
subformRemoveButtonEl.before(confirmationEl);
confirmationEl.fadeIn(function () {
$('.confirm-removal', confirmationEl).focus();
});
$('.cancel-removal', confirmationEl).click(function (event) {
confirmationEl.remove();
subformRemoveButtonEl.fadeIn();
return false;
});
$('.confirm-removal', confirmationEl).click(function (event) {
event.preventDefault();
event.stopPropagation();
onConfirmCallback($(event.target));
return false;
});
return false;
};
// extra add button plugin for subrecord forms
AS.initAddAsYouGoActions = function ($form, $list) {
if ($form.data('cardinality') === 'zero_to_one') {
// nothing to do here
return;
}
// delete any existing subrecord-add-as-you-go-actions
$('.subrecord-add-as-you-go-actions', $form).remove();
var $asYouGo = $("<div class='subrecord-add-as-you-go-actions'></div>");
$form.append($asYouGo);
var numberOfSubRecords = function () {
return $('> li', $list).length;
};
var bindEvents = function () {
$form
.off('subrecordcreated.aspace')
.on('subrecordcreated.aspace', function () {
$asYouGo.fadeIn();
});
$form
.off('subrecorddeleted.aspace')
.on('subrecorddeleted.aspace', function () {
if (numberOfSubRecords() === 0) {
$asYouGo.hide();
}
});
};
var init = function () {
if (numberOfSubRecords() === 0) {
$asYouGo.hide();
}
var btnsToReplicate = $(
'.subrecord-form-heading:first > .btn, .subrecord-form-heading:first > .custom-action > .btn',
$form
);
btnsToReplicate = btnsToReplicate.map(function () {
var $btn = $(this);
if ($btn.hasClass('show-all') && numberOfSubRecords() < 5) return;
else return this;
});
var fillToPercentage = 100; // full width
btnsToReplicate.each(function () {
var $btn = $(this);
var $a = $("<a href='#'>+</a>");
var btnText = $btn.val().length ? $btn.val() : $btn.text();
$a.css(
'width',
Math.floor(fillToPercentage / btnsToReplicate.length) + '%'
);
if (btnsToReplicate.length > 1) {
// we need to differentiate the links
$a.text(btnText);
$a.addClass('has-label');
if ($btn.hasClass('show-all')) {
$a.addClass('show-all');
}
} else {
// just add a title and we'll have a '+'
$a.attr('title', btnText);
}
$a.click(function (e) {
e.preventDefault();
e.stopPropagation();
$btn.trigger('click');
});
$asYouGo.append($a);
});
bindEvents();
};
init();
};
// Used by all tree layouts -- sets the initial height for the tree pane... but can
// be overridden by a user's cookie value
AS.DEFAULT_TREE_PANE_HEIGHT = 100;
AS.resetScrollSpy = function () {
// reset the scrollspy plugin
// so the headers update the status of the sidebar
$(document.body).removeData('scrollspy');
$(document.body).scrollspy({
target: '#archivesSpaceSidebar',
offset: 20,
});
};
AS.delayedTypeAhead = function (source, delay) {
if (!delay) {
delay = 200;
}
return (function () {
var queued_requests = [];
var timer = undefined;
var startTimer = function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
var last_request = queued_requests.pop();
queued_requests = [];
source(last_request.query, last_request.process);
}, delay);
};
return {
handle: function (query, callback) {
queued_requests.push({ query: query, process: callback });
startTimer();
},
};
})();
};
AS.prefixed_cookie = function (cookie_name, value) {
var args = Array.prototype.slice.call(arguments, 0);
args[0] = COOKIE_PREFIX + '_' + args[0];
return $.cookie.apply(this, args);
};
// Sub Record Sorting
AS.initSubRecordSorting = function ($list) {
var $subform = $list.closest('.subrecord-form');
if (
$subform.data('cardinality') === 'zero_to_one' ||
$subform.data('sorting') === 'disabled'
) {
// nothing to do here
return;
}
if ($list.length) {
$list.children('li').each(function () {
var $child = $(this);
if (!$child.hasClass('sort-enabled')) {
var $handle = $("<div class='drag-handle'></div>");
if ($list.parent().hasClass('controls')) {
$handle.addClass('inline');
}
$(this).append($handle);
$(this).addClass('sort-enabled');
}
});
if ($list.data('sortable')) {
$list.sortable('destroy');
}
$list.sortable({
items: 'li',
handle: ' > .drag-handle',
forcePlaceholderSize: true,
forceHelperSize: true,
placeholder: 'sortable-placeholder',
tolerance: 'pointer',
helper: 'clone',
});
$list.off('sortupdate').on('sortupdate', function () {
$('form.aspace-record-form').triggerHandler('formchanged.aspace');
});
// ANW-429: trigger special event for agents merge form
$list.off('sortupdate').on('sortupdate', function () {
$($list).triggerHandler('mergesubformchanged.aspace');
});
}
};
// Add confirmation btn behaviour
$(function () {
$.fn.initConfirmationAction = function () {
$(this).each(function () {
var $this = $(this);
if ($this.hasClass('initialised')) {
return;
}
$this.addClass('initialised');
var template_data = {
message: $this.data('message') || '',
title: $this.data('title') || 'Are you sure?',
confirm_label: $this.data('confirm-btn-label') || false,
confirm_class: $this.data('confirm-btn-class') || false,
};
var onClick = function (event) {
event.preventDefault();
event.stopImmediatePropagation();
AS.openCustomModal(
'confirmChangesModal',
template_data.title,
AS.renderTemplate('confirmation_modal_template', template_data),
null,
{},
$this
);
$('#confirmButton', '#confirmChangesModal').click(function () {
$('.btn', '#confirmChangesModal').attr('disabled', 'disabled');
var $form = $('<form>')
.attr('action', $this.data('target') || $this.attr('href'))
.attr('accept-charset', 'UTF-8')
.attr('method', $this.data('method') || 'post');
if ($this.data('authenticity_token')) {
var $h = $("<input type='hidden'>");
$h.attr('name', 'authenticity_token').val(
$this.data('authenticity_token')
);
$form.append($h);
}
if ($this.data('form-data')) {
$.each($this.data('form-data'), function (name, value) {
if (typeof value === 'object') {
$.each(value, function (i, val) {
var $h = $("<input type='hidden'>");
$h.attr('name', name + '[]').val(val);
$form.append($h);
});
} else {
var $h = $("<input type='hidden'>");
$h.attr('name', name).val(value);
$form.append($h);
}
});
}
$(document.body).append($form);
$form.submit();
});
};
$this.click(onClick);
});
};
$(document).ready(function () {
$(document).bind('loadedrecordform.aspace', function (event, $container) {
$(
'.btn[data-confirmation]:not(.initialised)',
$container
).initConfirmationAction();
});
$('.btn[data-confirmation]:not(.initialised)').initConfirmationAction();
});
});
// Set up some subrecord specific event bindings
$(document).bind(
'subrecordcreated.aspace',
function (event, object_name, newFormEl) {
newFormEl
.parents('.subrecord-form:first')
.triggerHandler('subrecordcreated.aspace');
}
);
$(document).bind('subrecorddeleted.aspace', function (event, formEl) {
formEl.triggerHandler('subrecorddeleted.aspace');
});
// Global AJAX setup
$(function () {
$.ajaxSetup({
beforeSend: function (xhr, settings) {
// if it's a POST, lets make sure the CSRF token is passed through
if (settings.type === 'POST') {
xhr.setRequestHeader(
'X-CSRF-Token',
$('meta[name="csrf-token"]').attr('content')
);
}
},
});
});
// Add close action to all alerts
$(function () {
var handleCloseAlert = function (event) {
event.stopPropagation();
event.preventDefault();
var $hideAlert = $(this);
$hideAlert
.hide()
.closest('.alert')
.slideUp(function () {
$hideAlert.show();
});
};
$.fn.initCloseAlertAction = function (event, $container) {
$(this).each(function () {
var $alert = $(this);
// add a close icon to the alert
var $close = $('<a>')
.attr('href', 'javascript:void(0);')
.addClass('hide-alert');
$close.attr('aria-label', 'Close Alert');
$close.append($('<span>').addClass('glyphicon glyphicon-remove'));
$close.click(handleCloseAlert);
$alert.prepend($close);
$alert.addClass('with-hide-alert');
});
};
$(document).ready(function () {
$(document).bind('loadedrecordform.aspace', function (event, $container) {
$('.alert', $container).initCloseAlertAction();
});
$('.alert:not(.with-hide-alert)').initCloseAlertAction();
});
});
// shortcuts
$(function () {
var initFormShortcuts = function () {
var $form = $(this);
};
$(document).bind('keydown', 'shift+/', function () {
if (!$('#ASModal').length) {
AS.openAjaxModal(AS.app_prefix('shortcuts'));
}
});
$(document).bind('keydown', 'esc', function () {
if ($('#ASModal').length) {
$('#ASModal').modal('hide').data('bs.modal', null);
}
});
$(document).bind('keydown', 'ctrl+x', function () {
$(document).trigger('formclosed.aspace');
});
$(document).bind('keydown', 'shift+b', function () {
$('li.browse-container a.dropdown-toggle').trigger('click.bs.dropdown');
});
$(document).bind('keydown', 'shift+c', function () {
$('li.create-container a.dropdown-toggle').trigger('click.bs.dropdown');
});
$(window).bind('keydown', function (event) {
if (event.ctrlKey || event.metaKey) {
switch (String.fromCharCode(event.which).toLowerCase()) {
case 's':
event.preventDefault();
console.log('ctrl-s');
break;
}
}
});
var traverseMenuDown = function () {
var $current = $(this).find('ul li.active');
var $next = $current.length ? $current.next() : $(this).find('li:first');
if ($next.length) {
$next.addClass('active');
$current.removeClass('active');
}
};
var traverseMenuUp = function () {
var $current = $(this).find('ul li.active');
var $next = $current.length ? $current.prev() : $(this).find('li:last');
if ($next.length) {
$next.addClass('active');
$current.removeClass('active');
}
};
var clickActive = function (e) {
e.preventDefault();
e.stopPropagation();
var $active = $(this).find('ul li.active');
if ($active.length) {
$active.find('a:first')[0].click();
}
};
$('li.dropdown').on({
'shown.bs.dropdown': function () {
$(this).bind('keydown', 'down', traverseMenuDown);
$(this).bind('keydown', 'up', traverseMenuUp);
$(this).bind('keydown', 'return', clickActive);
},
'hide.bs.dropdown': function () {
$(this).unbind('keydown', traverseMenuDown);
$(this).unbind('keydown', traverseMenuUp);
$(this).unbind('keydown', clickActive);
},
});
});
AS.app_prefix = function (path) {
return APP_PATH + path.replace(/^\//, '');
};
// Enable bootstrap-tagsinput for any elements with class 'js-taggable'
$(function () {
$(document).ready(function () {
$('.js-taggable').tagsinput({ confirmKeys: [13], delimiter: '|' });
});
});