{% set attr = _args.attr|default({}) %}
{% set attr = attr|merge({
class: 'sidepanel %s'|format(
attr.class|default('')
)|trim,
}) %}
{% set preserveScrool = _args.preserveScroll|default(false) %}
<div {{ attributes(attr) }}>
<button type="button" class="sidepanel__control sidepanel__cancel" data-dismiss="sidepanel" title="Cancel">
<i class="icon-glyph-chevron-right"></i>
</button>
<div class="sidepanel__wrapper">
<div class="sidepanel__head sidepanel__head--cols">
{% block header %}{% endblock %}
</div>
<div class="sidepanel__content">
{% block content %}{% endblock %}
</div>
</div>
</div>
<script type="text/javascript">
(function (window, document, $, undefined) {
$(function () {
$('#{{ attr.id }}')
// load up the start page when showing, only if a target page is set
.on('show.cs.sidepanel', function (e) {
var $modal = $(e.target),
$trigger = $(e.relatedTarget);
if ($trigger.length && $trigger.is('a[href][href!=""][href!="#"]:not([href^="#"])')) {
let $form = $($trigger.data('form'));
$modal
.addClass('modal-ajax')
.addClass('modal-ajax-loading')
.trigger('navigate.cs.modal', {
url: $trigger.attr('href'),
data: $form ? $form.serialize() : null,
method: $form ? 'POST' : 'GET',
});
}
})
.on('shown.cs.sidepanel', function (e) {
var $modal = $(e.target);
$modal.removeClass('modal-ajax-loading');
})
// once hidden, wipe the html content
.on('hidden.cs.sidepanel', function (e) {
var $modal = $(e.target);
if ($modal.is('.modal-ajax')) {
$modal
.removeClass('modal-ajax-loading')
.removeClass('modal-ajax');
$modal.find('.sidepanel__wrapper').html('');
}
})
// special event handling for "navigating" within the modal
.on('navigate.cs.modal', function (e, opts) {
var $elem = $(e.target),// element the even is being triggered on, can be anything
$modal = $('#{{ attr.id }}'),// get the modal wrapper/main element
$ajax = $.ajax($.extend({}, {
method: 'GET',
xhrFields: {
withCredentials: true
}
}, opts));// ajax call to get the url
// fade out the existing content
$modal.find('.sidepanel__wrapper .sidepanel__content').addClass('ajax-disabled');
// save the original scroll top value
const $originalScrollTop = $modal.find('.sidepanel__content').scrollTop();
// handle success
$ajax.done(function (resp) {
// TODO: wait for animation then set the html on the element
$modal.find('.sidepanel__wrapper').html(resp);
{% if preserveScrool %}
$modal.find('.sidepanel__content').scrollTop($originalScrollTop);
{% endif %}
});
// TODO: handle errors
$ajax.fail(function () {
//alert('ERROR!');
});
// fade the content back in when done
$ajax.always(function () {
// TODO: need to wait for animations
$modal
.removeClass('ajax-disabled');
// scroll to the top of the modal
// TODO: probably need to fix this...
$modal.scrollTop(0);
// in case we need to run things after a modal reload
$modal.trigger('updated.cs.modal');
});
})
// handle special event of form ajax submission
.on('submission.cs.modal', function (e, opts) {
var $elem = $(e.target),// the element that triggered the form load
$modal = $('#{{ attr.id }}'),// get the modal wrapper/main element
$ajax = $.ajax($.extend({}, {
xhrFields: {
withCredentials: true
}
}, opts));// ajax call for the form submission
// fade out the content
$modal.find('.sidepanel__wrapper .sidepanel__content').addClass('ajax-disabled');
// save the original scroll top value
const $originalScrollTop = $modal.find('.sidepanel__content').scrollTop();
// handle success
$ajax.done(function (resp) {
// check if we have an object or not
// this chunk of code handles non-html returns
// these special cases allow for basic redirection or modal closing
if (typeof resp === 'object') {
switch (true) {
// set a "close" key on the json object to TRUE in order to simply close the modal
// no page reload or anything will occur, the modal simply closes
case (resp.close === true):
$modal.trigger('do-hide.cs.sidepanel');
break;
// set a "redirect" key on the json object to TRUE in order to immediately reload the current URL in the browser
// this is useful for like modal form submissions
case (resp.redirect === true):
window.location.replace(window.location.origin + window.location.pathname + window.location.search);
break;
// the "redirect" key on the json object can also be set to a string
// in this case the string is expected to be a valid url pattern that the browser can understand
// this url will then be used to perform a redirection to the desired page
case (typeof resp.redirect === 'string'):
window.location.href = resp.redirect;
break;
}
} else {
// TODO: wait for animation then set the html on the element
$modal.find('.sidepanel__wrapper').html(resp);
{% if preserveScrool %}
$modal.find('.sidepanel__content').scrollTop($originalScrollTop);
{% endif %}
}
});
// TODO: handle errors
$ajax.fail(function () {
//alert('ERROR!');
});
// fade the content back in when done
$ajax.always(function () {
// TODO: wait for animation...
$modal
.removeClass('ajax-disabled');
// scroll to the top of the modal
// TODO: probably need to handle this somehow...
$modal.scrollTop(0);
// in case we need to run things after a modal reload
$modal.trigger('updated.cs.modal');
});
})
;
// register click handlers in the modal to capture and process navigating to different "screens" in the modal
$('#{{ attr.id }}')
// handle link clicks
.on('click', 'a[target="_modal"][href][href!="#"]:not([href^="#"])', function (e) {
var $link = $(e.currentTarget);// the link that was clicked
// need to prevent the default behavior
e.preventDefault();
// due to using this in the page editor stuff, we also need to stop the click propagation
e.stopPropagation();
// trigger the navigation
$link.trigger('navigate.cs.modal', {
url: $link.attr('href')
});
// to be safe, also return false
return false;
})
// handle form submissions, these need done through ajax otherwise the whole page will reload
.on('submit', 'form[target="_modal"]', function (e) {
var $form = $(e.currentTarget),// the form being submitted
$button = (e.originalEvent) ? $(e.originalEvent.submitter) : $(),// input button, if any, that was used to submit the form
data = $form.serializeArray();
// add button if there is a name on it
if ($button.attr('name')) {
data.push({
name: $button.attr('name'),
value: ($button.attr('value')) ? $button.attr('value') : ''
});
}
// we want to handle the submission, prevent the default
e.preventDefault();
// due to using this in the page editor stuff, we also need to stop the click propagation
e.stopPropagation();
// use the ajax submit
$form.trigger('submission.cs.modal', {
url: $button.attr('formaction') ? $button.attr('formaction') : $form.attr('action'),
method: $button.attr('formmethod') ? $button.attr('formmethod') : $form.attr('method'),
data: data
});
// to be safe, also return false
return false;
})
;
});
})(window, document, jQuery);
</script>
<style type="text/css">
.modal-ajax.modal-ajax-loading .modal-content {
display: none !important;
}
</style>