diff --git a/addons/default/visiosoft/base-theme/resources/js/theme/modal.js b/addons/default/visiosoft/base-theme/resources/js/theme/modal.js new file mode 100644 index 000000000..2a478e37e --- /dev/null +++ b/addons/default/visiosoft/base-theme/resources/js/theme/modal.js @@ -0,0 +1,85 @@ +let initModal = function () { + + let modal = $('.modal.remote:not([data-initialized])'); + + let loading = ''; + + // Loading state + modal.on('loading', function() { + $(this).find('.modal-content').append(loading); + }); + + // Clear remote modals when closed. + modal.on('hidden.bs.modal', function () { + + $(this).removeData('bs.modal'); + + $(this).find('.modal-content').html(loading); + }); + + // Show loader for remote modals. + modal.on('show.bs.modal', function () { + $(this).find('.modal-content').html(loading); + }); + + // Handle ajax links in modals. + modal.on('click', 'a.ajax, .pagination a', function (e) { + + e.preventDefault(); + + let wrapper = $(this).closest('.modal-content'); + + wrapper.append(loading); + + $.get($(this).attr('href'), function (html) { + wrapper.html(html); + }); + }); + + // Handle ajax forms in modals. + modal.on('submit', 'form.ajax', function (e) { + + e.preventDefault(); + + let wrapper = $(this).closest('.modal-content'); + + wrapper.append(loading); + + if ($(this).attr('method') == 'GET') { + $.get($(this).attr('action'), $(this).serializeArray(), function (html) { + wrapper.html(html); + }); + } else { + $.post($(this).attr('action'), $(this).serializeArray(), function (html) { + wrapper.html(html); + }); + } + }); + + // Handle load indicators in modals. + modal.on('click', '[data-toggle="loader"]', function () { + + let wrapper = $(this).closest('.modal-content'); + + wrapper.append(loading); + }); + + // Mark as initialized. + modal.attr('data-initialized', ''); +}; + +$(document).ready(function () { + initModal(); +}); + +$(document).ajaxComplete(function () { + initModal(); +}); + +$(document).on('show.bs.modal', '.modal', function () { + let zIndex = 1040 + (10 * $('.modal:visible').length); + $(this).css('z-index', zIndex); + setTimeout(function() { + $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack'); + }, 0); +}); diff --git a/addons/default/visiosoft/base-theme/resources/js/theme/search.js b/addons/default/visiosoft/base-theme/resources/js/theme/search.js new file mode 100644 index 000000000..d73818e9e --- /dev/null +++ b/addons/default/visiosoft/base-theme/resources/js/theme/search.js @@ -0,0 +1,191 @@ +$(function () { + + var form = $('#search'); + var input = form.find('input'); + var list = form.find('.results'); + var items = list.find('a'); + var selected = null; + + // Don't submit on return. + form.on('submit', function () { + return false; + }); + + // Open search + input.on('focus', function () { + form.addClass('open'); + }); + + // Close search. + $(window).click(function () { + form.removeClass('open'); + }); + + form.click(function (e) { + e.stopPropagation(); + }); + + // Handle simple searching + input.on('keydown', function (e) { + + /** + * Capture the down arrow. + */ + if (e.which == 40) { + + if (selected) { + + /** + * If we have a selection then + * push to the next visible option. + */ + if (selected.nextAll('a:visible').length) { + items.removeClass('active'); + selected = selected.nextAll('a:visible').first(); + selected.addClass('active'); + } + } else { + + /** + * Otherwise select the first + * visible option in the list. + */ + selected = items.filter('a:visible').first(); + selected.addClass('active'); + } + } + + /** + * Capture the up arrow. + */ + if (e.which == 38) { + + if (selected) { + + /** + * If we have a selection then push + * to the previous visible option. + */ + if (selected.prevAll('a:visible').length) { + items.removeClass('active'); + selected = selected.prevAll('a:visible').first(); + selected.addClass('active'); + } + } else { + + /** + * Otherwise select the last + * visible option in the list. + */ + selected = items.filter('a:visible').last(); + selected.addClass('active'); + } + } + + /** + * Capture the enter key. + */ + if (e.which == 13) { + + if (selected) { + + /** + * If the key press was the return + * key and we have a selection + * then follow the link. + */ + if (selected.hasClass('has-click-event') || selected.hasClass('ajax')) { + selected.trigger('click'); + } else { + + /** + * If nothing is selected + * there's nothing to do. + */ + if (!selected.length) { + return false; + } + + /** + * If control or the meta key is + * being held open a new window. + */ + if (e.ctrlKey || e.metaKey) { + window.open(selected.attr('href'), "_blank"); + } else { + window.location = selected.attr('href'); + } + + input.val(''); + input.blur(); + form.removeClass('open'); + + modal.find('.modal-content').append(''); + } + } + } + + /** + * Capture up and down arrows. + */ + if (e.which == 38 || e.which == 40) { + + // store current positions in variables + var start = input[0].selectionStart, + end = input[0].selectionEnd; + + // restore from variables... + input[0].setSelectionRange(start, end); + + e.preventDefault(); + } + + /** + * Capture the escape key. + */ + if (e.which == 27) { + + form.removeClass('open'); + + items + .show() + .removeClass('active'); + + input.val('').blur(); + } + }); + + input.on('keyup', function (e) { + + /** + * If the keyup was a an arrow + * up or down then skip this step. + */ + if (e.which == 38 || e.which == 40) { + return; + } + + var value = $(this).val(); + + /** + * Filter the list by the items to + * show only those containing value. + */ + items.each(function () { + if ($(this).text().toLowerCase().indexOf(value.toLowerCase()) >= 0) { + $(this).show(); + } else { + $(this).hide(); + } + }); + + /** + * If we don't have a selected item + * then choose the first visible option. + */ + if (!selected || !selected.is(':visible')) { + selected = items.filter(':visible').first(); + selected.addClass('active'); + } + }); +}); diff --git a/addons/default/visiosoft/base-theme/resources/views/partials/assets.twig b/addons/default/visiosoft/base-theme/resources/views/partials/assets.twig index 48582c6d5..efae4833f 100644 --- a/addons/default/visiosoft/base-theme/resources/views/partials/assets.twig +++ b/addons/default/visiosoft/base-theme/resources/views/partials/assets.twig @@ -17,8 +17,9 @@ {{ asset_add("theme.js", "visiosoft.theme.base::js/script.js") }} {# Theme Scripts #} -{#{{ asset_add("theme.js", "visiosoft.theme.base::js/plugins/*") }}#} {{ asset_add("theme.js", "visiosoft.theme.base::js/theme/initialize.js") }} +{{ asset_add("theme.js", "visiosoft.theme.base::js/theme/search.js") }} +{{ asset_add("theme.js", "visiosoft.theme.base::js/theme/modal.js") }} {{ asset_script("theme.js") }} diff --git a/addons/default/visiosoft/singlefile-field_type/resources/js/upload.js b/addons/default/visiosoft/singlefile-field_type/resources/js/upload.js index 5aaa7684f..f4e39538c 100644 --- a/addons/default/visiosoft/singlefile-field_type/resources/js/upload.js +++ b/addons/default/visiosoft/singlefile-field_type/resources/js/upload.js @@ -64,9 +64,6 @@ $(function () { var response = JSON.parse(file.xhr.response); uploaded.push(response.id); - $('[data-provides="visiosoft.field_type.singlefile"]').val(response.id) - $('#file-modal').modal('hide'); - $('#profile-detail').submit(); file.previewElement.querySelector('[data-dz-uploadprogress]').setAttribute('class', 'progress progress-success'); @@ -83,4 +80,12 @@ $(function () { alert(message.error ? message.error : message); }); + + // When all files are processed. + dropzone.on('queuecomplete', function () { + + uploader.find('.uploaded .modal-body').html(element.data('loading') + '...'); + + uploader.find('.uploaded').load(REQUEST_ROOT_PATH + '/streams/singlefile-field_type/recent?uploaded=' + uploaded.join(',')); + }); });