Added views for QOR admin

This commit is contained in:
Nedim
2023-09-07 13:04:34 +02:00
parent 40c6366608
commit f02e5e49cb
180 changed files with 18556 additions and 2 deletions

View File

@@ -0,0 +1 @@
"use strict";$(function(){$(document).on("click.qor.alert",'[data-dismiss="alert"]',function(){$(this).closest(".qor-alert").removeClass("qor-alert__active")}),setTimeout(function(){$('.qor-alert[data-dismissible="true"]').removeClass("qor-alert__active")},5e3)}),$(function(){$(document).on("click",".qor-dialog--global-search",function(e){e.stopPropagation(),$(e.target).parents(".qor-dialog-content").length||$(e.target).is(".qor-dialog-content")||$(".qor-dialog--global-search").remove()}),$(document).on("click",".qor-global-search--show",function(e){e.preventDefault();var a=$(this).data(),o=window.Mustache.render('<div class="qor-dialog qor-dialog--global-search" tabindex="-1" role="dialog" aria-hidden="true"><div class="qor-dialog-content"><form action=[[actionUrl]]><div class="mdl-textfield mdl-js-textfield" id="global-search-textfield"><input class="mdl-textfield__input ignore-dirtyform" name="keyword" id="globalSearch" value="" type="text" placeholder="" /><label class="mdl-textfield__label" for="globalSearch">[[placeholder]]</label></div></form></div></div>',a);$("body").append(o),window.componentHandler.upgradeElement(document.getElementById("global-search-textfield")),$("#globalSearch").focus()})}),$(function(){var l=[],s="qoradmin_menu_status",e=localStorage.getItem(s);e&&e.length&&(l=e.split(",")),$(".qor-menu-container").on("click","> ul > li > a",function(){var e=$(this),a=e.parent(),o=e.next("ul"),t=a.attr("qor-icon-name");o.length&&(o.hasClass("in")?(l.push(t),a.removeClass("is-expanded"),o.one("transitionend",function(){o.removeClass("collapsing in")}).addClass("collapsing").height(0)):(l=_.without(l,t),a.addClass("is-expanded"),o.one("transitionend",function(){o.removeClass("collapsing")}).addClass("collapsing in").height(o.prop("scrollHeight"))),localStorage.setItem(s,l))}).find("> ul > li > a").each(function(){var e=$(this),a=e.parent(),o=e.next("ul"),t=a.attr("qor-icon-name");o.length&&(o.addClass("collapse"),a.addClass("has-menu"),-1!=l.indexOf(t)?o.height(0):(a.addClass("is-expanded"),o.addClass("in").height(o.prop("scrollHeight"))))});var a=$(".qor-page > .qor-page__header"),o=$(".qor-page > .qor-page__body"),t=a.find(".qor-page-subnav__header").length?96:48;a.length&&(a.height()>t&&o.css("padding-top",a.height()),$(".qor-page").addClass("has-header"),$("header.mdl-layout__header").addClass("has-action"))}),$(function(){$(".qor-mobile--show-actions").on("click",function(){$(".qor-page__header").toggleClass("actions-show")})}),$(function(){var p,m,q=$("body"),f="is-selected",b=function(){return q.hasClass("qor-bottomsheets-open")};function _(e){$("[data-url]").removeClass(f),e&&e.length&&e.addClass(f)}q.qorBottomSheets(),q.qorSlideout(),p=q.data("qor.slideout"),m=q.data("qor.bottomsheets"),$(document).on("click.qor.openUrl","[data-url]",function(e){var a,o=$(this),t=$(e.target),l=o.hasClass("qor-button--new"),s=o.hasClass("qor-button--edit"),n=(o.is(".qor-table tr[data-url]")||o.closest(".qor-js-table").length)&&!o.closest(".qor-slideout").length,r=o.data(),i=r.openType,d=o.parents(".qor-theme-slideout").length,c=o.closest(".qor-slideout").length,h=o.hasClass("qor-action-button")||o.hasClass("qor-action--button");if(e.stopPropagation(),!(o.data("ajax-form")||t.closest(".qor-table--bulking").length||t.closest(".qor-button--actions").length||!t.data("url")&&t.is("a")||n&&b()))if("window"!=i){var u,g;if("new_window"!=i)return h&&(u=$(".qor-js-table tbody").find(".mdl-checkbox__input:checked"),g=[],(a=!!u.length&&(u.each(function(){g.push($(this).closest("tr").data("primary-key"))}),g))&&(r=$.extend({},r,{actionData:a}))),r.$target=t,r.method&&"GET"!=r.method.toUpperCase()?void 0:("bottomsheet"!=i&&!h||"slideout"==i?"slideout"==i||n||l&&!b()||s?"slideout"==i||d?o.hasClass(f)?(p.hide(),_()):(p.open(r),_(o)):window.location.href=r.url:q.hasClass("qor-slideout-open")||l&&b()?m.open(r):d?p.open(r):m.open(r):h&&!a&&o.closest('[data-toggle="qor.action.bulk"]').length&&!c?window.QOR.qorConfirm(r.errorNoItem):m.open(r),!1);window.open(r.url,"_blank")}else window.location.href=r.url})}),$(function(){var l=window.location;$(".qor-search").each(function(){var e=$(this),a=e.find(".qor-search__input"),o=e.find(".qor-search__clear"),t=!!a.val();e.closest(".qor-page__header").addClass("has-search"),$("header.mdl-layout__header").addClass("has-search"),o.on("click",function(){a.val()||t?"?"==l.search.replace(new RegExp(a.attr("name")+"\\=?\\w*"),"")?l.href=l.href.split("?")[0]:l.search=l.search.replace(new RegExp(a.attr("name")+"\\=?\\w*"),""):e.removeClass("is-dirty")})})});

View File

@@ -0,0 +1,13 @@
$(function() {
'use strict';
$(document).on('click.qor.alert', '[data-dismiss="alert"]', function() {
$(this)
.closest('.qor-alert')
.removeClass('qor-alert__active');
});
setTimeout(function() {
$('.qor-alert[data-dismissible="true"]').removeClass('qor-alert__active');
}, 5000);
});

View File

@@ -0,0 +1,36 @@
$(function () {
'use strict';
var modal = (
'<div class="qor-dialog qor-dialog--global-search" tabindex="-1" role="dialog" aria-hidden="true">' +
'<div class="qor-dialog-content">' +
'<form action=[[actionUrl]]>' +
'<div class="mdl-textfield mdl-js-textfield" id="global-search-textfield">' +
'<input class="mdl-textfield__input ignore-dirtyform" name="keyword" id="globalSearch" value="" type="text" placeholder="" />' +
'<label class="mdl-textfield__label" for="globalSearch">[[placeholder]]</label>' +
'</div>' +
'</form>' +
'</div>' +
'</div>'
);
$(document).on('click', '.qor-dialog--global-search', function(e){
e.stopPropagation();
if (!$(e.target).parents('.qor-dialog-content').length && !$(e.target).is('.qor-dialog-content')){
$('.qor-dialog--global-search').remove();
}
});
$(document).on('click', '.qor-global-search--show', function(e){
e.preventDefault();
var data = $(this).data();
var modalHTML = window.Mustache.render(modal, data);
$('body').append(modalHTML);
window.componentHandler.upgradeElement(document.getElementById('global-search-textfield'));
$('#globalSearch').focus();
});
});

View File

@@ -0,0 +1,80 @@
$(function() {
'use strict';
let menuDatas = [],
storageName = 'qoradmin_menu_status',
lastMenuStatus = localStorage.getItem(storageName);
if (lastMenuStatus && lastMenuStatus.length) {
menuDatas = lastMenuStatus.split(',');
}
$('.qor-menu-container')
.on('click', '> ul > li > a', function() {
let $this = $(this),
$li = $this.parent(),
$ul = $this.next('ul'),
menuName = $li.attr('qor-icon-name');
if (!$ul.length) {
return;
}
if ($ul.hasClass('in')) {
menuDatas.push(menuName);
$li.removeClass('is-expanded');
$ul
.one('transitionend', function() {
$ul.removeClass('collapsing in');
})
.addClass('collapsing')
.height(0);
} else {
menuDatas = _.without(menuDatas, menuName);
$li.addClass('is-expanded');
$ul
.one('transitionend', function() {
$ul.removeClass('collapsing');
})
.addClass('collapsing in')
.height($ul.prop('scrollHeight'));
}
localStorage.setItem(storageName, menuDatas);
})
.find('> ul > li > a')
.each(function() {
let $this = $(this),
$li = $this.parent(),
$ul = $this.next('ul'),
menuName = $li.attr('qor-icon-name');
if (!$ul.length) {
return;
}
$ul.addClass('collapse');
$li.addClass('has-menu');
if (menuDatas.indexOf(menuName) != -1) {
$ul.height(0);
} else {
$li.addClass('is-expanded');
$ul.addClass('in').height($ul.prop('scrollHeight'));
}
});
let $pageHeader = $('.qor-page > .qor-page__header'),
$pageBody = $('.qor-page > .qor-page__body'),
triggerHeight = $pageHeader.find('.qor-page-subnav__header').length ? 96 : 48;
if ($pageHeader.length) {
if ($pageHeader.height() > triggerHeight) {
$pageBody.css('padding-top', $pageHeader.height());
}
$('.qor-page').addClass('has-header');
$('header.mdl-layout__header').addClass('has-action');
}
});

View File

@@ -0,0 +1,5 @@
$(function () {
$('.qor-mobile--show-actions').on('click', function () {
$('.qor-page__header').toggleClass('actions-show');
});
});

View File

@@ -0,0 +1,162 @@
$(function() {
"use strict";
let $body = $("body"),
Slideout,
BottomSheets,
CLASS_IS_SELECTED = "is-selected",
isSlideoutOpened = function() {
return $body.hasClass("qor-slideout-open");
},
isBottomsheetsOpened = function() {
return $body.hasClass("qor-bottomsheets-open");
};
$body.qorBottomSheets();
$body.qorSlideout();
Slideout = $body.data("qor.slideout");
BottomSheets = $body.data("qor.bottomsheets");
function toggleSelectedCss(ele) {
$("[data-url]").removeClass(CLASS_IS_SELECTED);
ele && ele.length && ele.addClass(CLASS_IS_SELECTED);
}
function collectSelectID() {
let $checked = $(".qor-js-table tbody").find(
".mdl-checkbox__input:checked"
),
IDs = [];
if (!$checked.length) {
return false;
}
$checked.each(function() {
IDs.push(
$(this)
.closest("tr")
.data("primary-key")
);
});
return IDs;
}
$(document).on("click.qor.openUrl", "[data-url]", function(e) {
let $this = $(this),
$target = $(e.target),
isNewButton = $this.hasClass("qor-button--new"),
isEditButton = $this.hasClass("qor-button--edit"),
isInTable =
($this.is(".qor-table tr[data-url]") ||
$this.closest(".qor-js-table").length) &&
!$this.closest(".qor-slideout").length, // if table is in slideout, will open bottom sheet
openData = $this.data(),
actionData,
openType = openData.openType,
hasSlideoutTheme = $this.parents(".qor-theme-slideout").length,
isInSlideout = $this.closest(".qor-slideout").length,
isActionButton =
$this.hasClass("qor-action-button") ||
$this.hasClass("qor-action--button");
e.stopPropagation();
// if clicking item's menu actions
if (
$this.data("ajax-form") ||
$target.closest(".qor-table--bulking").length ||
$target.closest(".qor-button--actions").length ||
(!$target.data("url") && $target.is("a")) ||
(isInTable && isBottomsheetsOpened())
) {
return;
}
if (openType == "window") {
window.location.href = openData.url;
return;
}
if (openType == "new_window") {
window.open(openData.url, "_blank");
return;
}
if (isActionButton) {
actionData = collectSelectID();
if (actionData) {
openData = $.extend({}, openData, {
actionData: actionData
});
}
}
openData.$target = $target;
if (!openData.method || openData.method.toUpperCase() == "GET") {
// Open in BottmSheet: is action button, open type is bottom-sheet
// is action button but opentype == slideout, should open in slideout\
// open type is No.1 priority
if (
(openType == "bottomsheet" || isActionButton) &&
openType != "slideout"
) {
// if is bulk action and no item selected
if (
isActionButton &&
!actionData &&
$this.closest('[data-toggle="qor.action.bulk"]').length &&
!isInSlideout
) {
window.QOR.qorConfirm(openData.errorNoItem);
return false;
}
BottomSheets.open(openData);
return false;
}
// Slideout or New Page: table items, new button, edit button
if (
openType == "slideout" ||
isInTable ||
(isNewButton && !isBottomsheetsOpened()) ||
isEditButton
) {
if (openType == "slideout" || hasSlideoutTheme) {
if ($this.hasClass(CLASS_IS_SELECTED)) {
Slideout.hide();
toggleSelectedCss();
return false;
} else {
Slideout.open(openData);
toggleSelectedCss($this);
return false;
}
} else {
window.location.href = openData.url;
return false;
}
}
// Open in BottmSheet: slideout is opened or openType is Bottom Sheet
if (isSlideoutOpened() || (isNewButton && isBottomsheetsOpened())) {
BottomSheets.open(openData);
return false;
}
// Other clicks
if (hasSlideoutTheme) {
Slideout.open(openData);
return false;
} else {
BottomSheets.open(openData);
return false;
}
}
});
});

View File

@@ -0,0 +1,33 @@
$(function () {
'use strict';
var location = window.location;
$('.qor-search').each(function () {
var $this = $(this);
var $input = $this.find('.qor-search__input');
var $clear = $this.find('.qor-search__clear');
var isSearched = !!$input.val();
var emptySearch = function () {
var search = location.search.replace(new RegExp($input.attr('name') + '\\=?\\w*'), '');
if (search == '?'){
location.href = location.href.split('?')[0];
} else {
location.search = location.search.replace(new RegExp($input.attr('name') + '\\=?\\w*'), '');
}
};
$this.closest('.qor-page__header').addClass('has-search');
$('header.mdl-layout__header').addClass('has-search');
$clear.on('click', function () {
if ($input.val() || isSearched) {
emptySearch();
} else {
$this.removeClass('is-dirty');
}
});
});
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,408 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let Mustache = window.Mustache,
QOR = window.QOR,
NAMESPACE = 'qor.action',
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_UNDO = 'undo.' + NAMESPACE,
CLASS_ACTION_FORMS = '.qor-action-forms',
CLASS_MENU_ACTIONS = '[data-ajax-form="true"][data-method]',
CLASS_BUTTON_BULKS = '.qor-action-bulk-buttons',
CLASS_TABLE = '.qor-page .qor-table-container',
CLASS_TABLE_BULK = '.qor-table--bulking',
CLASS_TABLE_BULK_TR = '.qor-table--bulking tbody tr',
CLASS_IS_UNDO = 'is_undo',
CLASS_TABLE_MDL = 'mdl-data-table--selectable',
CLASS_SLIDEOUT = '.qor-slideout',
ACTION_FORM_DATA = 'primary_values[]',
CLASS_HEADER_TOGGLE = '.qor-page__header .qor-actions, .qor-page__header .qor-search-container',
CLASS_BODY_LOADING = ".qor-body__loading";
function QorAction(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorAction.DEFAULTS, $.isPlainObject(options) && options);
this.ajaxForm = {};
this.init();
}
QorAction.prototype = {
constructor: QorAction,
init: function() {
this.bind();
this.initActions();
},
bind: function() {
this.$element.on(EVENT_CLICK, '.qor-action--bulk', this.renderBulkTable.bind(this)).on(EVENT_CLICK, '.qor-action--exit-bulk', this.removeBulkTable.bind(this));
$(document)
.on(EVENT_CLICK, CLASS_TABLE_BULK_TR, this.handleBulkTableClick.bind(this))
.on(EVENT_CLICK, CLASS_MENU_ACTIONS, this.clickAjaxButton.bind(this));
},
unbind: function() {
this.$element.off(EVENT_CLICK);
$(document)
.off(EVENT_CLICK, CLASS_TABLE_BULK_TR, this.handleBulkTableClick)
.off(EVENT_CLICK, CLASS_MENU_ACTIONS, this.clickAjaxButton);
},
initActions: function() {
if (!$(CLASS_TABLE).find('table').length) {
$(CLASS_BUTTON_BULKS).hide();
$('.qor-page__header a.qor-action--button').hide();
}
},
collectFormData: function() {
let checkedInputs = $(CLASS_TABLE_BULK).find('.mdl-checkbox__input:checked'),
formData = [],
normalFormData = [],
tempObj;
if (checkedInputs.length) {
checkedInputs.each(function() {
let id = $(this)
.closest('tr')
.data('primary-key');
tempObj = {};
if (id) {
formData.push({
name: ACTION_FORM_DATA,
value: id.toString()
});
tempObj[ACTION_FORM_DATA] = id.toString();
normalFormData.push(tempObj);
}
});
}
this.ajaxForm.formData = formData;
this.ajaxForm.normalFormData = normalFormData;
return this.ajaxForm;
},
actionSubmit: function($action) {
this.submit($action);
return false;
},
handleBulkTableClick: function(e) {
let $target = $(e.target).closest('tr'),
$firstTd = $target.find('td').first(),
$checkbox = $firstTd.find('.mdl-js-checkbox');
$checkbox.toggleClass('is-checked');
$target.toggleClass('is-selected');
$firstTd.find('input').prop('checked', $checkbox.hasClass('is-checked'));
return false;
},
adjustPageBodyStyle: function(isRender) {
let $pageHeader = $('.qor-page > .qor-page__header'),
$pageBody = $('.qor-page > .qor-page__body'),
triggerHeight = $pageHeader.find('.qor-page-subnav__header').length ? 96 : 48;
if (isRender) {
if ($pageHeader.height() > triggerHeight) {
$pageBody.css('padding-top', $pageHeader.height());
}
} else {
if (parseInt($pageBody.css('padding-top')) > triggerHeight) {
$pageBody.css('padding-top', '');
}
}
},
renderBulkTable: function() {
let $body = $('body');
if ($body.hasClass('qor-slideout-open')) {
$body.data('qor.slideout').hide();
}
$('.qor-table__inner-list').remove();
this.toggleBulkButtons();
this.enableTableMDL();
this.adjustPageBodyStyle(true);
},
removeBulkTable: function() {
this.toggleBulkButtons();
this.disableTableMDL();
this.adjustPageBodyStyle();
},
enableTableMDL: function() {
$(CLASS_TABLE)
.find('table')
.removeAttr('data-upgraded')
.addClass(CLASS_TABLE_MDL)
.trigger('enable');
},
disableTableMDL: function() {
$(CLASS_TABLE)
.find('table')
.removeClass(CLASS_TABLE_MDL)
.find('tr')
.removeClass('is-selected')
.find('td:first,th:first')
.remove();
},
toggleBulkButtons: function() {
this.$element.find(CLASS_ACTION_FORMS).toggle();
$(CLASS_BUTTON_BULKS)
.find('button')
.toggleClass('hidden');
$(CLASS_TABLE)
.toggleClass('qor-table--bulking')
.find('.qor-table__actions')
.toggle();
$(CLASS_HEADER_TOGGLE).toggle();
},
clickAjaxButton: function(e) {
let $target = $(e.target);
this.collectFormData();
this.ajaxForm.properties = $target.data();
this.submit($target);
return false;
},
renderFlashMessage: function(data) {
let flashMessageTmpl = QorAction.FLASHMESSAGETMPL;
Mustache.parse(flashMessageTmpl);
return Mustache.render(flashMessageTmpl, data);
},
addLoading: function() {
$(CLASS_BODY_LOADING).remove();
var $loading = $(QorAction.TEMPLATE_LOADING);
$loading.appendTo($("body")).trigger("enable.qor.material");
},
submit: function($actionButton) {
let _this = this,
ajaxForm = this.ajaxForm || {},
properties = ajaxForm.properties || $actionButton.data();
if($actionButton.hasClass("qor-action-disabled")){
return false;
}
if (properties.fromIndex && (!ajaxForm.formData || !ajaxForm.formData.length)) {
QOR.qorConfirm(ajaxForm.properties.errorNoItem);
return;
}
if (properties.confirm) {
QOR.qorConfirm(properties, function(confirm) {
if (confirm) {
_this.handleAjaxSubmit(ajaxForm, $actionButton);
} else {
return;
}
});
} else {
this.handleAjaxSubmit(ajaxForm, $actionButton);
}
},
handleAjaxSubmit: function(ajaxForm, $actionButton) {
let _this = this,
$element = this.$element,
$parent = $actionButton.closest(".qor-action-forms"),
properties = ajaxForm.properties || $actionButton.data(),
url = properties.url,
undoUrl = properties.undoUrl,
isUndo = $actionButton.hasClass(CLASS_IS_UNDO),
isInSlideout = $actionButton.closest(CLASS_SLIDEOUT).length,
needDisableButtons = $element.length && !isInSlideout;
if (isUndo) {
url = undoUrl; // notification has undo url
}
this.addLoading();
if($parent.length){
$parent.find('[data-ajax-form="true"][data-method]').addClass("qor-action-disabled");
} else {
$actionButton.addClass("qor-action-disabled");
}
$.ajax(url, {
method: properties.method,
data: ajaxForm.formData,
dataType: properties.datatype || 'json',
beforeSend: function() {
if (undoUrl) {
$actionButton.prop('disabled', true);
} else if (needDisableButtons) {
_this.switchButtons($element, 1);
}
},
success: function(data) {
// has undo action
if (undoUrl) {
$element.trigger(EVENT_UNDO, [$actionButton, isUndo, data]);
isUndo ? $actionButton.removeClass(CLASS_IS_UNDO) : $actionButton.addClass(CLASS_IS_UNDO);
$actionButton.prop('disabled', false);
return;
}
window.location.reload();
},
error: function(err) {
if (err.status == 200) {
return;
}
if (undoUrl) {
$actionButton.prop('disabled', false);
} else if (needDisableButtons) {
_this.switchButtons($element);
}
QOR.handleAjaxError(err);
},
complete: function(response) {
let contentType = response.getResponseHeader('content-type'),
disposition = response.getResponseHeader('Content-Disposition');
$(CLASS_BODY_LOADING).remove();
$actionButton.prop('disabled', false);
if($parent.length){
$parent.find('[data-ajax-form="true"][data-method]').removeClass("qor-action-disabled");
} else {
$actionButton.removeClass("qor-action-disabled");
}
// handle file download from form submit
if (disposition && disposition.indexOf('attachment') !== -1) {
var fileNameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/,
matches = fileNameRegex.exec(disposition),
fileData = {},
fileName = '';
if (matches != null && matches[1]) {
fileName = matches[1].replace(/['"]/g, '');
}
if (properties.method) {
fileData = $.extend({}, ajaxForm.normalFormData, {
_method: properties.method
});
}
QOR.qorAjaxHandleFile(url, contentType, fileName, fileData);
if (undoUrl) {
$actionButton.prop('disabled', false);
} else {
_this.switchButtons($element);
}
}
}
});
},
switchButtons: function($element, disbale) {
let needDisbale = disbale ? true : false;
$element.find('.qor-action-button').prop('disabled', needDisbale);
},
destroy: function() {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorAction.DEFAULTS = {};
QorAction.TEMPLATE_LOADING = `<div class="qor-body__loading">
<div class="mdl-dialog-bg"></div>
<div><div class="mdl-spinner mdl-js-spinner is-active qor-layout__bottomsheet-spinner"></div></div>
</div>`;
$.fn.qorSliderAfterShow.qorInsertActionData = function(url, html) {
let $action = $(html).find('[data-toggle="qor-action-slideout"]'),
$actionForm = $action.find('form'),
$checkedItem = $(CLASS_TABLE_BULK).find('.mdl-checkbox__input:checked');
if ($action.length && $checkedItem.length) {
// insert checked value into sliderout form
$checkedItem.each(function() {
let id = $(this)
.closest('tr')
.data('primary-key');
if (id) {
$actionForm.prepend('<input class="js-primary-value" type="hidden" name="primary_values[]" value="' + id + '" />');
}
});
}
};
QorAction.plugin = function(options) {
return this.each(function() {
let $this = $(this),
data = $this.data(NAMESPACE),
fn;
if (!data) {
$this.data(NAMESPACE, (data = new QorAction(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.call(data);
}
});
};
$(function() {
let options = {},
selector = '[data-toggle="qor.action.bulk"]';
if (!$(selector).length) {
$(document).on(EVENT_CLICK, CLASS_MENU_ACTIONS, function(e) {
new QorAction().actionSubmit($(e.target));
return false;
});
}
$(document)
.on(EVENT_DISABLE, function(e) {
QorAction.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorAction.plugin.call($(selector, e.target), options);
})
.triggerHandler(EVENT_ENABLE);
});
return QorAction;
});

View File

@@ -0,0 +1,272 @@
(function(factory) {
if (typeof define === "function" && define.amd) {
// AMD. Register as anonymous module.
define(["jquery"], factory);
} else if (typeof exports === "object") {
// Node / CommonJS
factory(require("jquery"));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
"use strict";
let location = window.location,
QOR = window.QOR,
NAMESPACE = "qor.advancedsearch",
EVENT_ENABLE = "enable." + NAMESPACE,
EVENT_DISABLE = "disable." + NAMESPACE,
EVENT_CLICK = "click." + NAMESPACE,
EVENT_SHOWN = "shown.qor.modal",
EVENT_SUBMIT = "submit." + NAMESPACE;
function getExtraPairs(names) {
let pairs = decodeURIComponent(location.search.substr(1)).split("&"),
pairsObj = {},
pair,
i;
if (pairs.length == 1 && pairs[0] == "") {
return false;
}
for (i in pairs) {
if (pairs[i] === "") continue;
pair = pairs[i].split("=");
pairsObj[pair[0]] = pair[1];
}
names.forEach(function(item) {
delete pairsObj[item];
});
return pairsObj;
}
function QorAdvancedSearch(element, options) {
this.$element = $(element);
this.options = $.extend(
{},
QorAdvancedSearch.DEFAULTS,
$.isPlainObject(options) && options
);
this.init();
}
QorAdvancedSearch.prototype = {
constructor: QorAdvancedSearch,
init: function() {
this.$form = this.$element.find("form");
this.$modal = $(QorAdvancedSearch.MODAL).appendTo("body");
this.bind();
},
bind: function() {
this.$element
.on(EVENT_SUBMIT, "form", this.submit.bind(this))
.on(
EVENT_CLICK,
".qor-advanced-filter__save",
this.showSaveFilter.bind(this)
)
.on(
EVENT_CLICK,
".qor-advanced-filter__toggle",
this.toggleFilterContent
)
.on(EVENT_CLICK, ".qor-advanced-filter__close", this.closeFilter)
.on(
EVENT_CLICK,
".qor-advanced-filter__delete",
this.deleteSavedFilter
);
this.$modal.on(EVENT_SHOWN, this.start.bind(this));
},
closeFilter: function() {
$(".qor-advanced-filter__dropdown").hide();
},
toggleFilterContent: function(e) {
$(e.target)
.closest(".qor-advanced-filter__toggle")
.parent()
.find(">[advanced-search-toggle]")
.toggle();
},
showSaveFilter: function() {
this.$modal.qorModal("show");
},
deleteSavedFilter: function(e) {
let $target = $(e.target).closest(".qor-advanced-filter__delete"),
$savedFilter = $target.closest(".qor-advanced-filter__savedfilter"),
name = $target.data("filter-name"),
url = location.pathname,
message = {
confirm: "Are you sure you want to delete this saved filter?"
};
QOR.qorConfirm(message, function(confirm) {
if (confirm) {
$.get(url, $.param({ delete_saved_filter: name }))
.done(function() {
$target.closest("li").remove();
if ($savedFilter.find("li").length === 0) {
$savedFilter.remove();
}
})
.fail(function() {
QOR.qorConfirm("Server error, please try again!");
});
}
});
return false;
},
start: function() {
this.$modal
.trigger("enable.qor.material")
.on(
EVENT_CLICK,
".qor-advanced-filter__savefilter",
this.saveFilter.bind(this)
);
},
saveFilter: function() {
let name = this.$modal.find("#qor-advanced-filter__savename").val();
if (!name) {
return;
}
this.$form
.prepend(
`<input type="hidden" name="filter_saving_name" value="${name}" />`
)
.submit();
},
submit: function() {
let $form = this.$form,
formArr = $form.find("input[name],select[name]"),
names = [],
extraPairs,
$bottomsheet = $form.closest(".qor-bottomsheets"),
params = $form.serialize();
formArr.each(function() {
names.push($(this).attr("name"));
});
extraPairs = getExtraPairs(names);
if (!$.isEmptyObject(extraPairs)) {
for (let key in extraPairs) {
if (extraPairs.hasOwnProperty(key)) {
$form.prepend(
`<input type="hidden" name=${key} value=${extraPairs[key]} />`
);
}
}
}
this.$element.find(".qor-advanced-filter__dropdown").hide();
this.removeEmptyPairs($form);
if ($bottomsheet.length) {
if ($bottomsheet.data().url) {
let reloadUrl = `${$bottomsheet.data().url}?${params}`;
$bottomsheet.trigger("reloadFromUrl.qor.bottomsheets", [reloadUrl]);
return false;
} else {
console.log("dont have base URL! advancedsearch reload failed");
}
}
},
removeEmptyPairs: function($form) {
$form.find("advanced-filter-group").each(function() {
let $this = $(this),
$input = $this.find("[filter-required]");
if ($input.val() == "") {
$this.remove();
}
});
},
destroy: function() {
this.$element.removeData(NAMESPACE);
}
};
QorAdvancedSearch.DEFAULTS = {};
QorAdvancedSearch.MODAL = `<div class="qor-modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="mdl-card mdl-shadow--2dp" role="document">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">Save advanced filter</h2>
</div>
<div class="mdl-card__supporting-text">
<div class="mdl-textfield mdl-textfield--full-width mdl-js-textfield">
<input class="mdl-textfield__input" type="text" id="qor-advanced-filter__savename">
<label class="mdl-textfield__label" for="qor-advanced-filter__savename">Please enter name for this filter</label>
</div>
</div>
<div class="mdl-card__actions">
<a class="mdl-button mdl-button--colored mdl-button--raised qor-advanced-filter__savefilter">Save This Filter</a>
<a class="mdl-button mdl-button--colored" data-dismiss="modal">Cancel</a>
</div>
<div class="mdl-card__menu">
<button class="mdl-button mdl-button--icon" data-dismiss="modal" aria-label="close">
<i class="material-icons">close</i>
</button>
</div>
</div>
</div>`;
QorAdvancedSearch.plugin = function(options) {
return this.each(function() {
let $this = $(this),
data = $this.data(NAMESPACE),
fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorAdvancedSearch(this, options)));
}
if (typeof options === "string" && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$(function() {
let selector = '[data-toggle="qor.advancedsearch"]',
options;
$(document)
.on(EVENT_DISABLE, function(e) {
QorAdvancedSearch.plugin.call($(selector, e.target), "destroy");
})
.on(EVENT_ENABLE, function(e) {
QorAdvancedSearch.plugin.call($(selector, e.target), options);
})
.triggerHandler(EVENT_ENABLE);
});
return QorAdvancedSearch;
});

View File

@@ -0,0 +1,101 @@
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function ($) {
'use strict';
var NAMESPACE = 'qor.autoheight';
var EVENT_ENABLE = 'enable.' + NAMESPACE;
var EVENT_DISABLE = 'disable.' + NAMESPACE;
var EVENT_INPUT = 'input';
function QorAutoheight(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorAutoheight.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorAutoheight.prototype = {
constructor: QorAutoheight,
init: function () {
var $this = this.$element;
this.paddingTop = parseInt($this.css('padding-top'), 10);
this.paddingBottom = parseInt($this.css('padding-bottom'), 10);
this.resize();
this.bind();
},
bind: function () {
this.$element.on(EVENT_INPUT, $.proxy(this.resize, this));
},
unbind: function () {
this.$element.off(EVENT_INPUT, this.resize);
},
resize: function () {
var $this = this.$element;
var scrollHeight = $this.prop('scrollHeight');
if(scrollHeight){
$this.height('auto').height(scrollHeight - this.paddingTop - this.paddingBottom);
} else {
$this.height('40px');
}
},
destroy: function () {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorAutoheight.DEFAULTS = {};
QorAutoheight.plugin = function (options) {
return this.each(function () {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorAutoheight(this, options)));
}
if (typeof options === 'string' && $.isFunction(fn = data[options])) {
fn.apply(data);
}
});
};
$(function () {
var selector = 'textarea.qor-js-autoheight';
$(document).
on(EVENT_DISABLE, function (e) {
QorAutoheight.plugin.call($(selector, e.target), 'destroy');
}).
on(EVENT_ENABLE, function (e) {
QorAutoheight.plugin.call($(selector, e.target));
}).
triggerHandler(EVENT_ENABLE);
});
return QorAutoheight;
});

View File

@@ -0,0 +1,754 @@
(function(factory) {
if (typeof define === "function" && define.amd) {
// AMD. Register as anonymous module.
define(["jquery"], factory);
} else if (typeof exports === "object") {
// Node / CommonJS
factory(require("jquery"));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
"use strict";
let _ = window._,
FormData = window.FormData,
QOR_Translations = window.QOR_Translations,
NAMESPACE = "qor.bottomsheets",
EVENT_CLICK = "click." + NAMESPACE,
EVENT_SUBMIT = "submit." + NAMESPACE,
EVENT_SUBMITED = "ajaxSuccessed." + NAMESPACE,
EVENT_RELOAD = "reload." + NAMESPACE,
EVENT_RELOADFROMURL = "reloadFromUrl." + NAMESPACE,
EVENT_BOTTOMSHEET_BEFORESEND = "bottomsheetBeforeSend." + NAMESPACE,
EVENT_BOTTOMSHEET_LOADED = "bottomsheetLoaded." + NAMESPACE,
EVENT_BOTTOMSHEET_CLOSED = "bottomsheetClosed." + NAMESPACE,
EVENT_BOTTOMSHEET_SUBMIT = "bottomsheetSubmitComplete." + NAMESPACE,
EVENT_HIDDEN = "hidden." + NAMESPACE,
EVENT_KEYUP = "keyup." + NAMESPACE,
CLASS_OPEN = "qor-bottomsheets-open",
CLASS_IS_SHOWN = "is-shown",
CLASS_IS_SLIDED = "is-slided",
CLASS_MAIN_CONTENT = ".mdl-layout__content.qor-page",
CLASS_BODY_CONTENT = ".qor-page__body",
CLASS_BODY_HEAD = ".qor-page__header",
CLASS_BOTTOMSHEETS_FILTER = ".qor-bottomsheet__filter",
CLASS_BOTTOMSHEETS_BUTTON = ".qor-bottomsheets__search-button",
CLASS_BOTTOMSHEETS_INPUT = ".qor-bottomsheets__search-input",
URL_GETQOR = "http://www.getqor.com/";
function getUrlParameter(name, search) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
var results = regex.exec(decodeURIComponent(search));
return results === null
? ""
: results[1].replace(/\+/g, " ");
}
function updateQueryStringParameter(key, value, uri) {
var escapedkey = String(key).replace(/[\\^$*+?.()|[\]{}]/g, "\\$&"),
re = new RegExp("([?&])" + escapedkey + "=.*?(&|$)", "i"),
separator = uri.indexOf("?") !== -1 ? "&" : "?";
if (uri.match(re)) {
if (value) {
return uri.replace(re, "$1" + key + "=" + value + "$2");
} else {
if (RegExp.$1 === "?" || RegExp.$1 === RegExp.$2) {
return uri.replace(re, "$1");
} else {
return uri.replace(re, "");
}
}
} else if (value) {
return uri + separator + key + "=" + value;
}
}
function pushArrary($ele, isScript) {
let array = [],
prop = "href";
isScript && (prop = "src");
$ele.each(function() {
array.push($(this).attr(prop));
});
return _.uniq(array);
}
function execSlideoutEvents(url, response) {
// exec qorSliderAfterShow after script loaded
var qorSliderAfterShow = $.fn.qorSliderAfterShow;
for (var name in qorSliderAfterShow) {
if (
qorSliderAfterShow.hasOwnProperty(name) &&
!qorSliderAfterShow[name]["isLoadedInBottomSheet"] &&
name != "initPublishForm" &&
name != "qorActivityinit"
) {
qorSliderAfterShow[name]["isLoadedInBottomSheet"] = true;
qorSliderAfterShow[name].call(this, url, response);
}
}
}
function loadScripts(srcs, data, callback) {
let scriptsLoaded = 0;
for (let i = 0, len = srcs.length; i < len; i++) {
let script = document.createElement("script");
script.onload = function() {
scriptsLoaded++;
if (scriptsLoaded === srcs.length) {
if ($.isFunction(callback)) {
callback();
}
}
if (data && data.url && data.response) {
execSlideoutEvents(data.url, data.response);
}
};
script.src = srcs[i];
document.body.appendChild(script);
}
}
function loadStyles(srcs) {
let ss = document.createElement("link"),
src = srcs.shift();
ss.type = "text/css";
ss.rel = "stylesheet";
ss.onload = function() {
if (srcs.length) {
loadStyles(srcs);
}
};
ss.href = src;
document.getElementsByTagName("head")[0].appendChild(ss);
}
function compareScripts($scripts) {
let $currentPageScripts = $("script"),
slideoutScripts = pushArrary($scripts, true),
currentPageScripts = pushArrary($currentPageScripts, true),
scriptDiff = _.difference(slideoutScripts, currentPageScripts);
return scriptDiff;
}
function compareLinks($links) {
let $currentStyles = $("link"),
slideoutStyles = pushArrary($links),
currentStyles = pushArrary($currentStyles),
styleDiff = _.difference(slideoutStyles, currentStyles);
return styleDiff;
}
function QorBottomSheets(element, options) {
this.$element = $(element);
this.options = $.extend(
{},
QorBottomSheets.DEFAULTS,
$.isPlainObject(options) && options
);
this.resourseData = {};
this.init();
}
QorBottomSheets.prototype = {
constructor: QorBottomSheets,
init: function() {
this.build();
this.bind();
},
build: function() {
let $bottomsheets;
this.$bottomsheets = $bottomsheets = $(QorBottomSheets.TEMPLATE).appendTo(
"body"
);
this.$body = $bottomsheets.find(".qor-bottomsheets__body");
this.$title = $bottomsheets.find(".qor-bottomsheets__title");
this.$header = $bottomsheets.find(".qor-bottomsheets__header");
this.$bodyClass = $("body").prop("class");
this.filterURL = "";
this.searchParams = "";
},
bind: function() {
this.$bottomsheets
.on(EVENT_SUBMIT, "form", this.submit.bind(this))
.on(EVENT_CLICK, '[data-dismiss="bottomsheets"]', this.hide.bind(this))
.on(EVENT_CLICK, ".qor-pagination-container a", this.pagination.bind(this))
.on(EVENT_CLICK, CLASS_BOTTOMSHEETS_BUTTON, this.search.bind(this))
.on(EVENT_KEYUP, this.keyup.bind(this))
.on("selectorChanged.qor.selector", this.selectorChanged.bind(this))
.on("filterChanged.qor.filter", this.filterChanged.bind(this))
.on(EVENT_RELOADFROMURL, this.reloadFromUrl.bind(this));
},
unbind: function() {
this.$bottomsheets
.off(EVENT_SUBMIT, "form")
.off(EVENT_CLICK)
.off("selectorChanged.qor.selector")
.off("filterChanged.qor.filter");
},
bindActionData: function(actiondData) {
var $form = this.$body
.find('[data-toggle="qor-action-slideout"]')
.find("form");
for (var i = actiondData.length - 1; i >= 0; i--) {
$form.prepend(
'<input type="hidden" name="primary_values[]" value="' +
actiondData[i] +
'" />'
);
}
},
filterChanged: function(e, search, key) {
// if this event triggered:
// search: ?locale_mode=locale, ?filters[Color].Value=2
// key: search param name: locale_mode
var loadUrl;
loadUrl = this.constructloadURL(search, key);
loadUrl && this.reload(loadUrl);
return false;
},
selectorChanged: function(e, url, key) {
// if this event triggered:
// url: /admin/!remote_data_searcher/products/Collections?locale=en-US
// key: search param key: locale
var loadUrl;
loadUrl = this.constructloadURL(url, key);
loadUrl && this.reload(loadUrl);
return false;
},
keyup: function(e) {
var searchInput = this.$bottomsheets.find(CLASS_BOTTOMSHEETS_INPUT);
if (e.which === 13 && searchInput.length && searchInput.is(":focus")) {
this.search();
}
},
search: function() {
var $bottomsheets = this.$bottomsheets,
param = "?keyword=",
baseUrl = $bottomsheets.data().url,
searchValue = $.trim(
$bottomsheets.find(CLASS_BOTTOMSHEETS_INPUT).val()
),
url = baseUrl + param + searchValue;
if(/\?/g.test(baseUrl)){
url = baseUrl + "&keyword=" + searchValue;
}
this.reload(url);
},
pagination: function(e) {
var $ele = $(e.target).closest("a"),
url = $ele.prop("href");
if (url) {
this.reload(url);
}
return false;
},
reload: function(url) {
var $content = this.$bottomsheets.find(CLASS_BODY_CONTENT);
this.addLoading($content);
this.fetchPage(url);
},
reloadFromUrl: function(e, url) {
this.reload(url);
},
fetchPage: function(url) {
var $bottomsheets = this.$bottomsheets,
_this = this;
$.get(url, function(response) {
var $response = $(response).find(CLASS_MAIN_CONTENT),
$responseHeader = $response.find(CLASS_BODY_HEAD),
$responseBody = $response.find(CLASS_BODY_CONTENT);
if ($responseBody.length) {
$bottomsheets.find(CLASS_BODY_CONTENT).html($responseBody.html());
if ($responseHeader.length) {
_this.$body
.find(CLASS_BODY_HEAD)
.html($responseHeader.html())
.trigger("enable");
_this.addHeaderClass();
}
// will trigger this event(relaod.qor.bottomsheets) when bottomsheets reload complete: like pagination, filter, action etc.
$bottomsheets.trigger(EVENT_RELOAD);
} else {
_this.reload(url);
}
}).fail(function() {
window.alert("server error, please try again later!");
});
},
constructloadURL: function(url, key) {
var fakeURL,
value,
filterURL = this.filterURL,
bindUrl = this.$bottomsheets.data().url;
if (!filterURL) {
if (bindUrl) {
filterURL = bindUrl;
} else {
return;
}
}
fakeURL = new URL(URL_GETQOR + url);
value = getUrlParameter(key, fakeURL.search);
filterURL = this.filterURL = updateQueryStringParameter(
key,
value,
filterURL
);
return filterURL;
},
addHeaderClass: function() {
this.$body.find(CLASS_BODY_HEAD).hide();
if (
this.$bottomsheets
.find(CLASS_BODY_HEAD)
.children(CLASS_BOTTOMSHEETS_FILTER).length
) {
this.$body
.addClass("has-header")
.find(CLASS_BODY_HEAD)
.show();
}
},
addLoading: function($element) {
$element.html("");
$(QorBottomSheets.TEMPLATE_LOADING)
.appendTo($element)
.trigger("enable.qor.material");
},
loadExtraResource: function(data) {
let styleDiff = compareLinks(data.$links),
scriptDiff = compareScripts(data.$scripts);
styleDiff.length && loadStyles(styleDiff);
scriptDiff.length && loadScripts(scriptDiff, data);
},
loadMedialibraryJS: function($response) {
var $script = $response.filter("script"),
theme = /theme=media_library/g,
src,
_this = this;
$script.each(function() {
src = $(this).prop("src");
if (theme.test(src)) {
var script = document.createElement("script");
script.src = src;
document.body.appendChild(script);
_this.mediaScriptAdded = true;
}
});
},
submit: function(e) {
let form = e.target,
$form = $(form),
_this = this,
url = $form.prop("action"),
formData,
$bottomsheets = $form.closest(".qor-bottomsheets"),
resourseData = $bottomsheets.data(),
ajaxType = resourseData.ajaxType,
$submit = $form.find(":submit");
// will ingore submit event if need handle with other submit event: like select one, many...
if (resourseData.ingoreSubmit) {
return;
}
// will submit form as normal,
// if you need download file after submit form or other things, please add
// data-use-normal-submit="true" to form tag
// <form action="/admin/products/!action/localize" method="POST" enctype="multipart/form-data" data-normal-submit="true"></form>
var normalSubmit = $form.data().normalSubmit;
if (normalSubmit) {
return;
}
$(document).trigger(EVENT_BOTTOMSHEET_BEFORESEND);
e.preventDefault();
formData = new FormData(form);
$.ajax(url, {
method: $form.prop("method"),
data: formData,
dataType: ajaxType ? ajaxType : "html",
processData: false,
contentType: false,
beforeSend: function() {
$submit.prop("disabled", true);
},
success: function(data, textStatus, jqXHR) {
if (resourseData.ajaxMute) {
$bottomsheets.remove();
return;
}
if (resourseData.ajaxTakeover) {
resourseData.$target
.parent()
.trigger(EVENT_SUBMITED, [data, $bottomsheets]);
return;
}
// handle file download from form submit
var disposition = jqXHR.getResponseHeader("Content-Disposition");
if (disposition && disposition.indexOf("attachment") !== -1) {
var fileNameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/,
matches = fileNameRegex.exec(disposition),
contentType = jqXHR.getResponseHeader("Content-Type"),
fileName = "";
if (matches != null && matches[1]) {
fileName = matches[1].replace(/['"]/g, "");
}
window.QOR.qorAjaxHandleFile(url, contentType, fileName, formData);
$submit.prop("disabled", false);
return;
}
$(".qor-error").remove();
var returnUrl = $form.data("returnUrl");
var refreshUrl = $form.data("refreshUrl");
if (refreshUrl) {
window.location.href = refreshUrl;
return;
}
if (returnUrl == "refresh") {
_this.refresh();
return;
}
if (returnUrl && returnUrl != "refresh") {
_this.load(returnUrl);
} else {
_this.refresh();
}
$(document).trigger(EVENT_BOTTOMSHEET_SUBMIT);
},
error: function(err) {
window.QOR.handleAjaxError(err);
},
complete: function() {
$submit.prop("disabled", false);
}
});
},
load: function(url, data, callback) {
var options = this.options,
method,
dataType,
load,
actionData = data.actionData,
resourseData = this.resourseData,
selectModal = resourseData.selectModal,
ingoreSubmit = resourseData.ingoreSubmit,
$bottomsheets = this.$bottomsheets,
$header = this.$header,
$body = this.$body;
if (!url) {
return;
}
this.show();
this.addLoading($body);
this.filterURL = url;
$body.removeClass("has-header has-hint");
data = $.isPlainObject(data) ? data : {};
method = data.method ? data.method : "GET";
dataType = data.datatype ? data.datatype : "html";
load = $.proxy(function() {
$.ajax(url, {
method: method,
dataType: dataType,
success: $.proxy(function(response) {
if (method === "GET") {
let $response = $(response),
$content,
bodyClass,
loadExtraResourceData = {
$scripts: $response.filter("script"),
$links: $response.filter("link"),
url: url,
response: response
},
hasSearch =
selectModal && $response.find(".qor-search-container").length,
bodyHtml = response.match(/<\s*body.*>[\s\S]*<\s*\/body\s*>/gi);
$content = $response.find(CLASS_MAIN_CONTENT);
if (bodyHtml) {
bodyHtml = bodyHtml
.join("")
.replace(/<\s*body/gi, "<div")
.replace(/<\s*\/body/gi, "</div");
bodyClass = $(bodyHtml).prop("class");
$("body").addClass(bodyClass);
}
if (!$content.length) {
return;
}
this.loadExtraResource(loadExtraResourceData);
if (ingoreSubmit) {
$content.find(CLASS_BODY_HEAD).remove();
}
$content
.find(".qor-button--cancel")
.attr("data-dismiss", "bottomsheets");
$body.html($content.html());
this.$title.html($response.find(options.title).html());
if (data.selectDefaultCreating) {
this.$title.append(
`<button class="mdl-button mdl-button--primary" type="button" data-load-inline="true" data-select-nohint="${
data.selectNohint
}" data-select-modal="${
data.selectModal
}" data-select-listing-url="${data.selectListingUrl}">${
data.selectBacktolistTitle
}</button>`
);
}
if (selectModal) {
$body
.find(".qor-button--new")
.data("ingoreSubmit", true)
.data("selectId", resourseData.selectId)
.data("loadInline", true);
if (
selectModal != "one" &&
!data.selectNohint &&
(typeof resourseData.maxItem === "undefined" ||
resourseData.maxItem != "1")
) {
$body.addClass("has-hint");
}
if (selectModal == "mediabox" && !this.mediaScriptAdded) {
this.loadMedialibraryJS($response);
}
}
$header.find(".qor-button--new").remove();
this.$title.after($body.find(".qor-button--new"));
if (hasSearch) {
$bottomsheets.addClass("has-search");
$header.find(".qor-bottomsheets__search").remove();
$header.prepend(QorBottomSheets.TEMPLATE_SEARCH);
}
if (actionData && actionData.length) {
this.bindActionData(actionData);
}
if (resourseData.bottomsheetClassname) {
$bottomsheets.addClass(resourseData.bottomsheetClassname);
}
$bottomsheets.trigger("enable");
$bottomsheets.one(EVENT_HIDDEN, function() {
$(this).trigger("disable");
});
this.addHeaderClass();
$bottomsheets.data(data);
// handle after opened callback
if (callback && $.isFunction(callback)) {
callback(this.$bottomsheets);
}
// callback for after bottomSheets loaded HTML
$bottomsheets.trigger(EVENT_BOTTOMSHEET_LOADED, [url, response]);
} else {
if (data.returnUrl) {
this.load(data.returnUrl);
} else {
this.refresh();
}
}
}, this),
error: $.proxy(function() {
this.$bottomsheets.remove();
if (!$(".qor-bottomsheets").is(":visible")) {
$("body").removeClass(CLASS_OPEN);
}
var errors;
if ($(".qor-error span").length > 0) {
errors = $(".qor-error span")
.map(function() {
return $(this).text();
})
.get()
.join(", ");
} else {
errors = QOR_Translations.serverError;
}
window.alert(errors);
}, this)
});
}, this);
load();
},
open: function(options, callback) {
if (!options.loadInline) {
this.init();
}
this.resourseData = options;
this.load(options.url, options, callback);
},
show: function() {
this.$bottomsheets.addClass(CLASS_IS_SHOWN).get(0).offsetHeight;
this.$bottomsheets.addClass(CLASS_IS_SLIDED);
$("body").addClass(CLASS_OPEN);
},
hide: function(e) {
let $bottomsheets = $(e.target).closest(".qor-bottomsheets"),
$datePicker = $(".qor-datepicker").not(".hidden");
if ($datePicker.length) {
$datePicker.addClass("hidden");
}
$bottomsheets.qorSelectCore("destroy");
$bottomsheets.trigger(EVENT_BOTTOMSHEET_CLOSED).remove();
if (!$(".qor-bottomsheets").is(":visible")) {
$("body").removeClass(CLASS_OPEN);
}
return false;
},
refresh: function() {
this.$bottomsheets.remove();
$("body").removeClass(CLASS_OPEN);
setTimeout(function() {
window.location.reload();
}, 350);
},
destroy: function() {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorBottomSheets.DEFAULTS = {
title: ".qor-form-title, .mdl-layout-title",
content: false
};
QorBottomSheets.TEMPLATE_ERROR = `<ul class="qor-error"><li><label><i class="material-icons">error</i><span>[[error]]</span></label></li></ul>`;
QorBottomSheets.TEMPLATE_LOADING = `<div style="text-align: center; margin-top: 30px;"><div class="mdl-spinner mdl-js-spinner is-active qor-layout__bottomsheet-spinner"></div></div>`;
QorBottomSheets.TEMPLATE_SEARCH = `<div class="qor-bottomsheets__search">
<input autocomplete="off" type="text" class="mdl-textfield__input qor-bottomsheets__search-input" placeholder="Search" />
<button class="mdl-button mdl-js-button mdl-button--icon qor-bottomsheets__search-button" type="button"><i class="material-icons">search</i></button>
</div>`;
QorBottomSheets.TEMPLATE = `<div class="qor-bottomsheets">
<div class="qor-bottomsheets__header">
<h3 class="qor-bottomsheets__title"></h3>
<button type="button" class="mdl-button mdl-button--icon mdl-js-button mdl-js-repple-effect qor-bottomsheets__close" data-dismiss="bottomsheets">
<span class="material-icons">close</span>
</button>
</div>
<div class="qor-bottomsheets__body"></div>
</div>`;
QorBottomSheets.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorBottomSheets(this, options)));
}
if (typeof options === "string" && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$.fn.qorBottomSheets = QorBottomSheets.plugin;
return QorBottomSheets;
});

View File

@@ -0,0 +1,131 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
var NAMESPACE = 'qor.chooser';
var EVENT_ENABLE = 'enable.' + NAMESPACE;
var EVENT_DISABLE = 'disable.' + NAMESPACE;
function QorChooser(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorChooser.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorChooser.prototype = {
constructor: QorChooser,
init: function() {
let $this = this.$element,
select2Data = $this.data(),
resetSelect2Width,
option = {
minimumResultsForSearch: 8,
dropdownParent: $this.parent()
};
let getSelect2AjaxDynamicURL = window.getSelect2AjaxDynamicURL;
let remoteImage = select2Data.remoteImage;
if (select2Data.remoteData) {
option.ajax = $.fn.select2.ajaxCommonOptions(select2Data);
if (getSelect2AjaxDynamicURL && $.isFunction(getSelect2AjaxDynamicURL)) {
option.ajax.url = function() {
return getSelect2AjaxDynamicURL(select2Data);
};
} else {
option.ajax.url = select2Data.remoteUrl;
}
option.templateResult = function(data) {
let tmpl = $this.parents('.qor-field').find('[name="select2-result-template"]');
return $.fn.select2.ajaxFormatResult(data, tmpl, remoteImage);
};
option.templateSelection = function(data) {
if (data.loading) return data.text;
let tmpl = $this.parents('.qor-field').find('[name="select2-selection-template"]');
return $.fn.select2.ajaxFormatResult(data, tmpl, remoteImage);
};
}
$this
.on('select2:select', function(evt) {
$(evt.target).attr('chooser-selected', 'true');
})
.on('select2:unselect', function(evt) {
$(evt.target).attr('chooser-selected', '');
});
$this.select2(option);
// reset select2 container width
this.resetSelect2Width();
resetSelect2Width = window._.debounce(this.resetSelect2Width.bind(this), 300);
$(window).resize(resetSelect2Width);
if ($this.val()) {
$this.attr('chooser-selected', 'true');
}
},
resetSelect2Width: function() {
var $container,
select2 = this.$element.data().select2;
if (select2 && select2.$container) {
$container = select2.$container;
$container.width($container.parent().width());
}
},
destroy: function() {
this.$element.select2('destroy').removeData(NAMESPACE);
}
};
QorChooser.DEFAULTS = {};
QorChooser.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorChooser(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = 'select[data-toggle="qor.chooser"]';
$(document)
.on(EVENT_DISABLE, function(e) {
QorChooser.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorChooser.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorChooser;
});

View File

@@ -0,0 +1,218 @@
$(function() {
let _ = window._,
QOR = window.QOR,
QOR_Translations = window.QOR_Translations,
html = `<div id="dialog" style="display: none;">
<div class="mdl-dialog-bg"></div>
<div class="mdl-dialog">
<div class="mdl-dialog__content">
<p><i class="material-icons">warning</i></p>
<p class="mdl-dialog__message dialog-message">
</p>
</div>
<div class="mdl-dialog__actions">
<button type="button" class="mdl-button mdl-button--raised mdl-button--colored dialog-ok dialog-button" data-type="confirm">
${QOR_Translations.okButton}
</button>
<button type="button" class="mdl-button dialog-cancel dialog-button" data-type="">
${QOR_Translations.cancelButton}
</button>
</div>
</div>
</div>`,
$dialog = $(html).appendTo("body");
// ************************************ Refactor window.confirm ************************************
$(document)
.on("keyup.qor.confirm", function(e) {
if (!$dialog.is(":visible")) {
return;
}
if (e.which === 27) {
setTimeout(function() {
$dialog.hide();
QOR.qorConfirmCallback = undefined;
}, 100);
}
if (e.which === 13) {
setTimeout(function() {
$('.dialog-button[data-type="confirm"]').click();
}, 100);
}
})
.on("click.qor.confirm", ".dialog-button", function() {
let value = $(this).data("type"),
callback = QOR.qorConfirmCallback;
$.isFunction(callback) && callback(value);
$dialog.hide();
QOR.qorConfirmCallback = undefined;
return false;
});
QOR.qorConfirm = function(data, callback) {
let okBtn = $dialog.find(".dialog-ok"),
cancelBtn = $dialog.find(".dialog-cancel");
if (_.isString(data)) {
$dialog.find(".dialog-message").text(data);
okBtn.text(QOR_Translations.okButton);
cancelBtn.text(QOR_Translations.cancelButton);
} else if (_.isObject(data)) {
if (data.confirmOk && data.confirmCancel) {
okBtn.text(data.confirmOk);
cancelBtn.text(data.confirmCancel);
} else {
okBtn.text(QOR_Translations.okButton);
cancelBtn.text(QOR_Translations.cancelButton);
}
if(data.icon){
$dialog.find('i.material-icons').addClass(data.icon).html(data.icon);
}
$dialog.find(".dialog-message").text(data.confirm);
}
$dialog.show();
QOR.qorConfirmCallback = callback;
return false;
};
// *******************************************************************************
// ****************Handle download file from AJAX POST****************************
let objectToFormData = function(obj, form) {
let formdata = form || new FormData(),
key;
for (var variable in obj) {
if (obj.hasOwnProperty(variable) && obj[variable]) {
key = variable;
}
if (obj[variable] instanceof Date) {
formdata.append(key, obj[variable].toISOString());
} else if (
typeof obj[variable] === "object" &&
!(obj[variable] instanceof File)
) {
objectToFormData(obj[variable], formdata);
} else {
formdata.append(key, obj[variable]);
}
}
return formdata;
};
QOR.qorAjaxHandleFile = function(url, contentType, fileName, data) {
let request = new XMLHttpRequest();
request.responseType = "arraybuffer";
request.open("POST", url, true);
request.onload = function() {
if (this.status === 200) {
let blob = new Blob([this.response], {
type: contentType
}),
url = window.URL.createObjectURL(blob),
a = document.createElement("a");
document.body.appendChild(a);
a.href = url;
a.download = fileName || "download-" + $.now();
a.click();
} else {
window.alert(QOR_Translations.serverError);
}
};
if (_.isObject(data)) {
if (Object.prototype.toString.call(data) != "[object FormData]") {
data = objectToFormData(data);
}
request.send(data);
}
};
// ********************************convert video link********************
// linkyoutube: /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig,
// linkvimeo: /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/,
let converVideoLinks = function() {
let $ele = $(".qor-linkify-object"),
linkyoutube = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.\-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/gi;
if (!$ele.length) {
return;
}
$ele.each(function() {
let url = $(this).data("video-link");
if (url.match(linkyoutube)) {
$(this).html(
`<iframe width="100%" height="100%" src="//www.youtube.com/embed/${url.replace(
linkyoutube,
"$1"
)}" frameborder="0" allowfullscreen></iframe>`
);
}
});
};
$.fn.qorSliderAfterShow.converVideoLinks = converVideoLinks;
converVideoLinks();
// ********************************Qor Handle AJAX error********************
QOR.handleAjaxError = function(err) {
let $body = $("body"),
rJSON = err.responseJSON,
rText = err.responseText,
$error = $(`<ul class="qor-alert qor-error" data-dismissible="true"><button type="button" class="mdl-button mdl-button--icon" data-dismiss="alert">
<i class="material-icons">close</i>
</button></ul>`);
$body.find(".qor-alert").remove();
if (err.status === 422) {
if (rJSON) {
let errors = rJSON.errors,
$errorContent = "";
if ($.isArray(errors)) {
for (let i = 0; i < errors.length; i++) {
$errorContent += `<li>
<i class="material-icons">error</i>
<span>${errors[i]}</span>
</li>`;
}
} else {
$errorContent = `<li>
<i class="material-icons">error</i>
<span>${errors}</span>
</li>`;
}
$error.append($errorContent);
} else {
$error = $(rText).find(".qor-error");
}
} else {
$error.append(`<li>
<i class="material-icons">error</i>
<span>${err.statusText}</span>
</li>`);
}
$error.prependTo($body);
setTimeout(function() {
$error.addClass("qor-alert__active");
}, 50);
setTimeout(function() {
$('.qor-alert[data-dismissible="true"]').removeClass("qor-alert__active");
$("#qor-submit-loading").remove();
}, 6000);
};
});

View File

@@ -0,0 +1,126 @@
// init for slideout after show event
$.fn.qorSliderAfterShow = $.fn.qorSliderAfterShow || {};
window.QOR = {
$formLoading: '<div id="qor-submit-loading" class="clearfix"><div class="mdl-spinner mdl-spinner--single-color mdl-js-spinner is-active"></div></div>'
};
String.prototype.escapeSymbol = function() {
var tagsToReplace = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"' : '&quot;',
"'" : '&#x27;',
'/' : '&#x2F;'
};
return this.replace(/[&<>"']/g, function(tag) {
return tagsToReplace[tag] || tag;
});
};
// change Mustache tags from {{}} to [[]]
window.Mustache && (window.Mustache.tags = ['[[', ']]']);
// clear close alert after ajax complete
$(document).ajaxComplete(function(event, xhr, settings) {
if (settings.type == 'POST' || settings.type == 'PUT') {
if ($.fn.qorSlideoutBeforeHide) {
$.fn.qorSlideoutBeforeHide = null;
window.onbeforeunload = null;
}
}
});
// select2 ajax common options
// $.fn.select2 = $.fn.select2 || function(){};
$.fn.select2.ajaxCommonOptions = function(select2Data) {
let remoteDataPrimaryKey = select2Data.remoteDataPrimaryKey;
return {
dataType: 'json',
headers: getSelect2Header(select2Data),
cache: true,
delay: 250,
data: function(params) {
return {
keyword: params.term, // search term
page: params.page,
per_page: 20
};
},
processResults: function(data, params) {
// parse the results into the format expected by Select2
// since we are using custom formatting functions we do not need to
// alter the remote JSON data, except to indicate that infinite
// scrolling can be used
params.page = params.page || 1;
var processedData = $.map(data, function(obj) {
obj.id = obj[remoteDataPrimaryKey] || obj.primaryKey || obj.Id || obj.ID;
return obj;
});
return {
results: processedData,
pagination: {
more: processedData.length >= 20
}
};
}
};
};
// select2 ajax common options
// format ajax template data
$.fn.select2.ajaxFormatResult = function(data, tmpl, remoteDataImage) {
var result = '';
if (data.loading) {
return data.text;
}
console.log('select2.ajaxFormatResult: Data');
console.log(data);
console.log('select2.ajaxFormatResult: has remote image');
console.log(remoteDataImage);
if (remoteDataImage) {
var resultName = data.text || data.Name || data.Title || data.Code || data[Object.keys(data)[0]];
var imageUrl = data.Image;
if (imageUrl) {
result = '<div class="select2-results__option-withimage">' + '<img src="' + imageUrl + '">' + '<span>' + resultName + '</span></div>';
} else {
result = '<div class="select2-results__option-withimage">' + resultName + '</span></div>';
}
return $(result);
} else {
if (tmpl.length > 0) {
result = window.Mustache.render(tmpl.html().replace(/{{(.*?)}}/g, '[[$1]]'), data);
} else {
result = data.text || data.Name || data.Title || data.Code || data[Object.keys(data)[0]];
}
// if is HTML
if (/<(.*)(\/>|<\/.+>)/.test(result)) {
return $(result);
}
return result;
}
};
function getSelect2Header() {
let data = $('body').data();
let selectAjaxHeader = data.selectAjaxHeader;
let getSelect2HeaderFunction = window.getSelect2HeaderFunction;
let headers = {};
if (selectAjaxHeader && getSelect2HeaderFunction && $.isFunction(getSelect2HeaderFunction)) {
headers[selectAjaxHeader] = getSelect2HeaderFunction();
return headers;
} else {
return {};
}
}

View File

@@ -0,0 +1,766 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let URL = window.URL || window.webkitURL,
NAMESPACE = 'qor.cropper',
// Events
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_CHANGE = 'change.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_SHOWN = 'shown.qor.modal',
EVENT_HIDDEN = 'hidden.qor.modal',
// Classes
CLASS_TOGGLE = '.qor-cropper__toggle',
CLASS_CANVAS = '.qor-cropper__canvas',
CLASS_WRAPPER = '.qor-cropper__wrapper',
CLASS_OPTIONS = '.qor-cropper__options',
CLASS_SAVE = '.qor-cropper__save',
CLASS_DELETE = '.qor-cropper__toggle--delete',
CLASS_CROP = '.qor-cropper__toggle--crop',
CLASS_UNDO = '.qor-fieldset__undo',
HIDDEN_DATA_INPUT = 'input[name="QorResource.MediaOption"]:hidden';
function capitalize(str) {
if (typeof str === 'string') {
str = str.charAt(0).toUpperCase() + str.substr(1);
}
return str;
}
function getLowerCaseKeyObject(obj) {
let newObj = {},
key;
if ($.isPlainObject(obj)) {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[String(key).toLowerCase()] = obj[key];
}
}
}
return newObj;
}
function getValueByNoCaseKey(obj, key) {
let originalKey = String(key),
lowerCaseKey = originalKey.toLowerCase(),
upperCaseKey = originalKey.toUpperCase(),
capitalizeKey = capitalize(originalKey);
if ($.isPlainObject(obj)) {
return obj[lowerCaseKey] || obj[capitalizeKey] || obj[upperCaseKey];
}
}
function replaceText(str, data) {
if (typeof str === 'string') {
if (typeof data === 'object') {
$.each(data, function(key, val) {
str = str.replace('$[' + String(key).toLowerCase() + ']', val);
});
}
}
return str;
}
function isSVG(url) {
return /.svg$/.test(url);
}
function QorCropper(element, options) {
this.$element = $(element);
this.options = $.extend(true, {}, QorCropper.DEFAULTS, $.isPlainObject(options) && options);
this.data = null;
this.init();
}
QorCropper.prototype = {
constructor: QorCropper,
init: function() {
let options = this.options,
$this = this.$element,
$parent = $this.closest(options.parent),
data,
outputValue,
fetchUrl,
_this = this,
imageData;
if (!$parent.length) {
$parent = $this.parent();
}
this.$parent = $parent;
this.$output = $parent.find(options.output);
this.$formCropInput = $parent.closest('form').find(HIDDEN_DATA_INPUT);
this.$list = $parent.find(options.list);
fetchUrl = this.$output.data('fetchSizedata');
if (fetchUrl) {
$.getJSON(fetchUrl, function(data) {
imageData = JSON.parse(data.MediaOption);
_this.$output.val(JSON.stringify(data));
_this.$formCropInput.val(JSON.stringify(data));
_this.data = imageData || {};
if (isSVG(imageData.URL || imageData.Url)) {
_this.resetImage();
}
_this.build();
_this.bind();
});
} else {
outputValue = $.trim(this.$output.val());
if (outputValue) {
data = JSON.parse(outputValue);
if (isSVG(data.URL || data.Url)) {
this.resetImage();
}
}
this.data = data || {};
this.build();
this.bind();
}
},
resetImage: function() {
this.$parent.addClass('is-svg');
},
build: function() {
let textData = this.$output.data(),
text = {},
replaceTexts;
if (textData) {
text = {
title: textData.cropperTitle,
ok: textData.cropperOk,
cancel: textData.cropperCancel
};
replaceTexts = this.options.text;
}
if (text.ok && text.title && text.cancel) {
replaceTexts = text;
}
this.wrap();
this.$modal = $(replaceText(QorCropper.MODAL, replaceTexts)).appendTo('body');
},
unbuild: function() {
this.$modal.remove();
this.unwrap();
},
wrap: function() {
let $list = this.$list,
$img;
$img = $list.find('img').not('.is-svg');
if ($img.length) {
$list.find('li').append(QorCropper.TOGGLE);
$img.wrap(QorCropper.CANVAS);
this.center($img);
} else {
$list.find(CLASS_CROP).remove();
}
},
unwrap: function() {
let $list = this.$list;
$list.find(CLASS_TOGGLE).remove();
$list.find(CLASS_CANVAS).each(function() {
let $this = $(this);
$this.before($this.html()).remove();
});
},
bind: function() {
this.$element.on(EVENT_CHANGE, $.proxy(this.read, this));
this.$list.on(EVENT_CLICK, $.proxy(this.click, this));
this.$modal.on(EVENT_SHOWN, $.proxy(this.start, this)).on(EVENT_HIDDEN, $.proxy(this.stop, this));
},
unbind: function() {
this.$element.off(EVENT_CHANGE, this.read);
this.$list.off(EVENT_CLICK, this.click);
this.$modal.off(EVENT_SHOWN, this.start).off(EVENT_HIDDEN, this.stop);
},
click: function(e) {
let target = e.target,
$target,
data = this.data,
$alert;
if (target === this.$list[0]) {
return;
}
$target = $(target);
if ($target.closest(CLASS_DELETE).length) {
data.Delete = true;
this.$output.val(JSON.stringify(data));
this.$formCropInput.val(JSON.stringify(data));
this.$list.hide();
$alert = $(QorCropper.ALERT);
$alert.find(CLASS_UNDO).one(
EVENT_CLICK,
function() {
$alert.remove();
this.$list.show();
delete data.Delete;
this.$output.val(JSON.stringify(data));
this.$formCropInput.val(JSON.stringify(data));
}.bind(this)
);
this.$parent.find('.qor-fieldset').append($alert);
}
if ($target.closest(CLASS_CROP).length) {
$target = $target.closest('li').find('img');
this.$target = $target;
this.$modal.qorModal('show');
}
},
read: function(e) {
let files = e.target.files,
file,
$list = this.$list,
$alert = this.$parent.find('.qor-fieldset__alert');
$list.show();
if ($alert.length) {
$alert.remove();
}
if (files && files.length) {
file = files[0];
if (/^image\//.test(file.type) && URL) {
this.fileType = file.type;
this.load(URL.createObjectURL(file));
this.$parent.find('.qor-medialibrary__image-desc').show();
} else {
$list.empty().html(QorCropper.FILE_LIST.replace('{{filename}}', file.name));
}
}
},
load: function(url, fromExternal, callback) {
let options = this.options,
_this = this,
$list = this.$list,
$ul = $(QorCropper.LIST),
data = this.data || {},
outputOriginalData = this.$output.val() ? JSON.parse(this.$output.val()) : {},
outputOriginalDataType = ['Video', 'SelectedType', 'Description'],
fileType = this.fileType,
$image,
imageLength;
// media box will use load method, has it's own html structure.
if (!fromExternal) {
$list.find('ul').remove();
$list.html($ul);
}
$image = $list.find('img');
this.wrap();
imageLength = $image.length;
$image
.one('load', function() {
if (fileType === 'image/svg+xml') {
$list.find(CLASS_TOGGLE).remove();
return false;
}
let $this = $(this),
naturalWidth = this.naturalWidth,
naturalHeight = this.naturalHeight,
sizeData = $this.data(),
sizeResolution = sizeData.sizeResolution,
sizeName = sizeData.sizeName,
emulateImageData = {},
emulateCropData = {},
aspectRatio,
width = sizeData.sizeResolutionWidth,
height = sizeData.sizeResolutionHeight;
if (sizeResolution) {
if (!width && !height) {
width = getValueByNoCaseKey(sizeResolution, 'width');
height = getValueByNoCaseKey(sizeResolution, 'height');
}
if (height && width) {
aspectRatio = width / height;
} else {
aspectRatio = naturalWidth / naturalHeight;
}
if (naturalHeight * aspectRatio > naturalWidth) {
width = naturalWidth;
height = width / aspectRatio;
} else {
height = naturalHeight;
width = height * aspectRatio;
}
emulateImageData = {
naturalWidth: naturalWidth,
naturalHeight: naturalHeight
};
emulateCropData = {
x: Math.round((naturalWidth - width) / 2),
y: Math.round((naturalHeight - height) / 2),
width: Math.round(width),
height: Math.round(height)
};
_this.preview($this, emulateImageData, emulateCropData);
if (sizeName) {
data.Crop = true;
if (!data[options.key]) {
data[options.key] = {};
}
if (sizeName != 'original') {
data[options.key][sizeName] = emulateCropData;
}
}
} else {
_this.center($this);
}
// Crop, CropOptions and Delete should be BOOL type, if empty should delete,
if (data.Crop === '' || !fromExternal) {
delete data.Crop;
}
if (!fromExternal) {
data.CropOptions = null;
delete data.Sizes;
}
delete data.Delete;
// Fix media upload image other property missing bug: ["Video", "SelectedType", "Description"]
outputOriginalDataType.forEach((type) => {
if (outputOriginalData[type]) {
data[type] = outputOriginalData[type];
}
});
_this.$output.val(JSON.stringify(data));
_this.$formCropInput.val(JSON.stringify(data));
// callback after load complete
if (sizeName && data[options.key] && Object.keys(data[options.key]).length >= imageLength) {
if (callback && $.isFunction(callback)) {
callback();
}
}
})
.attr('src', url)
.data('originalUrl', url);
$list.show();
},
start: function() {
let options = this.options,
$modal = this.$modal,
$target = this.$target,
sizeData = $target.data(),
sizeName = sizeData.sizeName || 'original',
sizeResolution = sizeData.sizeResolution,
originalUrl = (sizeData && sizeData.originalUrl && $target.attr('data-original-url'))
? (/\.original\./.test(sizeData.originalUrl) ? sizeData.originalUrl
: /\.original\./.test($target.attr('data-original-url'))
? $target.attr('data-original-url')
: $target.attr('data-original-url').replace(/file\./, 'file.original.'))
: $target.attr('src'),
$clone = $(`<img src=${originalUrl}>`),
data = this.data || {},
_this = this,
sizeAspectRatio = NaN,
sizeWidth = sizeData.sizeResolutionWidth,
sizeHeight = sizeData.sizeResolutionHeight,
list;
if (sizeResolution) {
if (!sizeWidth && !sizeHeight) {
sizeWidth = getValueByNoCaseKey(sizeResolution, 'width');
sizeHeight = getValueByNoCaseKey(sizeResolution, 'height');
}
sizeAspectRatio = sizeWidth / sizeHeight;
}
if (!data[options.key]) {
data[options.key] = {};
}
$modal
.trigger('enable.qor.material')
.find(CLASS_WRAPPER)
.html($clone);
list = this.getList(sizeAspectRatio);
if (list) {
$modal
.find(CLASS_OPTIONS)
.show()
.append(list);
}
$clone.cropper({
aspectRatio: sizeAspectRatio,
data: getLowerCaseKeyObject(data[options.key][sizeName]),
background: false,
movable: false,
zoomable: false,
scalable: false,
rotatable: false,
autoCropArea: 1,
ready: function() {
$modal
.find('.qor-cropper__options-toggle')
.on(EVENT_CLICK, function() {
$modal.find('.qor-cropper__options-input').prop('checked', $(this).prop('checked'));
})
.prop('checked', true);
$modal.find(CLASS_SAVE).one(EVENT_CLICK, function() {
let cropData = $clone.cropper('getData', true),
croppedCanvas = $clone.cropper('getCroppedCanvas'),
syncData = [],
url;
data.Crop = true;
data[options.key][sizeName] = cropData;
_this.imageData = $clone.cropper('getImageData');
_this.cropData = cropData;
if (croppedCanvas) {
try {
url = croppedCanvas.toDataURL();
} catch (error) {
console.log(error);
console.log('Please check image Cross-origin setting');
}
}
$modal.find(CLASS_OPTIONS + ' input').each(function() {
let $this = $(this);
if ($this.prop('checked')) {
syncData.push($this.attr('name'));
}
});
_this.output(url, syncData);
$modal.qorModal('hide');
});
}
});
},
stop: function() {
this.$modal
.trigger('disable.qor.material')
.find(CLASS_WRAPPER + ' > img')
.cropper('destroy')
.remove()
.end()
.find(CLASS_OPTIONS)
.hide()
.find('ul')
.remove();
},
getList: function(aspectRatio) {
let list = [];
this.$list
.find('img')
.not(this.$target)
.each(function() {
let data = $(this).data(),
resolution = data.sizeResolution,
name = data.sizeName,
width = data.sizeResolutionWidth,
height = data.sizeResolutionHeight;
if (resolution) {
if (!width && !height) {
width = getValueByNoCaseKey(resolution, 'width');
height = getValueByNoCaseKey(resolution, 'height');
}
if (width / height === aspectRatio) {
list.push(
'<label>' +
'<input class="qor-cropper__options-input" type="checkbox" name="' +
name +
'" checked> ' +
'<span>' +
name +
'<small>(' +
width +
'&times;' +
height +
' px)</small>' +
'</span>' +
'</label>'
);
}
}
});
return list.length ? '<ul><li>' + list.join('</li><li>') + '</li></ul>' : '';
},
output: function(url, data) {
let $target = this.$target;
if (url) {
this.center($target.attr('src', url), true);
} else {
this.preview($target);
}
if ($.isArray(data) && data.length) {
this.autoCrop(url, data);
}
this.$output.val(JSON.stringify(this.data)).trigger(EVENT_CHANGE);
this.$formCropInput.val(JSON.stringify(this.data));
},
preview: function($target, emulateImageData, emulateCropData) {
let $canvas = $target.parent(),
$container = $canvas.parent(),
containerWidth = $container.width(),
containerHeight = $container.height(),
imageData = emulateImageData || this.imageData,
cropData = $.extend({}, emulateCropData || this.cropData), // Clone one to avoid changing it
aspectRatio = cropData.width / cropData.height,
canvasWidth = containerWidth,
scaledRatio;
if (canvasWidth == 0 || imageData.naturalWidth == 0 || imageData.naturalHeight == 0) {
return;
}
if (containerHeight * aspectRatio <= containerWidth) {
canvasWidth = containerHeight * aspectRatio;
}
scaledRatio = cropData.width / canvasWidth;
$target.css({
maxWidth: imageData.naturalWidth / scaledRatio,
maxHeight: imageData.naturalHeight / scaledRatio
});
this.center($target);
},
center: function($target, reset) {
$target.each(function() {
let $this = $(this),
$canvas = $this.parent(),
$container = $canvas.parent();
function center() {
let containerHeight = $container.height(),
canvasHeight = $canvas.height(),
marginTop = 'auto';
if (canvasHeight < containerHeight) {
marginTop = (containerHeight - canvasHeight) / 2;
}
$canvas.css('margin-top', marginTop);
}
if (reset) {
$canvas.add($this).removeAttr('style');
}
if (this.complete) {
center.call(this);
} else {
this.onload = center;
}
});
},
autoCrop: function(url, data) {
let cropData = this.cropData,
cropOptions = this.data[this.options.key],
_this = this;
this.$list
.find('img')
.not(this.$target)
.each(function() {
let $this = $(this),
sizeName = $this.data('sizeName');
if ($.inArray(sizeName, data) > -1) {
cropOptions[sizeName] = $.extend({}, cropData);
if (url) {
_this.center($this.attr('src', url), true);
} else {
_this.preview($this);
}
}
});
},
destroy: function() {
if (!isSVG) {
this.unbind();
this.unbuild();
}
this.$element.removeData(NAMESPACE);
}
};
QorCropper.DEFAULTS = {
parent: false,
output: false,
list: false,
key: 'data',
data: null,
text: {
title: 'Crop the image',
ok: 'OK',
cancel: 'Cancel'
}
};
QorCropper.TOGGLE = `<div class="qor-cropper__toggle">
<div class="qor-cropper__toggle--crop"><i class="material-icons">crop</i></div>
<div class="qor-cropper__toggle--delete"><i class="material-icons">delete</i></div>
</div>`;
QorCropper.ALERT = `<div class="qor-fieldset__alert">
<button class="mdl-button mdl-button--accent qor-fieldset__undo" type="button">Undo delete</button>
</div>`;
QorCropper.CANVAS = '<div class="qor-cropper__canvas"></div>';
QorCropper.LIST = '<ul><li><img></li></ul>';
QorCropper.FILE_LIST = `<div class="qor-file__list-item">
<span><span>{{filename}}</span></span>
<div class="qor-cropper__toggle">
<div class="qor-cropper__toggle--delete"><i class="material-icons">delete</i></div>
</div>
</div>`;
QorCropper.MODAL = `<div class="qor-modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="mdl-card mdl-shadow--2dp" role="document">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">$[title]</h2>
</div>
<div class="mdl-card__supporting-text">
<div class="qor-cropper__wrapper"></div>
<div class="qor-cropper__options">
<p>Sync cropping result to: <label><input type="checkbox" class="qor-cropper__options-toggle" checked/> All</label></p>
</div>
</div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-button--raised qor-cropper__save">$[ok]</a>
<a class="mdl-button mdl-button--colored" data-dismiss="modal">$[cancel]</a>
</div>
<div class="mdl-card__menu">
<button class="mdl-button mdl-button--icon" data-dismiss="modal" aria-label="close">
<i class="material-icons">close</i>
</button>
</div>
</div>
</div>`;
QorCropper.plugin = function(option) {
return this.each(function() {
let $this = $(this),
data = $this.data(NAMESPACE),
options,
fn;
if (!data) {
if (!$.fn.cropper) {
return;
}
if (/destroy/.test(option)) {
return;
}
options = $.extend(true, {}, $this.data(), typeof option === 'object' && option);
$this.data(NAMESPACE, (data = new QorCropper(this, options)));
}
if (typeof option === 'string' && $.isFunction((fn = data[option]))) {
fn.apply(data);
}
});
};
$(function() {
let selector = '.qor-file__input',
options = {
parent: '.qor-file',
output: '.qor-file__options',
list: '.qor-file__list',
key: 'CropOptions'
};
$(document)
.on(EVENT_ENABLE, function(e) {
QorCropper.plugin.call($(selector, e.target), options);
})
.on(EVENT_DISABLE, function(e) {
QorCropper.plugin.call($(selector, e.target), 'destroy');
})
.triggerHandler(EVENT_ENABLE);
});
return QorCropper;
});

View File

@@ -0,0 +1,242 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let NAMESPACE = 'qor.datepicker',
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_CHANGE = 'pick.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
CLASS_EMBEDDED = '.qor-datepicker__embedded',
CLASS_SAVE = '.qor-datepicker__save',
CLASS_PARENT = '[data-picker-type]';
function replaceText(str, data) {
if (typeof str === 'string') {
if (typeof data === 'object') {
$.each(data, function(key, val) {
str = str.replace('$[' + String(key).toLowerCase() + ']', val);
});
}
}
return str;
}
function QorDatepicker(element, options) {
this.$element = $(element);
this.options = $.extend(true, {}, QorDatepicker.DEFAULTS, $.isPlainObject(options) && options);
this.date = null;
this.formatDate = null;
this.built = false;
this.pickerData = this.$element.data();
this.$parent = this.$element.closest(CLASS_PARENT);
this.isDateTimePicker = this.$parent.data('picker-type') == 'datetime';
this.$targetInput = this.$parent.find(this.pickerData.targetInput || (this.isDateTimePicker ? '.qor-datetimepicker__input' : '.qor-datepicker__input'));
this.init();
}
QorDatepicker.prototype = {
init: function() {
if (this.$targetInput.is(':disabled')) {
this.$element.remove();
return;
}
this.bind();
},
bind: function() {
this.$element.on(EVENT_CLICK, $.proxy(this.show, this));
},
unbind: function() {
this.$element.off(EVENT_CLICK, this.show);
},
build: function() {
let $modal,
$ele = this.$element,
$targetInput = this.$targetInput,
defaultDate = $targetInput.val(),
datepickerOptions = {
date: new Date(),
inline: true
};
if (this.built) {
return;
}
if ($ele.is(':input') && Date.parse($ele.val())) {
datepickerOptions.date = new Date($ele.val());
} else if (defaultDate && Date.parse(defaultDate)) {
datepickerOptions.date = new Date(defaultDate);
}
this.$modal = $modal = $(replaceText(QorDatepicker.TEMPLATE, this.options.text)).appendTo('body');
if ($targetInput.data('start-date')) {
datepickerOptions.startDate = new Date($targetInput.data('start-date'));
}
if ($targetInput.data('end-date')) {
datepickerOptions.endDate = new Date($targetInput.data('end-date'));
}
$modal
.find(CLASS_EMBEDDED)
.on(EVENT_CHANGE, $.proxy(this.change, this))
.qorDatepicker(datepickerOptions)
.triggerHandler(EVENT_CHANGE);
$modal.find(CLASS_SAVE).on(EVENT_CLICK, $.proxy(this.pick, this));
this.built = true;
},
unbuild: function() {
if (!this.built) {
return;
}
this.$modal
.find(CLASS_EMBEDDED)
.off(EVENT_CHANGE, this.change)
.qorDatepicker('destroy')
.end()
.find(CLASS_SAVE)
.off(EVENT_CLICK, this.pick)
.end()
.remove();
},
change: function(e) {
var $modal = this.$modal;
var $target = $(e.target);
var date;
this.date = date = $target.qorDatepicker('getDate');
this.formatDate = $target.qorDatepicker('getDate', true);
$modal.find('.qor-datepicker__picked-year').text(date.getFullYear());
$modal
.find('.qor-datepicker__picked-date')
.text(
[$target.qorDatepicker('getDayName', date.getDay(), true) + ',', String($target.qorDatepicker('getMonthName', date.getMonth(), true)), date.getDate()].join(' ')
);
},
show: function() {
if (!this.built) {
this.build();
}
this.$modal.qorModal('show');
},
pick: function() {
let $targetInput = this.$targetInput,
newValue = this.formatDate;
if (this.isDateTimePicker) {
var regDate = /^\d{4}-\d{1,2}-\d{1,2}/;
var oldValue = $targetInput.val();
var hasDate = regDate.test(oldValue);
if (hasDate) {
newValue = oldValue.replace(regDate, newValue);
} else {
newValue = newValue + ' 00:00';
}
}
$targetInput.val(newValue).trigger('change');
this.$modal.qorModal('hide');
},
destroy: function() {
this.unbind();
this.unbuild();
this.$element.removeData(NAMESPACE);
}
};
QorDatepicker.DEFAULTS = {
text: {
title: 'Pick a date',
ok: 'OK',
cancel: 'Cancel'
}
};
QorDatepicker.TEMPLATE = `<div class="qor-modal fade qor-datepicker" tabindex="-1" role="dialog" aria-hidden="true">
<div class="mdl-card mdl-shadow--2dp" role="document">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">$[title]</h2>
</div>
<div class="mdl-card__supporting-text">
<div class="qor-datepicker__picked">
<div class="qor-datepicker__picked-year"></div>
<div class="qor-datepicker__picked-date"></div>
</div>
<div class="qor-datepicker__embedded"></div>
</div>
<div class="mdl-card__actions">
<a class="mdl-button mdl-button--colored mdl-button--raised qor-datepicker__save">$[ok]</a>
<a class="mdl-button mdl-button--colored " data-dismiss="modal">$[cancel]</a>
</div>
</div>
</div>`;
QorDatepicker.plugin = function(option) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var options;
var fn;
if (!data) {
if (!$.fn.qorDatepicker) {
return;
}
if (/destroy/.test(option)) {
return;
}
options = $.extend(true, {}, $this.data(), typeof option === 'object' && option);
$this.data(NAMESPACE, (data = new QorDatepicker(this, options)));
}
if (typeof option === 'string' && $.isFunction((fn = data[option]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = '[data-toggle="qor.datepicker"]';
$(document)
.on(EVENT_DISABLE, function(e) {
QorDatepicker.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorDatepicker.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorDatepicker;
});

View File

@@ -0,0 +1,106 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
var dirtyForm = function(ele, options) {
var hasChangedObj = false;
if (this instanceof jQuery) {
options = ele;
ele = this;
} else if (!(ele instanceof jQuery)) {
ele = $(ele);
}
ele.each(function(item, element) {
var $ele = $(element);
if ($ele.is('form')) {
if ($ele.hasClass('ignore-dirtyform')) {
return false;
}
hasChangedObj = dirtyForm(
$ele.find(
'input:not([type="hidden"]):not(".search-field input"):not(".chosen-search input"):not(".ignore-dirtyform"), textarea, select'
),
options
);
if (hasChangedObj) {
return false;
}
} else if ($ele.is(':checkbox') || $ele.is(':radio')) {
if ($ele.hasClass('ignore-dirtyform')) {
return false;
}
if (element.checked != element.defaultChecked) {
hasChangedObj = true;
return false;
}
} else if ($ele.is('input') || $ele.is('textarea')) {
if ($ele.hasClass('ignore-dirtyform')) {
return false;
}
if (element.value != element.defaultValue) {
hasChangedObj = true;
return false;
}
} else if ($ele.is('select')) {
if ($ele.hasClass('ignore-dirtyform')) {
return false;
}
var option;
var defaultSelectedIndex = 0;
var numberOfOptions = element.options.length;
for (var i = 0; i < numberOfOptions; i++) {
option = element.options[i];
hasChangedObj = hasChangedObj || option.selected != option.defaultSelected;
if (option.defaultSelected) {
defaultSelectedIndex = i;
}
}
if (hasChangedObj && !element.multiple) {
hasChangedObj = defaultSelectedIndex != element.selectedIndex;
}
if (hasChangedObj) {
return false;
}
}
});
return hasChangedObj;
};
$.fn.extend({
dirtyForm: dirtyForm
});
$(function() {
$(document).on('submit', 'form', function() {
$.fn.qorSlideoutBeforeHide = null;
});
$(document).on('change', 'form', function() {
if ($(this).dirtyForm()) {
$.fn.qorSlideoutBeforeHide = true;
} else {
$.fn.qorSlideoutBeforeHide = null;
}
});
});
});

View File

@@ -0,0 +1,302 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let location = window.location,
$document = $(document),
NAMESPACE = 'qor.filter',
EVENT_FILTER_CHANGE = 'filterChanged.' + NAMESPACE,
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
CLASS_BOTTOMSHEETS = '.qor-bottomsheets',
CLASS_DATE_START = '.qor-filter__start',
CLASS_DATE_END = '.qor-filter__end',
CLASS_SEARCH_PARAM = '[data-search-param]',
CLASS_FILTER_SELECTOR = '.qor-filter__dropdown',
CLASS_FILTER_TOGGLE = '.qor-filter-toggle',
CLASS_IS_SELECTED = 'is-selected';
function QorFilterTime(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorFilterTime.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorFilterTime.prototype = {
constructor: QorFilterTime,
init: function() {
this.bind();
let $element = this.$element,
lcoal_moment = window.moment();
this.$timeStart = $element.find(CLASS_DATE_START);
this.$timeEnd = $element.find(CLASS_DATE_END);
this.$searchParam = $element.find(CLASS_SEARCH_PARAM);
this.$searchButton = $element.find(this.options.button);
this.startWeekDate = lcoal_moment.startOf('isoweek').toDate();
this.endWeekDate = lcoal_moment.endOf('isoweek').toDate();
this.startMonthDate = lcoal_moment.startOf('month').toDate();
this.endMonthDate = lcoal_moment.endOf('month').toDate();
this.initActionTemplate();
},
bind: function() {
var options = this.options;
this.$element
.on(EVENT_CLICK, options.trigger, this.show.bind(this))
.on(EVENT_CLICK, options.label, this.setFilterTime.bind(this))
.on(EVENT_CLICK, options.clear, this.clear.bind(this))
.on(EVENT_CLICK, options.button, this.search.bind(this));
$document.on(EVENT_CLICK, this.close);
},
unbind: function() {
this.$element.off(EVENT_CLICK);
},
initActionTemplate: function() {
let paramFrom = this.$element.data('schedule-from');
let paramTo = this.$element.data('schedule-to');
let scheduleStartAt = this.getUrlParameter(paramFrom || 'schedule_start_at');
let scheduleEndAt = this.getUrlParameter(paramTo || 'schedule_end_at');
let $filterToggle = $(this.options.trigger);
if (scheduleStartAt || scheduleEndAt) {
this.$timeStart.val(scheduleStartAt);
this.$timeEnd.val(scheduleEndAt);
scheduleEndAt = !scheduleEndAt ? '' : ' - ' + scheduleEndAt;
$filterToggle
.addClass('active clearable')
.find('.qor-selector-label')
.html(scheduleStartAt + scheduleEndAt);
$filterToggle.append('<i class="material-icons qor-selector-clear">clear</i>');
}
},
show: function() {
this.$element.find(CLASS_FILTER_SELECTOR).toggle();
},
close: function(e) {
var $target = $(e.target),
$filter = $(CLASS_FILTER_SELECTOR),
filterVisible = $filter.is(':visible'),
isInFilter = $target.closest(CLASS_FILTER_SELECTOR).length,
isInToggle = $target.closest(CLASS_FILTER_TOGGLE).length,
isInModal = $target.closest('.qor-modal').length,
isInTimePicker = $target.closest('.ui-timepicker-wrapper').length;
if (filterVisible && (isInFilter || isInToggle || isInModal || isInTimePicker)) {
return;
}
$filter.hide();
},
setFilterTime: function(e) {
let $target = $(e.target),
data = $target.data(),
range = data.filterRange,
startTime,
endTime,
startDate,
endDate;
if (!range) {
return false;
}
$(this.options.label).removeClass(CLASS_IS_SELECTED);
$target.addClass(CLASS_IS_SELECTED);
if (range == 'events') {
this.$timeStart.val(data.scheduleStartAt || '');
this.$timeEnd.val(data.scheduleEndAt || '');
this.$searchButton.click();
return false;
}
switch (range) {
case 'today':
startDate = endDate = new Date();
break;
case 'week':
startDate = this.startWeekDate;
endDate = this.endWeekDate;
break;
case 'month':
startDate = this.startMonthDate;
endDate = this.endMonthDate;
break;
}
if (!startDate || !endDate) {
return false;
}
startTime = this.getTime(startDate) + ' 00:00';
endTime = this.getTime(endDate) + ' 23:59';
this.$timeStart.val(startTime);
this.$timeEnd.val(endTime);
this.$searchButton.click();
},
getTime: function(dateNow) {
var month = dateNow.getMonth() + 1,
date = dateNow.getDate();
month = month < 10 ? '0' + month : month;
date = date < 10 ? '0' + date : date;
return dateNow.getFullYear() + '-' + month + '-' + date;
},
clear: function() {
var $trigger = $(this.options.trigger),
$label = $trigger.find('.qor-selector-label');
$trigger.removeClass('active clearable');
$label.html($label.data('label'));
this.$timeStart.val('');
this.$timeEnd.val('');
this.$searchButton.click();
return false;
},
getUrlParameter: function(name) {
let search = decodeURIComponent(location.search),
parameterName = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]'),
regex = new RegExp('[\\?&]' + parameterName + '=([^&#]*)'),
results = regex.exec(search);
return results === null ? '' : results[1].replace(/\+/g, ' ');
},
updateQueryStringParameter: function(key, value, url) {
let href = url || location.href,
local_hash = href.match(/#\S*$/) || '',
escapedkey = String(key).replace(/[\\^$*+?.()|[\]{}]/g, '\\$&'),
re = new RegExp('([?&])' + escapedkey + '=.*?(&|$)', 'i'),
separator = href.indexOf('?') !== -1 ? '&' : '?';
if (local_hash) {
local_hash = local_hash[0];
href = href.replace(local_hash, '');
}
if (href.match(re)) {
if (value) {
href = href.replace(re, '$1' + key + '=' + value + '$2');
} else {
if (RegExp.$1 === '?' || RegExp.$1 === RegExp.$2) {
href = href.replace(re, '$1');
} else {
href = href.replace(re, '');
}
}
} else if (value) {
href = href + separator + key + '=' + value;
}
return href + local_hash;
},
search: function() {
var $searchParam = this.$searchParam,
href = location.href,
_this = this,
type = 'qor.filter.time';
if (!$searchParam.length) {
return;
}
$searchParam.each(function() {
var $this = $(this),
searchParam = $this.data().searchParam,
val = $this.val();
href = _this.updateQueryStringParameter(searchParam, val, href);
});
if (this.$element.closest(CLASS_BOTTOMSHEETS).length) {
$(CLASS_BOTTOMSHEETS).trigger(EVENT_FILTER_CHANGE, [href, type]);
} else {
location.href = href;
}
},
destroy: function() {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorFilterTime.DEFAULTS = {
label: false,
trigger: false,
button: false,
clear: false
};
QorFilterTime.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorFilterTime(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = '[data-toggle="qor.filter.time"]';
var options = {
label: '.qor-filter__block-buttons button',
trigger: 'a.qor-filter-toggle',
button: '.qor-filter__button-search',
clear: '.qor-selector-clear'
};
$(document)
.on(EVENT_DISABLE, function(e) {
QorFilterTime.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorFilterTime.plugin.call($(selector, e.target), options);
})
.triggerHandler(EVENT_ENABLE);
});
return QorFilterTime;
});

View File

@@ -0,0 +1,237 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let location = window.location,
NAMESPACE = 'qor.filter',
EVENT_FILTER_CHANGE = 'filterChanged.' + NAMESPACE,
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_CHANGE = 'change.' + NAMESPACE,
CLASS_IS_ACTIVE = 'is-active',
CLASS_BOTTOMSHEETS = '.qor-bottomsheets';
function encodeSearch(data, detached) {
var search = decodeURI(location.search);
var per_page = location.search.match(/per_page=\d+/);
var params;
search = search.replace(/per_page=\d+/g,'').replace(/page=\d+/,'page=1');
if(per_page && per_page.length){
search = search + "&" + per_page[0];
}
if ($.isArray(data)) {
params = decodeSearch(search);
$.each(data, function(i, param) {
i = $.inArray(param, params);
if (i === -1) {
params.push(param);
} else if (detached) {
params.splice(i, 1);
}
});
search = '?' + params.join('&');
}
return search;
}
function decodeSearch(search) {
var data = [];
if (search && search.indexOf('?') > -1) {
search = search.replace(/\+/g, ' ').split('?')[1];
if (search && search.indexOf('#') > -1) {
search = search.split('#')[0];
}
if (search) {
// search = search.toLowerCase();
data = $.map(search.split('&'), function(n) {
var param = [];
var value;
n = n.split('=');
value = n[1];
param.push(n[0]);
if (value) {
value = $.trim(decodeURIComponent(value));
if (value) {
param.push(value);
}
}
return param.join('=');
});
}
}
return data;
}
function QorFilter(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorFilter.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorFilter.prototype = {
constructor: QorFilter,
init: function() {
// this.parse();
this.bind();
},
bind: function() {
var options = this.options;
this.$element.on(EVENT_CLICK, options.label, $.proxy(this.toggle, this)).on(EVENT_CHANGE, options.group, $.proxy(this.toggle, this));
},
unbind: function() {
this.$element.off(EVENT_CLICK, this.toggle).off(EVENT_CHANGE, this.toggle);
},
toggle: function(e) {
let $target = $(e.currentTarget),
data = [],
params,
param,
search,
name,
value,
index,
matched,
paramName;
if ($target.is('select')) {
params = decodeSearch(decodeURI(location.search));
paramName = name = $target.attr('name');
value = $target.val();
param = [name];
if (value) {
param.push(value);
}
param = param.join('=');
if (value) {
data.push(param);
}
$target.children().each(function() {
var $this = $(this);
var param = [name];
var value = $.trim($this.prop('value'));
if (value) {
param.push(value);
}
param = param.join('=');
index = $.inArray(param, params);
if (index > -1) {
matched = param;
return false;
}
});
if (matched) {
data.push(matched);
search = encodeSearch(data, true);
} else {
search = encodeSearch(data);
}
} else if ($target.is('a')) {
e.preventDefault();
paramName = $target.data().paramName;
data = decodeSearch($target.attr('href'));
if ($target.hasClass(CLASS_IS_ACTIVE)) {
search = encodeSearch(data, true); // set `true` to detach
} else {
search = encodeSearch(data);
}
}
if (this.$element.closest(CLASS_BOTTOMSHEETS).length) {
$(CLASS_BOTTOMSHEETS).trigger(EVENT_FILTER_CHANGE, [search, paramName]);
} else {
location.search = search;
}
},
destroy: function() {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorFilter.DEFAULTS = {
label: false,
group: false
};
QorFilter.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorFilter(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = '[data-toggle="qor.filter"]';
var options = {
label: 'a',
group: 'select'
};
$(document)
.on(EVENT_DISABLE, function(e) {
QorFilter.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorFilter.plugin.call($(selector, e.target), options);
})
.triggerHandler(EVENT_ENABLE);
});
return QorFilter;
});

View File

@@ -0,0 +1,169 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let $window = $(window),
NAMESPACE = 'qor.fixer',
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_RESIZE = 'resize.' + NAMESPACE,
EVENT_SCROLL = 'scroll.' + NAMESPACE,
CLASS_FIXED_TABLE = 'qor-table-fixed-header',
CLASS_HEADER = '.qor-page__header';
function QorFixer(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorFixer.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorFixer.prototype = {
constructor: QorFixer,
init: function() {
var options = this.options;
var $this = this.$element;
if (this.isNeedBuild()) {
return;
}
this.$thead = $this.find('> thead');
this.$tbody = $this.find('> tbody');
this.$header = $(options.header);
this.$subHeader = $(options.subHeader);
this.$content = $(options.content);
this.marginBottomPX = parseInt(this.$subHeader.css('marginBottom'));
this.paddingHeight = options.paddingHeight;
this.resize();
this.bind();
},
bind: function() {
this.$content.on(EVENT_SCROLL, this.toggle.bind(this));
$window.on(EVENT_RESIZE, this.resize.bind(this));
},
unbind: function() {
this.$content.off(EVENT_SCROLL, this.toggle).off(EVENT_RESIZE, this.resize);
},
isNeedBuild: function() {
var $this = this.$element;
// disable fixer if have multiple tables or in search page or in media library list page
if (
$('.qor-page__body .qor-js-table').length > 1 ||
$('.qor-global-search--container').length > 0 ||
$this.hasClass('qor-table--medialibrary') ||
$this.is(':hidden') ||
$this.find('tbody > tr:visible').length <= 1 ||
$this.data("disable-fixer")
) {
return true;
}
return false;
},
build: function() {
let headerWidth = [],
$items = this.$tbody.find('> tr:first').children();
$items.each(function() {
let tdWidth = $(this).outerWidth();
$(this).outerWidth(tdWidth);
headerWidth.push(tdWidth);
});
this.$thead
.find('>tr')
.children()
.each(function(i) {
$(this).outerWidth(headerWidth[i]);
});
},
toggle: function() {
if (!this.$content.length) {
return;
}
let $element = this.$element,
$thead = this.$thead,
scrollTop = this.$content.scrollTop(),
offsetTop = this.$subHeader.outerHeight() + this.paddingHeight + this.marginBottomPX,
headerHeight = $('.qor-page__header').outerHeight(),
pageTop = this.$content.offset().top + $(CLASS_HEADER).height();
if (scrollTop > offsetTop - headerHeight) {
$thead.css({top: pageTop});
$element.addClass(CLASS_FIXED_TABLE);
} else {
$element.removeClass(CLASS_FIXED_TABLE);
}
},
resize: function() {
this.build();
this.toggle();
},
destroy: function() {
if (this.buildCheck()) {
return;
}
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorFixer.DEFAULTS = {
header: false,
content: false
};
QorFixer.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
$this.data(NAMESPACE, (data = new QorFixer(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.call(data);
}
});
};
$(function() {
var selector = '.qor-js-table';
var options = {
header: '.mdl-layout__header',
subHeader: '.qor-page__header',
content: '.mdl-layout__content',
paddingHeight: 2 // Fix sub header height bug
};
$(document)
.on(EVENT_DISABLE, function(e) {
QorFixer.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorFixer.plugin.call($(selector, e.target), options);
})
.triggerHandler(EVENT_ENABLE);
});
return QorFixer;
});

View File

@@ -0,0 +1,202 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
const NAMESPACE = 'qor.inlineEdit',
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_MOUSEENTER = 'mouseenter.' + NAMESPACE,
EVENT_MOUSELEAVE = 'mouseleave.' + NAMESPACE,
CLASS_FIELD = '.qor-field',
CLASS_FIELD_SHOW = '.qor-field__show',
CLASS_FIELD_SHOW_INNER = '.qor-field__show-inner',
CLASS_EDIT = '.qor-inlineedit__edit',
CLASS_SAVE = '.qor-inlineedit__save',
CLASS_BUTTONS = '.qor-inlineedit__buttons',
CLASS_CANCEL = '.qor-inlineedit__cancel',
CLASS_CONTAINER = 'qor-inlineedit__field';
function QorInlineEdit(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorInlineEdit.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
function getJsonData(names, data) {
let key,
value = data[names[0].slice(1)];
if (names.length > 1) {
for (let i = 1; i < names.length; i++) {
key = names[i].slice(1);
value = $.isArray(value) ? value[0][key] : value[key];
}
}
return value;
}
QorInlineEdit.prototype = {
constructor: QorInlineEdit,
init: function() {
let $element = this.$element,
saveButton = $element.data('button-save'),
cancelButton = $element.data('button-cancel');
this.TEMPLATE_SAVE = `<div class="qor-inlineedit__buttons">
<button class="mdl-button mdl-button--colored mdl-js-button qor-button--small qor-inlineedit__cancel" type="button">${cancelButton}</button>
<button class="mdl-button mdl-button--colored mdl-js-button qor-button--small qor-inlineedit__save" type="button">${saveButton}</button>
</div>`;
this.bind();
},
bind: function() {
this.$element
.on(EVENT_MOUSEENTER, CLASS_FIELD_SHOW, this.showEditButton)
.on(EVENT_MOUSELEAVE, CLASS_FIELD_SHOW, this.hideEditButton)
.on(EVENT_CLICK, CLASS_CANCEL, this.hideEdit)
.on(EVENT_CLICK, CLASS_SAVE, this.saveEdit)
.on(EVENT_CLICK, CLASS_EDIT, this.showEdit.bind(this));
},
unbind: function() {
this.$element
.off(EVENT_MOUSEENTER)
.off(EVENT_MOUSELEAVE)
.off(EVENT_CLICK);
},
showEditButton: function(e) {
let $edit = $(QorInlineEdit.TEMPLATE_EDIT),
$field = $(e.target).closest(CLASS_FIELD);
if ($field.find('input:disabled, textarea:disabled,select:disabled').length) {
return false;
}
$edit.appendTo($(this));
},
hideEditButton: function() {
$('.qor-inlineedit__edit').remove();
},
showEdit: function(e) {
let $parent = $(e.target)
.closest(CLASS_EDIT)
.hide()
.closest(CLASS_FIELD)
.addClass(CLASS_CONTAINER),
$save = $(this.TEMPLATE_SAVE);
$save.appendTo($parent);
},
hideEdit: function() {
let $parent = $(this)
.closest(CLASS_FIELD)
.removeClass(CLASS_CONTAINER);
$parent.find(CLASS_BUTTONS).remove();
},
saveEdit: function() {
let $btn = $(this),
$parent = $btn.closest(CLASS_FIELD),
$form = $btn.closest('form'),
$hiddenInput = $parent.closest('.qor-fieldset').find('input.qor-hidden__primary_key[type="hidden"]'),
$input = $parent.find('input[name*="QorResource"],textarea[name*="QorResource"],select[name*="QorResource"]'),
names = $input.length && $input.prop('name').match(/\.\w+/g),
inputData = $input.serialize();
if ($hiddenInput.length) {
inputData = `${inputData}&${$hiddenInput.serialize()}`;
}
if (names.length) {
$.ajax($form.prop('action'), {
method: $form.prop('method'),
data: inputData,
dataType: 'json',
beforeSend: function() {
$btn.prop('disabled', true);
},
success: function(data) {
let newValue = getJsonData(names, data),
$show = $parent.removeClass(CLASS_CONTAINER).find(CLASS_FIELD_SHOW),
$inner = $show.find(CLASS_FIELD_SHOW_INNER);
if (typeof newValue === 'string' || newValue instanceof String){
newValue = newValue.escapeSymbol();
}
if ($inner.length) {
$inner.html(newValue);
} else {
$show.html(newValue);
}
$parent.find(CLASS_BUTTONS).remove();
$btn.prop('disabled', false);
},
error: function(err) {
window.QOR.handleAjaxError(err);
$btn.prop('disabled', false);
}
});
}
},
destroy: function() {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorInlineEdit.DEFAULTS = {};
QorInlineEdit.TEMPLATE_EDIT = `<button class="mdl-button mdl-js-button mdl-button--icon mdl-button--colored qor-inlineedit__edit" type="button"><i class="material-icons">mode_edit</i></button>`;
QorInlineEdit.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
$this.data(NAMESPACE, (data = new QorInlineEdit(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.call(data);
}
});
};
$(function() {
let selector = '[data-toggle="qor.inlineEdit"]',
options = {};
$(document)
.on(EVENT_DISABLE, function(e) {
QorInlineEdit.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorInlineEdit.plugin.call($(selector, e.target), options);
})
.triggerHandler(EVENT_ENABLE);
});
return QorInlineEdit;
});

View File

@@ -0,0 +1,59 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let componentHandler = window.componentHandler,
NAMESPACE = 'qor.material',
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_UPDATE = 'update.' + NAMESPACE,
SELECTOR_COMPONENT = '[class*="mdl-js"],[class*="mdl-tooltip"]';
function enable(target) {
/*jshint undef:false */
if (componentHandler) {
// Enable all MDL (Material Design Lite) components within the target element
if ($(target).is(SELECTOR_COMPONENT)) {
componentHandler.upgradeElements(target);
} else {
componentHandler.upgradeElements($(SELECTOR_COMPONENT, target).toArray());
}
}
}
function disable(target) {
/*jshint undef:false */
if (componentHandler) {
// Destroy all MDL (Material Design Lite) components within the target element
if ($(target).is(SELECTOR_COMPONENT)) {
componentHandler.downgradeElements(target);
} else {
componentHandler.downgradeElements($(SELECTOR_COMPONENT, target).toArray());
}
}
}
$(function() {
$(document)
.on(EVENT_ENABLE, function(e) {
enable(e.target);
})
.on(EVENT_DISABLE, function(e) {
disable(e.target);
})
.on(EVENT_UPDATE, function(e) {
disable(e.target);
enable(e.target);
});
});
});

View File

@@ -0,0 +1,235 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let $document = $(document),
NAMESPACE = 'qor.modal',
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_KEYUP = 'keyup.' + NAMESPACE,
EVENT_SHOW = 'show.' + NAMESPACE,
EVENT_SHOWN = 'shown.' + NAMESPACE,
EVENT_HIDE = 'hide.' + NAMESPACE,
EVENT_HIDDEN = 'hidden.' + NAMESPACE,
EVENT_TRANSITION_END = 'transitionend',
CLASS_OPEN = 'qor-modal-open',
CLASS_SHOWN = 'shown',
CLASS_FADE = 'fade',
CLASS_IN = 'in',
ARIA_HIDDEN = 'aria-hidden';
function QorModal(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorModal.DEFAULTS, $.isPlainObject(options) && options);
this.transitioning = false;
this.fadable = false;
this.init();
}
QorModal.prototype = {
constructor: QorModal,
init: function() {
this.fadable = this.$element.hasClass(CLASS_FADE);
if (this.options.show) {
this.show();
} else {
this.toggle();
}
},
bind: function() {
this.$element.on(EVENT_CLICK, $.proxy(this.click, this));
if (this.options.keyboard) {
$document.on(EVENT_KEYUP, $.proxy(this.keyup, this));
}
},
unbind: function() {
this.$element.off(EVENT_CLICK, this.click);
if (this.options.keyboard) {
$document.off(EVENT_KEYUP, this.keyup);
}
},
click: function(e) {
var element = this.$element[0];
var target = e.target;
if (target === element && this.options.backdrop) {
this.hide();
return;
}
while (target !== element) {
if ($(target).data('dismiss') === 'modal') {
this.hide();
break;
}
target = target.parentNode;
}
},
keyup: function(e) {
if (e.which === 27) {
this.hide();
}
},
show: function(noTransition) {
var $this = this.$element,
showEvent;
if (this.transitioning || $this.hasClass(CLASS_IN)) {
return;
}
showEvent = $.Event(EVENT_SHOW);
$this.trigger(showEvent);
if (showEvent.isDefaultPrevented()) {
return;
}
$document.find('body').addClass(CLASS_OPEN);
/*jshint expr:true */
$this
.addClass(CLASS_SHOWN)
.scrollTop(0)
.get(0).offsetHeight; // reflow for transition
this.transitioning = true;
if (noTransition || !this.fadable) {
$this.addClass(CLASS_IN);
this.shown();
return;
}
$this.one(EVENT_TRANSITION_END, $.proxy(this.shown, this));
$this.addClass(CLASS_IN);
},
shown: function() {
this.transitioning = false;
this.bind();
this.$element
.attr(ARIA_HIDDEN, false)
.trigger(EVENT_SHOWN)
.focus();
},
hide: function(noTransition) {
var $this = this.$element,
hideEvent;
if (this.transitioning || !$this.hasClass(CLASS_IN)) {
return;
}
hideEvent = $.Event(EVENT_HIDE);
$this.trigger(hideEvent);
if (hideEvent.isDefaultPrevented()) {
return;
}
$document.find('body').removeClass(CLASS_OPEN);
this.transitioning = true;
if (noTransition || !this.fadable) {
$this.removeClass(CLASS_IN);
this.hidden();
return;
}
$this.one(EVENT_TRANSITION_END, $.proxy(this.hidden, this));
$this.removeClass(CLASS_IN);
},
hidden: function() {
this.transitioning = false;
this.unbind();
this.$element
.removeClass(CLASS_SHOWN)
.attr(ARIA_HIDDEN, true)
.trigger(EVENT_HIDDEN);
},
toggle: function() {
if (this.$element.hasClass(CLASS_IN)) {
this.hide();
} else {
this.show();
}
},
destroy: function() {
this.$element.removeData(NAMESPACE);
}
};
QorModal.DEFAULTS = {
backdrop: false,
keyboard: true,
show: true
};
QorModal.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorModal(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$.fn.qorModal = QorModal.plugin;
$(function() {
var selector = '.qor-modal';
$(document)
.on(EVENT_CLICK, '[data-toggle="qor.modal"]', function() {
var $this = $(this);
var data = $this.data();
var $target = $(data.target || $this.attr('href'));
QorModal.plugin.call($target, $target.data(NAMESPACE) ? 'toggle' : data);
})
.on(EVENT_DISABLE, function(e) {
QorModal.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorModal.plugin.call($(selector, e.target));
});
});
return QorModal;
});

View File

@@ -0,0 +1,109 @@
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function ($) {
'use strict';
var NAMESPACE = 'qor.tabbar.radio';
var EVENT_ENABLE = 'enable.' + NAMESPACE;
var EVENT_DISABLE = 'disable.' + NAMESPACE;
var EVENT_CLICK = 'click.' + NAMESPACE;
var EVENT_SWITCHED = 'switched.' + NAMESPACE;
var CLASS_TAB = '[data-tab-target]';
var CLASS_TAB_SOURCE = '[data-tab-source]';
var CLASS_ACTIVE = 'is-active';
function QorTabRadio(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorTabRadio.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorTabRadio.prototype = {
constructor: QorTabRadio,
init: function () {
this.bind();
},
bind: function () {
this.$element.on(EVENT_CLICK, CLASS_TAB, this.switchTab.bind(this));
},
unbind: function () {
this.$element.off(EVENT_CLICK, CLASS_TAB, this.switchTab);
},
switchTab: function (e) {
var $target = $(e.target),
$element = this.$element,
$tabs = $element.find(CLASS_TAB),
$tabSources = $element.find(CLASS_TAB_SOURCE),
data = $target.data(),
tabTarget = data.tabTarget;
if ($target.hasClass(CLASS_ACTIVE)){
return;
}
$tabs.removeClass(CLASS_ACTIVE);
$target.addClass(CLASS_ACTIVE);
$tabSources.hide().filter('[data-tab-source="' + tabTarget + '"]').show();
$element.trigger(EVENT_SWITCHED, [$element, tabTarget]);
},
destroy: function () {
this.unbind();
}
};
QorTabRadio.DEFAULTS = {};
QorTabRadio.plugin = function (options) {
return this.each(function () {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorTabRadio(this, options)));
}
if (typeof options === 'string' && $.isFunction(fn = data[options])) {
fn.apply(data);
}
});
};
$(function () {
var selector = '[data-toggle="qor.tab.radio"]';
$(document)
.on(EVENT_DISABLE, function (e) {
QorTabRadio.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function (e) {
QorTabRadio.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorTabRadio;
});

View File

@@ -0,0 +1,452 @@
(function(factory) {
if (typeof define === "function" && define.amd) {
// AMD. Register as anonymous module.
define(["jquery"], factory);
} else if (typeof exports === "object") {
// Node / CommonJS
factory(require("jquery"));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
"use strict";
let NAMESPACE = "qor.redactor",
EVENT_ENABLE = "enable." + NAMESPACE,
EVENT_DISABLE = "disable." + NAMESPACE,
EVENT_CLICK = "click." + NAMESPACE,
EVENT_ADD_CROP = "addCrop." + NAMESPACE,
EVENT_REMOVE_CROP = "removeCrop." + NAMESPACE,
EVENT_SHOWN = "shown.qor.modal",
EVENT_HIDDEN = "hidden.qor.modal",
EVENT_SCROLL = "scroll." + NAMESPACE,
CLASS_WRAPPER = ".qor-cropper__wrapper",
CLASS_SAVE = ".qor-cropper__save",
CLASS_CROPPER_TOGGLE = ".qor-cropper__toggle--redactor";
function encodeCropData(data) {
var nums = [];
if ($.isPlainObject(data)) {
$.each(data, function() {
nums.push(arguments[1]);
});
}
return nums.join();
}
function decodeCropData(data) {
var nums = data && data.split(",");
data = null;
if (nums && nums.length === 4) {
data = {
x: Number(nums[0]),
y: Number(nums[1]),
width: Number(nums[2]),
height: Number(nums[3])
};
}
return data;
}
function capitalize(str) {
if (typeof str === "string") {
str = str.charAt(0).toUpperCase() + str.substr(1);
}
return str;
}
function getCapitalizeKeyObject(obj) {
var newObj = {},
key;
if ($.isPlainObject(obj)) {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[capitalize(key)] = obj[key];
}
}
}
return newObj;
}
function replaceText(str, data) {
if (typeof str === "string") {
if (typeof data === "object") {
$.each(data, function(key, val) {
str = str.replace("$[" + String(key).toLowerCase() + "]", val);
});
}
}
return str;
}
function redactorToolbarSrcoll($toolbar, $container, toolbarFixedTopOffset) {
let offsetTop = $container.offset().top,
containerHeight = $container.outerHeight(),
normallCSS = {
position: "relative",
top: "auto",
width: "auto"
},
fixedCSS = {
position: "fixed",
top: toolbarFixedTopOffset,
width: $container.width(),
boxShadow: "none"
};
if (offsetTop < toolbarFixedTopOffset) {
if (
Math.abs(offsetTop) < Math.abs(containerHeight - toolbarFixedTopOffset)
) {
$toolbar.css(fixedCSS);
$container.css("padding-top", $toolbar.outerHeight());
} else {
$toolbar.css(normallCSS);
$container.css("padding-top", 0);
}
} else {
$toolbar.css(normallCSS);
$container.css("padding-top", 0);
}
}
function QorRedactor(element, options) {
this.$element = $(element);
this.options = $.extend(
true,
{},
QorRedactor.DEFAULTS,
$.isPlainObject(options) && options
);
this.init();
}
QorRedactor.prototype = {
constructor: QorRedactor,
init: function() {
var options = this.options;
var $this = this.$element;
var $parent = $this.closest(options.parent);
if (!$parent.length) {
$parent = $this.parent();
}
this.$parent = $parent;
this.$button = $(QorRedactor.BUTTON);
this.$modal = $(replaceText(QorRedactor.MODAL, options.text)).appendTo(
"body"
);
this.bind();
},
bind: function() {
this.$element
.on(EVENT_ADD_CROP, $.proxy(this.addButton, this))
.on(EVENT_REMOVE_CROP, $.proxy(this.removeButton, this));
},
unbind: function() {
this.$element
.off(EVENT_ADD_CROP)
.off(EVENT_REMOVE_CROP)
.off(EVENT_SCROLL);
},
addButton: function(e, image) {
var $image = $(image);
this.$button
.css("left", $(image).width() / 2)
.prependTo($image.parent())
.find(CLASS_CROPPER_TOGGLE)
.one(EVENT_CLICK, $.proxy(this.crop, this, $image));
},
removeButton: function() {
this.$button.find(CLASS_CROPPER_TOGGLE).off(EVENT_CLICK);
this.$button.detach();
},
crop: function($image) {
let options = this.options,
url = $image.attr("src"),
originalUrl = url,
$clone,
$modal = this.$modal;
if ($.isFunction(options.replace)) {
originalUrl = options.replace(originalUrl);
}
$clone = $(`<img src='${originalUrl}'>`);
$modal
.one(EVENT_SHOWN, function() {
$clone.cropper({
data: decodeCropData($image.attr("data-crop-options")),
background: false,
movable: false,
zoomable: false,
scalable: false,
rotatable: false,
checkImageOrigin: false,
ready: function() {
$modal.find(CLASS_SAVE).one(EVENT_CLICK, function() {
var cropData = $clone.cropper("getData", true);
$.ajax(options.remote, {
type: "POST",
contentType: "application/json",
data: JSON.stringify({
Url: url,
CropOptions: {
original: getCapitalizeKeyObject(cropData)
},
Crop: true
}),
dataType: "json",
success: function(response) {
if ($.isPlainObject(response) && response.url) {
$image
.attr("src", response.url)
.attr("data-crop-options", encodeCropData(cropData))
.removeAttr("style")
.removeAttr("rel");
if ($.isFunction(options.complete)) {
options.complete();
}
$modal.qorModal("hide");
}
}
});
});
}
});
})
.one(EVENT_HIDDEN, function() {
$clone.cropper("destroy").remove();
})
.qorModal("show")
.find(CLASS_WRAPPER)
.append($clone);
},
destroy: function() {
this.unbind();
this.$modal.qorModal("hide").remove();
this.$element.removeData(NAMESPACE);
}
};
QorRedactor.DEFAULTS = {
remote: false,
parent: false,
toggle: false,
replace: null,
complete: null,
text: {
title: "Crop the image",
ok: "OK",
cancel: "Cancel"
}
};
QorRedactor.BUTTON = `<div class="qor-redactor__image--buttons">
<span class="qor-redactor__image--edit" contenteditable="false">Edit</span>
<span class="qor-cropper__toggle--redactor" contenteditable="false">Crop</span>
</div>`;
QorRedactor.MODAL = `<div class="qor-modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="mdl-card mdl-shadow--2dp" role="document">
<div class="mdl-card__title">
<h2 class="mdl-card__title-text">$[title]</h2>
</div>
<div class="mdl-card__supporting-text">
<div class="qor-cropper__wrapper"></div>
</div>
<div class="mdl-card__actions mdl-card--border">
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect qor-cropper__save">$[ok]</a>
<a class="mdl-button mdl-button--colored mdl-js-button mdl-js-ripple-effect" data-dismiss="modal">$[cancel]</a>
</div>
<div class="mdl-card__menu">
<button class="mdl-button mdl-button--icon mdl-js-button mdl-js-ripple-effect" data-dismiss="modal" aria-label="close">
<i class="material-icons">close</i>
</button>
</div>
</div>
</div>`;
QorRedactor.plugin = function(option) {
return this.each(function() {
let $this = $(this),
data = $this.data(NAMESPACE),
config,
fn;
if (!data) {
if (!window.$R) {
return;
}
if (/destroy/.test(option)) {
return;
}
$this.data(NAMESPACE, (data = {}));
let editorButtons = [
"html",
"format",
"bold",
"italic",
"deleted",
"lists",
"image",
"file",
"link"
];
config = {
imageUpload: $this.data("uploadUrl"),
fileUpload: $this.data("uploadUrl"),
buttons: editorButtons,
linkNewTab: true,
linkTitle: false,
autoparsePaste: false,
autoparseLinks: false,
multipleUpload: false,
toolbarFixedTarget:
!$this.closest(".qor-slideout").length &&
!$this.closest(".qor-bottomsheets").length
? $("main.mdl-layout__content").length
? "main.mdl-layout__content"
: document
: document,
callbacks: {
started: function() {
let $container = $(this.container.$container.nodes[0]),
$toolbar = $(this.toolbar.$toolbar.nodes[0]),
isInSlideout = $(".qor-slideout").is(":visible"),
toolbarFixedTarget,
toolbarFixedTopOffset = 64;
if (isInSlideout) {
if ($this.closest(".qor-bottomsheets").length != 0) {
toolbarFixedTarget = $this.closest(".qor-page__body");
toolbarFixedTopOffset = $this
.closest(".qor-page__body")
.offset().top;
} else {
toolbarFixedTarget = ".qor-slideout__body";
toolbarFixedTopOffset = $(".qor-slideout__header").height();
}
} else {
toolbarFixedTarget = ".qor-layout main.qor-page";
toolbarFixedTopOffset =
toolbarFixedTopOffset +
$(toolbarFixedTarget)
.find(".qor-page__header")
.height();
}
$(toolbarFixedTarget).on(EVENT_SCROLL, function() {
redactorToolbarSrcoll(
$toolbar,
$container,
toolbarFixedTopOffset
);
});
if (!$this.data("cropUrl")) {
return;
}
$this.data(
NAMESPACE,
(data = new QorRedactor($this, {
remote: $this.data("cropUrl"),
text: $this.data("text"),
parent: ".qor-field",
toggle: ".qor-cropper__toggle--redactor",
replace: function(url) {
return url.replace(/\.\w+$/, function(extension) {
return ".original" + extension;
});
},
complete: $.proxy(function() {
this.code.sync();
}, this)
}))
);
},
imageUpload: function(image, json) {
var $image = $(image);
json.filelink && $image.prop("src", json.filelink);
},
insertedLink: function(link) {
var $link = $(link),
description = this.link.description;
$link.prop("title", description ? description : $link.text());
this.link.description = "";
this.link.linkUrlText = "";
this.link.insertedTriggered = true;
},
fileUpload: function(link, json) {
$(link)
.prop("href", json.filelink)
.html(json.filename);
}
}
};
$.extend(config, $this.data("redactorSettings"));
window.$R.prototype.constructor.services.editor.prototype.focus = function() {
return false;
};
window.$R(this, config);
} else {
if (/destroy/.test(option)) {
window.$R(this, "destroy");
}
}
if (typeof option === "string" && $.isFunction((fn = data[option]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = 'textarea[data-toggle="qor.redactor"]';
$(document)
.on(EVENT_DISABLE, function(e) {
QorRedactor.plugin.call($(selector, e.target), "destroy");
})
.on(EVENT_ENABLE, function(e) {
QorRedactor.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorRedactor;
});

View File

@@ -0,0 +1,417 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let _ = window._,
QOR = window.QOR,
NAMESPACE = 'qor.replicator',
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_SUBMIT = 'submit.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_SLIDEOUTBEFORESEND = 'slideoutBeforeSend.qor.slideout.replicator',
EVENT_SELECTCOREBEFORESEND = 'selectcoreBeforeSend.qor.selectcore.replicator bottomsheetBeforeSend.qor.bottomsheets.replicator',
EVENT_REPLICATOR_ADDED = 'added.' + NAMESPACE,
EVENT_REPLICATORS_ADDED = 'addedMultiple.' + NAMESPACE,
EVENT_REPLICATORS_ADDED_DONE = 'addedMultipleDone.' + NAMESPACE,
CLASS_CONTAINER = '.qor-fieldset-container';
function QorReplicator(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorReplicator.DEFAULTS, $.isPlainObject(options) && options);
this.index = 0;
this.init();
}
QorReplicator.prototype = {
constructor: QorReplicator,
init: function() {
let $element = this.$element,
$template = $element.find('> .qor-field__block > .qor-fieldset--new'),
fieldsetName;
this.singlePage = !($element.closest('.qor-slideout').length && $element.closest('.qor-bottomsheets').length);
this.maxitems = $element.data('maxItem');
this.isSortable = $element.hasClass('qor-fieldset-sortable');
if (!$template.length || $element.closest('.qor-fieldset--new').length) {
return;
}
// Should destroy all components here
$template.trigger('disable');
// remove data-select2-id attribute or select2 will disable all previous instance
$template.find('select[data-toggle]').removeAttr('data-select2-id');
// if have isMultiple data value or template length large than 1
this.isMultipleTemplate = $element.data('isMultiple');
if (this.isMultipleTemplate) {
this.fieldsetName = [];
this.template = {};
this.index = [];
$template.each((i, ele) => {
fieldsetName = $(ele).data('fieldsetName');
if (fieldsetName) {
this.template[fieldsetName] = $(ele).prop('outerHTML');
this.fieldsetName.push(fieldsetName);
}
});
this.parseMultiple();
} else {
this.parse($template.prop('outerHTML'));
}
$template.hide();
this.bind();
this.resetButton();
this.resetPositionButton();
},
resetPositionButton: function() {
let sortableButton = this.$element.find('> .qor-sortable__button');
if (this.isSortable) {
if (this.getCurrentItems() > 1) {
sortableButton.show();
} else {
sortableButton.hide();
}
}
},
getCurrentItems: function() {
return this.$element.find('> .qor-field__block > .qor-fieldset').not('.qor-fieldset--new,.is-deleted').length;
},
toggleButton: function(isHide) {
let $button = this.$element.find('> .qor-field__block > .qor-fieldset__add');
if (isHide) {
$button.hide();
} else {
$button.show();
}
},
resetButton: function() {
if (this.maxitems <= this.getCurrentItems()) {
this.toggleButton(true);
} else {
this.toggleButton();
}
},
parse: function($tmp) {
let template;
if (!$tmp) {
return;
}
template = this.initTemplate($tmp);
this.template = template.template;
this.index = template.index;
},
parseMultiple: function() {
let template,
name,
fieldsetName = this.fieldsetName;
for (let i = 0, len = fieldsetName.length; i < len; i++) {
name = fieldsetName[i];
template = this.initTemplate(this.template[name]);
this.template[name] = template.template;
this.index.push(template.index);
}
this.multipleIndex = _.max(this.index);
},
initTemplate: function(template) {
let i,
deepLevel = this.$element.parents(CLASS_CONTAINER).length;
template = template.replace(/(\w+)\="(\S*\[\d+\]\S*)"/g, function(attribute, name, value) {
value = value.replace(/^(\S*)\[(\d+)\]([^\[\]]*)$/, function(input, prefix, index) {
if (input === value) {
if (name === 'name' && !i) {
i = index;
}
if (deepLevel) {
// assume input = QorResource.SerializableMeta.Menus[1].SubMenus[2].Items[3].URL
// if deepLevel = 1, input should be QorResource.SerializableMeta.Menus[1].SubMenus[{{index}}].Items[3].URL
// if deepLevel = 2, input should be QorResource.SerializableMeta.Menus[1].SubMenus[2].Items[{{index}}].URL
let newInput = '',
splitStr = input.split(/\[\d+\]/), // ["QorResource.SerializableMeta.Menus", ".SubMenus", ".Items", ".URL"]
sortNumbers = input.match(/\[\d+\]/g); // ["[1]", "[2]", "[3]"]
for (let j = 0; j < splitStr.length; j++) {
let str = '';
if (j === deepLevel) {
str = '[{{index}}]';
} else if (j < sortNumbers.length) {
str = sortNumbers[j];
}
newInput += splitStr[j] + str;
}
return newInput;
} else {
return input.replace(/\[\d+\]/, '[{{index}}]');
}
}
});
return name + '="' + value + '"';
});
return {
template: template,
index: parseFloat(i) + 5 //make sure the index is different from original.
};
},
bind: function() {
let options = this.options;
this.$element.on(EVENT_CLICK, options.addClass, $.proxy(this.add, this)).on(EVENT_CLICK, options.delClass, $.proxy(this.del, this));
this.singlePage && $(document).on(EVENT_SUBMIT, '.mdl-layout__container form', this.clearFieldData);
$(document)
.on(EVENT_SLIDEOUTBEFORESEND, '.qor-slideout', this.clearFieldDataInSlideout)
.on(EVENT_SELECTCOREBEFORESEND, this.clearFieldDataInBottomsheet);
},
unbind: function() {
this.$element.off(EVENT_CLICK);
this.singlePage && $(document).off(EVENT_SUBMIT, '.mdl-layout__container form', this.clearFieldData);
$(document)
.off(EVENT_SLIDEOUTBEFORESEND, '.qor-slideout', this.clearFieldDataInSlideout)
.off(EVENT_SELECTCOREBEFORESEND, this.clearFieldDataInBottomsheet);
},
clearFieldData: function() {
$('.qor-fieldset--new').remove();
},
clearFieldDataInSlideout: function() {
$('.qor-slideout .qor-fieldset--new').remove();
},
clearFieldDataInBottomsheet: function() {
$('.qor-bottomsheets .qor-fieldset--new').remove();
},
add: function(e, data, isAutomatically) {
let options = this.options,
$item,
template,
$target = $(e.target).closest(options.addClass);
if (this.maxitems <= this.getCurrentItems()) {
return false;
}
if (this.isMultipleTemplate) {
let templateName = $target.data('template'),
parents = $target.closest(this.$element),
parentsChildren = parents.children(options.childrenClass),
$fieldset = $target.closest(options.childrenClass).children('fieldset');
template = this.template[templateName];
$item = $(template.replace(/\{\{index\}\}/g, this.multipleIndex));
// get input kind from add button then add into QorResource.Rules[1].Kind input
for (let dataKey in $target.data()) {
if (dataKey.match(/^sync/)) {
let k = dataKey.replace(/^sync/, '');
$item.find("input[name*='." + k + "']").val($target.data(dataKey));
}
}
if ($fieldset.length) {
$fieldset.last().after($item.show());
} else {
parentsChildren.prepend($item.show());
}
$item.data('itemIndex', this.multipleIndex).removeClass('qor-fieldset--new');
this.multipleIndex++;
} else {
if (!isAutomatically) {
$item = this.addSingle();
$target.before($item.show());
this.index++;
} else {
if (data && data.length) {
this.addMultiple(data);
$(document).trigger(EVENT_REPLICATORS_ADDED_DONE);
}
}
}
if (!isAutomatically) {
$item.trigger('enable');
$(document).trigger(EVENT_REPLICATOR_ADDED, [$item]);
e.stopPropagation();
}
this.resetPositionButton();
this.resetButton();
},
addMultiple: function(data) {
let $item;
for (let i = 0, len = data.length; i < len; i++) {
$item = this.addSingle();
this.index++;
$(document).trigger(EVENT_REPLICATORS_ADDED, [$item, data[i]]);
}
},
addSingle: function() {
let $item,
$element = this.$element;
if (!this.template) {
return;
}
$item = $(this.template.replace(/\{\{index\}\}/g, this.index));
// add order property for sortable fieldset
if (this.isSortable) {
let order = $element.find('> .qor-field__block > .qor-sortable__item').not('.qor-fieldset--new').length;
$item
.attr('order-index', order)
.attr('order-item', `item_${order}`)
.css('order', order);
}
$item.data('itemIndex', this.index).removeClass('qor-fieldset--new');
return $item;
},
del: function(e) {
let options = this.options,
$item = $(e.target).closest(options.itemClass),
$alert,
that = this,
message = {
confirm:
$(e.target)
.closest(options.delClass)
.data('confirm') || 'Are you sure?'
};
QOR.qorConfirm(message, function(confirm) {
if (confirm) {
$item
.addClass('is-deleted')
.children(':visible')
.addClass('hidden')
.hide();
$alert = $(options.alertTemplate.replace('{{name}}', that.parseName($item)));
$alert.find(options.undoClass).one(
EVENT_CLICK,
function() {
if (that.maxitems <= that.getCurrentItems()) {
window.QOR.qorConfirm(that.$element.data('maxItemHint'));
return false;
}
$item.find('> .qor-fieldset__alert').remove();
$item
.removeClass('is-deleted')
.children('.hidden')
.removeClass('hidden')
.show();
that.resetButton();
that.resetPositionButton();
}.bind(this)
);
that.resetButton();
that.resetPositionButton();
$item.append($alert);
}
});
},
parseName: function($item) {
let name = $item.find('input[name]').attr('name') || $item.find('textarea[name]').attr('name');
if (name) {
return name.replace(/[^\[\]]+$/, '');
}
},
destroy: function() {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorReplicator.DEFAULTS = {
itemClass: '.qor-fieldset',
newClass: '.qor-fieldset--new',
addClass: '.qor-fieldset__add',
delClass: '.qor-fieldset__delete',
childrenClass: '.qor-field__block',
undoClass: '.qor-fieldset__undo',
alertTemplate:
'<div class="qor-fieldset__alert">' +
'<input type="hidden" name="{{name}}._destroy" value="1">' +
'<button class="mdl-button mdl-button--accent mdl-js-button mdl-js-ripple-effect qor-fieldset__undo" type="button">Undo delete</button>' +
'</div>'
};
QorReplicator.plugin = function(options) {
return this.each(function() {
let $this = $(this),
data = $this.data(NAMESPACE),
fn;
if (!data) {
$this.data(NAMESPACE, (data = new QorReplicator(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.call(data);
}
});
};
$(function() {
let selector = CLASS_CONTAINER;
let options = {};
$(document)
.on(EVENT_DISABLE, function(e) {
QorReplicator.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorReplicator.plugin.call($(selector, e.target), options);
})
.triggerHandler(EVENT_ENABLE);
});
return QorReplicator;
});

View File

@@ -0,0 +1,163 @@
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function ($) {
'use strict';
var location = window.location;
var componentHandler = window.componentHandler;
var history = window.history;
var NAMESPACE = 'qor.globalSearch';
var EVENT_ENABLE = 'enable.' + NAMESPACE;
var EVENT_DISABLE = 'disable.' + NAMESPACE;
var EVENT_CLICK = 'click.' + NAMESPACE;
var SEARCH_RESOURCE = '.qor-global-search--resource';
var SEARCH_RESULTS = '.qor-global-search--results';
var QOR_TABLE = '.qor-table';
var IS_ACTIVE = 'is-active';
function QorSearchCenter(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorSearchCenter.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorSearchCenter.prototype = {
constructor: QorSearchCenter,
init: function () {
this.bind();
this.initTab();
},
bind: function () {
this.$element.on(EVENT_CLICK, $.proxy(this.click, this));
},
unbind: function () {
this.$element.off(EVENT_CLICK, this.check);
},
initTab: function () {
var locationSearch = location.search;
var resourceName;
if (/resource_name/.test(locationSearch)){
resourceName = locationSearch.match(/resource_name=\w+/g).toString().split('=')[1];
$(SEARCH_RESOURCE).removeClass(IS_ACTIVE);
$('[data-resource="' + resourceName + '"]').addClass(IS_ACTIVE);
}
},
click : function (e) {
var $target = $(e.target);
var data = $target.data();
if ($target.is(SEARCH_RESOURCE)){
var oldUrl = location.href.replace(/#/g, '');
var newUrl;
var newResourceName = data.resource;
var hasResource = /resource_name/.test(oldUrl);
var hasKeyword = /keyword/.test(oldUrl);
var resourceParam = 'resource_name=' + newResourceName;
var searchSymbol = hasKeyword ? '&' : '?keyword=&';
if (newResourceName){
if (hasResource){
newUrl = oldUrl.replace(/resource_name=\w+/g, resourceParam);
} else {
newUrl = oldUrl + searchSymbol + resourceParam;
}
} else {
newUrl = oldUrl.replace(/&resource_name=\w+/g, '');
}
if (history.pushState){
this.fetchSearch(newUrl, $target);
} else {
location.href = newUrl;
}
}
},
fetchSearch: function (url,$target) {
var title = document.title;
$.ajax(url, {
method: 'GET',
dataType: 'html',
beforeSend: function () {
$('.mdl-spinner').remove();
$(SEARCH_RESULTS).prepend('<div class="mdl-spinner mdl-js-spinner is-active"></div>').find('.qor-section').hide();
componentHandler.upgradeElement(document.querySelector('.mdl-spinner'));
},
success: function (html) {
var result = $(html).find(SEARCH_RESULTS).html();
$(SEARCH_RESOURCE).removeClass(IS_ACTIVE);
$target.addClass(IS_ACTIVE);
// change location URL without refresh page
history.pushState({ Page: url, Title: title }, title, url);
$('.mdl-spinner').remove();
$(SEARCH_RESULTS).removeClass('loading').html(result);
componentHandler.upgradeElements(document.querySelectorAll(QOR_TABLE));
},
error: function (xhr, textStatus, errorThrown) {
$(SEARCH_RESULTS).find('.qor-section').show();
$('.mdl-spinner').remove();
window.alert([textStatus, errorThrown].join(': '));
}
});
},
destroy: function () {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorSearchCenter.DEFAULTS = {
};
QorSearchCenter.plugin = function (options) {
return this.each(function () {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
$this.data(NAMESPACE, (data = new QorSearchCenter(this, options)));
}
if (typeof options === 'string' && $.isFunction(fn = data[options])) {
fn.call(data);
}
});
};
$(function () {
var selector = '[data-toggle="qor.global.search"]';
var options = {};
$(document).
on(EVENT_DISABLE, function (e) {
QorSearchCenter.plugin.call($(selector, e.target), 'destroy');
}).
on(EVENT_ENABLE, function (e) {
QorSearchCenter.plugin.call($(selector, e.target), options);
}).
triggerHandler(EVENT_ENABLE);
});
return QorSearchCenter;
});

View File

@@ -0,0 +1,170 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let FormData = window.FormData,
QOR = window.QOR,
NAMESPACE = 'qor.selectcore',
EVENT_SELECTCORE_BEFORESEND = 'selectcoreBeforeSend.' + NAMESPACE,
EVENT_ONSELECT = 'afterSelected.' + NAMESPACE,
EVENT_ONSUBMIT = 'afterSubmitted.' + NAMESPACE,
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_SUBMIT = 'submit.' + NAMESPACE,
CLASS_TABLE = 'table.qor-js-table tr',
CLASS_FORM = 'form';
function QorSelectCore(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorSelectCore.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorSelectCore.prototype = {
constructor: QorSelectCore,
init: function() {
this.bind();
},
bind: function() {
this.$element.on(EVENT_CLICK, CLASS_TABLE, this.processingData.bind(this)).on(EVENT_SUBMIT, CLASS_FORM, this.submit.bind(this));
},
unbind: function() {
this.$element.off(EVENT_CLICK, CLASS_TABLE).off(EVENT_SUBMIT, CLASS_FORM);
},
processingData: function(e) {
let $this = $(e.target).closest('tr'),
$bottomsheets = $this.closest('.qor-bottomsheets'),
data = {},
url,
options = this.options,
onSelect = options.onSelect,
loading = options.loading;
data = $.extend({}, data, $this.data());
data.$clickElement = $this;
url = data.mediaLibraryUrl || data.url;
if (loading && $.isFunction(loading)) {
loading($bottomsheets);
}
if (url) {
$.getJSON(url, function(json) {
json.MediaOption && (json.MediaOption = JSON.parse(json.MediaOption));
data = $.extend({}, json, data);
if (onSelect && $.isFunction(onSelect)) {
onSelect(data, e);
$(document).trigger(EVENT_ONSELECT);
}
}).always(function() {
$bottomsheets.find('.qor-media-loading').remove();
});
} else {
if (onSelect && $.isFunction(onSelect)) {
onSelect(data, e);
$(document).trigger(EVENT_ONSELECT);
}
}
return false;
},
submit: function(e) {
let form = e.target,
$form = $(form),
_this = this,
$submit = $form.find(':submit'),
data,
$loading = $(QOR.$formLoading),
onSubmit = this.options.onSubmit;
$(document).trigger(EVENT_SELECTCORE_BEFORESEND);
$form.find('.qor-fieldset--new').remove();
if (FormData) {
e.preventDefault();
$.ajax($form.prop('action'), {
method: $form.prop('method'),
data: new FormData(form),
dataType: 'json',
processData: false,
contentType: false,
beforeSend: function() {
$('.qor-submit-loading').remove();
$loading.appendTo($submit.prop('disabled', true).closest('.qor-form__actions')).trigger('enable.qor.material');
},
success: function(json) {
json.MediaOption && (json.MediaOption = JSON.parse(json.MediaOption));
data = json;
data.primaryKey = data.ID;
$('.qor-error').remove();
if (onSubmit && $.isFunction(onSubmit)) {
onSubmit(data, e);
$(document).trigger(EVENT_ONSUBMIT);
} else {
_this.refresh();
}
},
error: function(err) {
QOR.handleAjaxError(err);
},
complete: function() {
$submit.prop('disabled', false);
}
});
}
},
refresh: function() {
setTimeout(function() {
window.location.reload();
}, 350);
},
destroy: function() {
this.unbind();
}
};
QorSelectCore.plugin = function(options) {
return this.each(function() {
let $this = $(this),
data = $this.data(NAMESPACE),
fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorSelectCore(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$.fn.qorSelectCore = QorSelectCore.plugin;
return QorSelectCore;
});

View File

@@ -0,0 +1,339 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let $body = $('body'),
$document = $(document),
Mustache = window.Mustache,
NAMESPACE = 'qor.selectone',
PARENT_NAMESPACE = 'qor.bottomsheets',
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_RELOAD = 'reload.' + PARENT_NAMESPACE,
CLASS_CLEAR_SELECT = '.qor-selected-many__remove',
CLASS_UNDO_DELETE = '.qor-selected-many__undo',
CLASS_DELETED_ITEM = 'qor-selected-many__deleted',
CLASS_SELECT_FIELD = '.qor-field__selected-many',
CLASS_SELECT_INPUT = '.qor-field__selectmany-input',
CLASS_SELECT_ICON = '.qor-select__select-icon',
CLASS_SELECT_HINT = '.qor-selectmany__hint',
CLASS_SELECT_ALL = '.qor-selectmany__selectall',
CLASS_PARENT = '.qor-field__selectmany',
CLASS_SELECTED = 'is_selected',
CLASS_MANY = 'qor-bottomsheets__select-many';
function QorSelectMany(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorSelectMany.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorSelectMany.prototype = {
constructor: QorSelectMany,
init: function() {
this.bind();
},
bind: function() {
$document.on(EVENT_RELOAD, `.${CLASS_MANY}`, this.reloadData.bind(this));
this.$element
.on(EVENT_CLICK, CLASS_CLEAR_SELECT, this.clearSelect.bind(this))
.on(EVENT_CLICK, '[data-select-modal="many"]', this.openBottomSheets.bind(this))
.on(EVENT_CLICK, CLASS_UNDO_DELETE, this.undoDelete.bind(this));
},
unbind: function() {
$document.off(EVENT_CLICK, '[data-select-modal="many"]').off(EVENT_RELOAD, `.${CLASS_MANY}`);
this.$element.off(EVENT_CLICK, CLASS_CLEAR_SELECT).off(EVENT_CLICK, CLASS_UNDO_DELETE);
},
clearSelect: function(e) {
var $target = $(e.target),
$selectFeild = $target.closest(CLASS_PARENT);
$target.closest('[data-primary-key]').addClass(CLASS_DELETED_ITEM);
this.updateSelectInputData($selectFeild);
return false;
},
undoDelete: function(e) {
var $target = $(e.target),
$selectFeild = $target.closest(CLASS_PARENT);
$target.closest('[data-primary-key]').removeClass(CLASS_DELETED_ITEM);
this.updateSelectInputData($selectFeild);
return false;
},
openBottomSheets: function(e) {
let $this = $(e.target),
data = $this.data();
this.BottomSheets = $body.data('qor.bottomsheets');
this.bottomsheetsData = data;
this.$selector = data.selectId ? $(data.selectId) : $this.closest(CLASS_PARENT).find('select');
this.$selectFeild = this.$selector.closest(CLASS_PARENT).find(CLASS_SELECT_FIELD);
// select many templates
this.SELECT_MANY_SELECTED_ICON = $('[name="select-many-selected-icon"]').html();
this.SELECT_MANY_UNSELECTED_ICON = $('[name="select-many-unselected-icon"]').html();
this.SELECT_MANY_HINT = $('[name="select-many-hint"]').html();
this.SELECT_MANY_TEMPLATE = $('[name="select-many-template"]').html();
data.url = data.selectListingUrl;
if (data.selectDefaultCreating) {
data.url = data.selectCreatingUrl;
}
this.BottomSheets.open(data, this.handleSelectMany.bind(this));
},
reloadData: function() {
this.initItems();
},
renderSelectMany: function(data) {
return Mustache.render(this.SELECT_MANY_TEMPLATE, data);
},
renderHint: function(data) {
return Mustache.render(this.SELECT_MANY_HINT, data);
},
initItems: function() {
var $tr = this.$bottomsheets.find('tbody tr'),
selectedIconTmpl = this.SELECT_MANY_SELECTED_ICON,
unSelectedIconTmpl = this.SELECT_MANY_UNSELECTED_ICON,
selectedIDs = [],
primaryKey,
$selectedItems = this.$selectFeild.find('[data-primary-key]').not('.' + CLASS_DELETED_ITEM);
$selectedItems.each(function() {
selectedIDs.push($(this).data().primaryKey);
});
$tr.each(function() {
var $this = $(this),
$td = $this.find('td:first');
primaryKey = $this.data().primaryKey;
if (selectedIDs.indexOf(primaryKey) != '-1') {
$this.addClass(CLASS_SELECTED);
$td.append(selectedIconTmpl);
} else {
$td.append(unSelectedIconTmpl);
}
});
this.updateHint(this.getSelectedItemData());
},
getSelectedItemData: function() {
var selecedItems = this.$selectFeild.find('[data-primary-key]').not('.' + CLASS_DELETED_ITEM);
return {
selectedNum: selecedItems.length
};
},
updateHint: function(data) {
var template;
$.extend(data, this.bottomsheetsData);
template = this.renderHint(data);
this.$bottomsheets.find(CLASS_SELECT_HINT).remove();
this.$bottomsheets.find('.qor-page__body').before(template);
},
updateSelectInputData: function($selectFeild) {
var $selectList = $selectFeild ? $selectFeild : this.$selectFeild,
$selectedItems = $selectList.find('[data-primary-key]').not('.' + CLASS_DELETED_ITEM),
$selector = $selectFeild ? $selectFeild.find(CLASS_SELECT_INPUT) : this.$selector,
$options = $selector.find('option'),
$option,
data,
primaryKey;
$options.prop('selected', false);
$selectedItems.each(function() {
primaryKey = $(this).data().primaryKey;
$option = $options.filter('[value="' + primaryKey + '"]');
if (!$option.length) {
data = {
primaryKey: primaryKey,
displayName: ''
};
$option = $(Mustache.render(QorSelectMany.SELECT_MANY_OPTION_TEMPLATE, data));
$selector.append($option);
}
$option.prop('selected', true);
});
},
changeIcon: function($ele, template) {
$ele.find(CLASS_SELECT_ICON).remove();
$ele.find('td:first').prepend(template);
},
removeItem: function(data) {
var primaryKey = data.primaryKey;
this.$selectFeild
.find('[data-primary-key="' + primaryKey + '"]')
.find(CLASS_CLEAR_SELECT)
.click();
this.changeIcon(data.$clickElement, this.SELECT_MANY_UNSELECTED_ICON);
},
addItem: function(data, isNewData) {
var template = this.renderSelectMany(data),
$option,
$list = this.$selectFeild.find('[data-primary-key="' + data.primaryKey + '"]');
if ($list.length) {
if ($list.hasClass(CLASS_DELETED_ITEM)) {
$list.removeClass(CLASS_DELETED_ITEM);
this.updateSelectInputData();
this.changeIcon(data.$clickElement, this.SELECT_MANY_SELECTED_ICON);
return;
} else {
return;
}
}
this.$selectFeild.append(template);
if (isNewData) {
$option = $(Mustache.render(QorSelectMany.SELECT_MANY_OPTION_TEMPLATE, data));
$option.appendTo(this.$selector);
$option.prop('selected', true);
this.$bottomsheets.remove();
if (!$('.qor-bottomsheets').is(':visible')) {
$('body').removeClass('qor-bottomsheets-open');
}
return;
}
this.changeIcon(data.$clickElement, this.SELECT_MANY_SELECTED_ICON);
},
handleSelectMany: function($bottomsheets) {
let options = {
onSelect: this.onSelectResults.bind(this), // render selected item after click item lists
onSubmit: this.onSubmitResults.bind(this) // render new items after new item form submitted
};
$bottomsheets.qorSelectCore(options).addClass(CLASS_MANY);
$bottomsheets.on(EVENT_CLICK, CLASS_SELECT_ALL, this.handleSelectAll.bind(this));
this.$bottomsheets = $bottomsheets;
this.initItems();
},
handleSelectAll: function() {
let $trs = this.$bottomsheets.find('.qor-table tbody tr'),
$trsHasUnselected = $trs.not('.is_selected');
if ($trsHasUnselected.length) {
$trsHasUnselected.click();
} else {
$trs.click();
}
},
onSelectResults: function(data) {
this.handleResults(data);
},
onSubmitResults: function(data) {
this.handleResults(data, true);
},
handleResults: function(data, isNewData) {
data.displayName = data.Text || data.Name || data.Title || data.Code || data[Object.keys(data)[0]];
data.displayName = (data.displayName).escapeSymbol();
if (isNewData) {
this.addItem(data, true);
return;
}
var $element = data.$clickElement,
isSelected;
$element.toggleClass(CLASS_SELECTED);
isSelected = $element.hasClass(CLASS_SELECTED);
if (isSelected) {
this.addItem(data);
} else {
this.removeItem(data);
}
this.updateHint(this.getSelectedItemData());
this.updateSelectInputData();
},
destroy: function() {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorSelectMany.SELECT_MANY_OPTION_TEMPLATE = '<option value="[[ primaryKey ]]" >[[ displayName ]]</option>';
QorSelectMany.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorSelectMany(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = '[data-toggle="qor.selectmany"]';
$(document)
.on(EVENT_DISABLE, function(e) {
QorSelectMany.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorSelectMany.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorSelectMany;
});

View File

@@ -0,0 +1,214 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
let $body = $('body'),
$document = $(document),
Mustache = window.Mustache,
NAMESPACE = 'qor.selectone',
PARENT_NAMESPACE = 'qor.bottomsheets',
EVENT_CLICK = 'click.' + NAMESPACE,
EVENT_ENABLE = 'enable.' + NAMESPACE,
EVENT_DISABLE = 'disable.' + NAMESPACE,
EVENT_RELOAD = 'reload.' + PARENT_NAMESPACE,
CLASS_CLEAR_SELECT = '.qor-selected__remove',
CLASS_CHANGE_SELECT = '.qor-selected__change',
CLASS_SELECT_FIELD = '.qor-field__selected',
CLASS_SELECT_INPUT = '.qor-field__selectone-input',
CLASS_SELECT_TRIGGER = '.qor-field__selectone-trigger',
CLASS_PARENT = '.qor-field__selectone',
CLASS_SELECTED = 'is_selected',
CLASS_ONE = 'qor-bottomsheets__select-one';
function QorSelectOne(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorSelectOne.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorSelectOne.prototype = {
constructor: QorSelectOne,
init: function() {
this.bind();
},
bind: function() {
$document.on(EVENT_RELOAD, `.${CLASS_ONE}`, this.reloadData.bind(this));
this.$element
.on(EVENT_CLICK, CLASS_CLEAR_SELECT, this.clearSelect.bind(this))
.on(EVENT_CLICK, '[data-selectone-url]', this.openBottomSheets.bind(this))
.on(EVENT_CLICK, CLASS_CHANGE_SELECT, this.changeSelect);
},
unbind: function() {
$document.off(EVENT_CLICK, '[data-selectone-url]').off(EVENT_RELOAD, `.${CLASS_ONE}`);
this.$element.off(EVENT_CLICK, CLASS_CLEAR_SELECT).off(EVENT_CLICK, CLASS_CHANGE_SELECT);
},
clearSelect: function(e) {
var $target = $(e.target),
$parent = $target.closest(CLASS_PARENT);
$parent.find(CLASS_SELECT_FIELD).remove();
$parent.find(CLASS_SELECT_INPUT).html('');
$parent.find(CLASS_SELECT_INPUT)[0].value = '';
$parent.find(CLASS_SELECT_TRIGGER).show();
$parent.trigger('qor.selectone.unselected');
return false;
},
changeSelect: function() {
var $target = $(this),
$parent = $target.closest(CLASS_PARENT);
$parent.find(CLASS_SELECT_TRIGGER).trigger('click');
},
openBottomSheets: function(e) {
var $this = $(e.target),
data = $this.data();
this.BottomSheets = $body.data('qor.bottomsheets');
this.$parent = $this.closest(CLASS_PARENT);
data.url = data.selectoneUrl;
this.SELECT_ONE_SELECTED_ICON = $('[name="select-one-selected-icon"]').html();
this.BottomSheets.open(data, this.handleSelectOne.bind(this));
},
initItem: function() {
var $selectFeild = this.$parent.find(CLASS_SELECT_FIELD),
selectedID;
if (!$selectFeild.length) {
return;
}
selectedID = $selectFeild.data().primaryKey;
if (selectedID) {
this.$bottomsheets
.find('tr[data-primary-key="' + selectedID + '"]')
.addClass(CLASS_SELECTED)
.find('td:first')
.append(this.SELECT_ONE_SELECTED_ICON);
}
},
reloadData: function() {
this.initItem();
},
renderSelectOne: function(data) {
return Mustache.render($('[name="select-one-selected-template"]').html(), data);
},
handleSelectOne: function($bottomsheets) {
var options = {
onSelect: this.onSelectResults.bind(this), //render selected item after click item lists
onSubmit: this.onSubmitResults.bind(this) //render new items after new item form submitted
};
$bottomsheets.qorSelectCore(options).addClass(CLASS_ONE);
this.$bottomsheets = $bottomsheets;
this.initItem();
},
onSelectResults: function(data) {
this.handleResults(data);
},
onSubmitResults: function(data) {
this.handleResults(data, true);
},
handleResults: function(data) {
var template,
$parent = this.$parent,
$select = $parent.find('select'),
$selectFeild = $parent.find(CLASS_SELECT_FIELD);
data.displayName = data.Text || data.Name || data.Title || data.Code || data[Object.keys(data)[0]];
data.selectoneValue = data.primaryKey || data.ID;
data.displayName = (data.displayName).escapeSymbol();
if (!$select.length) {
return;
}
template = this.renderSelectOne(data);
if ($selectFeild.length) {
$selectFeild.remove();
}
$parent.prepend(template);
$parent.find(CLASS_SELECT_TRIGGER).hide();
$select.html(Mustache.render(QorSelectOne.SELECT_ONE_OPTION_TEMPLATE, data));
$select[0].value = data.primaryKey || data.ID;
$parent.trigger('qor.selectone.selected', [data]);
this.$bottomsheets.qorSelectCore('destroy').remove();
if (!$('.qor-bottomsheets').is(':visible')) {
$('body').removeClass('qor-bottomsheets-open');
}
},
destroy: function() {
this.unbind();
this.$element.removeData(NAMESPACE);
}
};
QorSelectOne.SELECT_ONE_OPTION_TEMPLATE = '<option value="[[ selectoneValue ]]" selected>[[ displayName ]]</option>';
QorSelectOne.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorSelectOne(this, options)));
}
if (typeof options === 'string' && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = '[data-toggle="qor.selectone"]';
$(document)
.on(EVENT_DISABLE, function(e) {
QorSelectOne.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorSelectOne.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorSelectOne;
});

View File

@@ -0,0 +1,274 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
var $document = $(document);
var NAMESPACE = 'qor.selector';
var EVENT_ENABLE = 'enable.' + NAMESPACE;
var EVENT_DISABLE = 'disable.' + NAMESPACE;
var EVENT_CLICK = 'click.' + NAMESPACE;
var EVENT_SELECTOR_CHANGE = 'selectorChanged.' + NAMESPACE;
var CLASS_OPEN = 'open';
var CLASS_ACTIVE = 'active';
var CLASS_HOVER = 'hover';
var CLASS_SELECTED = 'selected';
var CLASS_DISABLED = 'disabled';
var CLASS_CLEARABLE = 'clearable';
var SELECTOR_SELECTED = '.' + CLASS_SELECTED;
var SELECTOR_TOGGLE = '.qor-selector-toggle';
var SELECTOR_LABEL = '.qor-selector-label';
var SELECTOR_CLEAR = '.qor-selector-clear';
var SELECTOR_MENU = '.qor-selector-menu';
var CLASS_BOTTOMSHEETS = '.qor-bottomsheets';
function QorSelector(element, options) {
this.options = options;
this.$element = $(element);
this.init();
}
QorSelector.prototype = {
constructor: QorSelector,
init: function() {
var $this = this.$element;
this.placeholder = $this.attr('placeholder') || $this.attr('name') || 'Select';
this.build();
},
build: function() {
var $this = this.$element;
var $selector = $(QorSelector.TEMPLATE);
var alignedClass = this.options.aligned + '-aligned';
var data = {};
var eleData = $this.data();
var hover = eleData.hover;
var paramName = $this.attr('name');
this.isBottom = eleData.position == 'bottom';
hover && $selector.addClass(CLASS_HOVER);
$selector
.addClass(alignedClass)
.find(SELECTOR_MENU)
.html(function() {
var list = [];
$this.children().each(function() {
var $this = $(this);
var selected = $this.attr('selected');
var disabled = $this.attr('disabled');
var value = $this.attr('value');
var label = $this.text();
var classNames = [];
if (selected) {
classNames.push(CLASS_SELECTED);
data.value = value;
data.label = label;
data.paramName = paramName;
}
if (disabled) {
classNames.push(CLASS_DISABLED);
}
list.push(
'<li' +
(classNames.length ? ' class="' + classNames.join(' ') + '"' : '') +
' data-value="' +
value +
'"' +
' data-label="' +
label +
'"' +
' data-param-name="' +
paramName +
'"' +
'>' +
label +
'</li>'
);
});
return list.join('');
});
this.$selector = $selector;
$this.hide().after($selector);
$selector.find(SELECTOR_TOGGLE).data('paramName', paramName);
this.pick(data, true);
this.bind();
},
unbuild: function() {
this.unbind();
this.$selector.remove();
this.$element.show();
},
bind: function() {
this.$selector.on(EVENT_CLICK, $.proxy(this.click, this));
$document.on(EVENT_CLICK, $.proxy(this.close, this));
},
unbind: function() {
this.$selector.off(EVENT_CLICK, this.click);
},
click: function(e) {
var $target = $(e.target);
e.stopPropagation();
if ($target.is(SELECTOR_CLEAR)) {
this.clear();
} else if ($target.is('li')) {
if (!$target.hasClass(CLASS_SELECTED) && !$target.hasClass(CLASS_DISABLED)) {
this.pick($target.data());
}
this.close();
} else if ($target.closest(SELECTOR_TOGGLE).length) {
this.open();
}
},
pick: function(data, initialized) {
var $selector = this.$selector;
var selected = !!data.value;
var $element = this.$element;
$selector
.find(SELECTOR_TOGGLE)
.toggleClass(CLASS_ACTIVE, selected)
.toggleClass(CLASS_CLEARABLE, selected && this.options.clearable)
.find(SELECTOR_LABEL)
.text(data.label || this.placeholder);
if (!initialized) {
$selector
.find(SELECTOR_MENU)
.children('[data-value="' + data.value + '"]')
.addClass(CLASS_SELECTED)
.siblings(SELECTOR_SELECTED)
.removeClass(CLASS_SELECTED);
$element.val(data.value);
if ($element.closest(CLASS_BOTTOMSHEETS).length && !$element.closest('[data-toggle="qor.filter"]').length) {
// If action is in bottom sheet, will trigger filterChanged.qor.selector event, add passed data.value parameter to event.
$(CLASS_BOTTOMSHEETS).trigger(EVENT_SELECTOR_CHANGE, [data.value, data.paramName]);
} else {
$element.trigger('change');
}
}
},
clear: function() {
var $element = this.$element;
this.$selector
.find(SELECTOR_TOGGLE)
.removeClass(CLASS_ACTIVE)
.removeClass(CLASS_CLEARABLE)
.find(SELECTOR_LABEL)
.text(this.placeholder)
.end()
.end()
.find(SELECTOR_MENU)
.children(SELECTOR_SELECTED)
.removeClass(CLASS_SELECTED);
$element.val('').trigger('change');
},
open: function() {
// Close other opened dropdowns first
$document.triggerHandler(EVENT_CLICK);
$('.qor-filter__dropdown').hide();
// Open the current dropdown
this.$selector.addClass(CLASS_OPEN);
if (this.isBottom) {
this.$selector.addClass('bottom');
}
},
close: function() {
this.$selector.removeClass(CLASS_OPEN);
if (this.isBottom) {
this.$selector.removeClass('bottom');
}
},
destroy: function() {
this.unbuild();
this.$element.removeData(NAMESPACE);
}
};
QorSelector.DEFAULTS = {
aligned: 'left',
clearable: false
};
QorSelector.TEMPLATE =
'<div class="qor-selector">' +
'<a class="qor-selector-toggle">' +
'<span class="qor-selector-label"></span>' +
'<i class="material-icons qor-selector-arrow">arrow_drop_down</i>' +
'<i class="material-icons qor-selector-clear">clear</i>' +
'</a>' +
'<ul class="qor-selector-menu"></ul>' +
'</div>';
QorSelector.plugin = function(option) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var options;
var fn;
if (!data) {
if (/destroy/.test(option)) {
return;
}
options = $.extend({}, QorSelector.DEFAULTS, $this.data(), typeof option === 'object' && option);
$this.data(NAMESPACE, (data = new QorSelector(this, options)));
}
if (typeof option === 'string' && $.isFunction((fn = data[option]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = '[data-toggle="qor.selector"]';
$(document)
.on(EVENT_DISABLE, function(e) {
QorSelector.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorSelector.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorSelector;
});

View File

@@ -0,0 +1,689 @@
(function(factory) {
if (typeof define === "function" && define.amd) {
// AMD. Register as anonymous module.
define(["jquery"], factory);
} else if (typeof exports === "object") {
// Node / CommonJS
factory(require("jquery"));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
"use strict";
let $document = $(document),
FormData = window.FormData,
QOR_Translations = window.QOR_Translations,
_ = window._,
QOR = window.QOR,
NAMESPACE = "qor.slideout",
EVENT_KEYUP = "keyup." + NAMESPACE,
EVENT_CLICK = "click." + NAMESPACE,
EVENT_SUBMIT = "submit." + NAMESPACE,
EVENT_SHOW = "show." + NAMESPACE,
EVENT_SLIDEOUT_SUBMIT_COMPLEMENT = "slideoutSubmitComplete." + NAMESPACE,
EVENT_SLIDEOUT_CLOSED = "slideoutClosed." + NAMESPACE,
EVENT_SLIDEOUT_LOADED = "slideoutLoaded." + NAMESPACE,
EVENT_SLIDEOUT_BEFORESEND = "slideoutBeforeSend." + NAMESPACE,
EVENT_SHOWN = "shown." + NAMESPACE,
EVENT_HIDE = "hide." + NAMESPACE,
EVENT_HIDDEN = "hidden." + NAMESPACE,
EVENT_TRANSITIONEND = "transitionend",
CLASS_OPEN = "qor-slideout-open",
CLASS_MINI = "qor-slideout-mini",
CLASS_IS_SHOWN = "is-shown",
CLASS_IS_SLIDED = "is-slided",
CLASS_IS_SELECTED = "is-selected",
CLASS_MAIN_CONTENT = ".mdl-layout__content.qor-page",
CLASS_HEADER_LOCALE = ".qor-actions__locale",
CLASS_BODY_LOADING = ".qor-body__loading";
function replaceHtml(el, html) {
let oldEl = typeof el === "string" ? document.getElementById(el) : el,
newEl = oldEl.cloneNode(false);
newEl.innerHTML = html;
oldEl.parentNode.replaceChild(newEl, oldEl);
return newEl;
}
function pushArrary($ele, isScript) {
let array = [],
prop = "href";
isScript && (prop = "src");
$ele.each(function() {
array.push($(this).attr(prop));
});
return _.uniq(array);
}
function execSlideoutEvents(url, response) {
// exec qorSliderAfterShow after script loaded
var qorSliderAfterShow = $.fn.qorSliderAfterShow;
for (var name in qorSliderAfterShow) {
if (
qorSliderAfterShow.hasOwnProperty(name) &&
!qorSliderAfterShow[name]["isLoaded"]
) {
qorSliderAfterShow[name]["isLoaded"] = true;
qorSliderAfterShow[name].call(this, url, response);
}
}
}
function loadScripts(srcs, data, callback) {
let scriptsLoaded = 0;
for (let i = 0, len = srcs.length; i < len; i++) {
let script = document.createElement("script");
script.onload = function() {
scriptsLoaded++;
if (scriptsLoaded === srcs.length) {
if ($.isFunction(callback)) {
callback();
}
}
if (data && data.url && data.response) {
execSlideoutEvents(data.url, data.response);
}
};
script.src = srcs[i];
document.body.appendChild(script);
}
}
function loadStyles(srcs) {
let ss = document.createElement("link"),
src = srcs.shift();
ss.type = "text/css";
ss.rel = "stylesheet";
ss.onload = function() {
if (srcs.length) {
loadStyles(srcs);
}
};
ss.href = src;
document.getElementsByTagName("head")[0].appendChild(ss);
}
function compareScripts($scripts) {
let $currentPageScripts = $("script"),
slideoutScripts = pushArrary($scripts, true),
currentPageScripts = pushArrary($currentPageScripts, true),
scriptDiff = _.difference(slideoutScripts, currentPageScripts);
return scriptDiff;
}
function compareLinks($links) {
let $currentStyles = $("link"),
slideoutStyles = pushArrary($links),
currentStyles = pushArrary($currentStyles),
styleDiff = _.difference(slideoutStyles, currentStyles);
return styleDiff;
}
function QorSlideout(element, options) {
this.$element = $(element);
this.options = $.extend(
{},
QorSlideout.DEFAULTS,
$.isPlainObject(options) && options
);
this.slided = false;
this.disabled = false;
this.slideoutType = false;
this.init();
}
QorSlideout.prototype = {
constructor: QorSlideout,
init: function() {
this.build();
this.bind();
},
build: function() {
var $slideout;
this.$slideout = $slideout = $(QorSlideout.TEMPLATE).appendTo("body");
this.$slideoutTemplate = $slideout.html();
},
unbuild: function() {
this.$slideout.remove();
},
bind: function() {
this.$slideout
.on(EVENT_SUBMIT, "form", this.submit.bind(this))
.on(
EVENT_CLICK,
".qor-slideout__fullscreen",
this.toggleSlideoutMode.bind(this)
)
.on(EVENT_CLICK, '[data-dismiss="slideout"]', this.hide.bind(this));
$document.on(EVENT_KEYUP, $.proxy(this.keyup, this));
},
unbind: function() {
this.$slideout.off(EVENT_SUBMIT, this.submit).off(EVENT_CLICK);
$document.off(EVENT_KEYUP, this.keyup);
},
keyup: function(e) {
if (e.which === 27) {
if (
$(".qor-bottomsheets").is(":visible") ||
$(".qor-modal").is(":visible") ||
$("#redactor-modal-box").length ||
$("#dialog").is(":visible")
) {
return;
}
this.hide();
this.removeSelectedClass();
}
},
loadExtraResource: function(data) {
let styleDiff = compareLinks(data.$links),
scriptDiff = compareScripts(data.$scripts);
if (styleDiff.length) {
loadStyles(styleDiff);
}
if (scriptDiff.length) {
loadScripts(scriptDiff, data);
}
},
removeSelectedClass: function() {
this.$element.find("[data-url]").removeClass(CLASS_IS_SELECTED);
},
addLoading: function() {
$(CLASS_BODY_LOADING).remove();
var $loading = $(QorSlideout.TEMPLATE_LOADING);
$loading.appendTo($("body")).trigger("enable.qor.material");
},
toggleSlideoutMode: function() {
this.$slideout
.toggleClass("qor-slideout__fullscreen")
.find(".qor-slideout__fullscreen i")
.toggle();
},
checkRichedutorHTMLTags: function(source){
var DOMHolderArray = new Array();
var tagsArray = new Array();
var lines = source.value.split('\n');
for (var x = 0; x < lines.length; x++) {
tagsArray = lines[x].match(/<(\/{1})?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)>/g);
if (tagsArray) {
for (var i = 0; i < tagsArray.length; i++) {
if (tagsArray[i].indexOf('</') >= 0) {
let elementToPop = tagsArray[i].substr(2, tagsArray[i].length - 3);
elementToPop = elementToPop.replace(/ /g, '');
for (var j = DOMHolderArray.length - 1; j >= 0; j--) {
if (DOMHolderArray[j].element == elementToPop) {
DOMHolderArray.splice(j, 1);
if (elementToPop != 'html') {
break;
}
}
}
} else {
var tag = new Object();
tag.full = tagsArray[i];
tag.line = x + 1;
if (tag.full.indexOf(' ') > 0) {
tag.element = tag.full.substr(1, tag.full.indexOf(' ') - 1);
} else {
tag.element = tag.full.substr(1, tag.full.length - 2);
}
var selfClosingTags = new Array('area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr');
var isSelfClosing = false;
for (var y = 0; y < selfClosingTags.length; y++) {
if (selfClosingTags[y].localeCompare(tag.element) == 0) {
isSelfClosing = true;
}
}
if (isSelfClosing == false) {
DOMHolderArray.push(tag);
}
}
}
}
}
return DOMHolderArray.length;
},
submit: function(e) {
let $slideout = this.$slideout,
form = e.target,
$form = $(form),
_this = this,
$loading = $(QOR.$formLoading),
$submit = $form.find(":submit"),
hasNotClosedTags = false;
if ($form.data("normal-submit")) {
return;
}
$slideout.trigger(EVENT_SLIDEOUT_BEFORESEND);
if (!FormData) {
return;
}
e.preventDefault();
document.querySelectorAll('.qor-redactor-box .redactor-source').forEach(function(item) {
if(_this.checkRichedutorHTMLTags(item)){
hasNotClosedTags=true;
}
});
if(hasNotClosedTags){
QOR.qorConfirm(QOR_Translations.slideoutCheckHTMLTagsError);
return false;
}
this.submitXHR = $.ajax($form.prop("action"), {
method: $form.prop("method"),
data: new FormData(form),
dataType: "html",
processData: false,
contentType: false,
beforeSend: function() {
$(".qor-submit-loading").remove();
$loading
.appendTo(
$submit.prop("disabled", true).closest(".qor-form__actions")
)
.trigger("enable.qor.material");
$.fn.qorSlideoutBeforeHide = null;
},
success: function() {
let returnUrl = $form.data("returnUrl"),
refreshUrl = $form.data("refreshUrl");
$slideout.trigger(EVENT_SLIDEOUT_SUBMIT_COMPLEMENT);
if (refreshUrl) {
window.location.href = refreshUrl;
return;
}
if (returnUrl == "refresh") {
_this.refresh();
return;
}
if (returnUrl && returnUrl != "refresh") {
_this.load(returnUrl);
} else {
_this.refresh();
}
},
error: function(err) {
QOR.handleAjaxError(err);
},
complete: function() {
$submit.prop("disabled", false);
}
});
},
load: function(url, data) {
var options = this.options;
var method;
var dataType;
var load;
var $slideout = this.$slideout;
var $title;
if (!url) {
return;
}
data = $.isPlainObject(data) ? data : {};
method = data.method ? data.method : "GET";
dataType = data.datatype ? data.datatype : "html";
load = $.proxy(function() {
$.ajax(url, {
method: method,
dataType: dataType,
cache: true,
ifModified: true,
success: $.proxy(function(response) {
let $response,
$content,
$qorFormContainer,
$scripts,
$links,
bodyClass;
$(CLASS_BODY_LOADING).remove();
if (method === "GET") {
$response = $(response);
$content = $response.find(CLASS_MAIN_CONTENT);
$qorFormContainer = $content.find(".qor-form-container");
this.slideoutType =
$qorFormContainer.length &&
$qorFormContainer.data().slideoutType;
if (!$content.length) {
return;
}
let bodyHtml = response.match(
/<\s*body.*>[\s\S]*<\s*\/body\s*>/gi
);
if (bodyHtml) {
bodyHtml = bodyHtml
.join("")
.replace(/<\s*body/gi, "<div")
.replace(/<\s*\/body/gi, "</div");
bodyClass = $(bodyHtml).prop("class");
$("body").addClass(bodyClass);
let data = {
$scripts: $response.filter("script"),
$links: $response.filter("link"),
url: url,
response: response
};
this.loadExtraResource(data);
}
$content
.find(".qor-button--cancel")
.attr("data-dismiss", "slideout")
.removeAttr("href");
$scripts = compareScripts($content.find("script[src]"));
$links = compareLinks($content.find("link[href]"));
if ($scripts.length) {
let data = {
url: url,
response: response
};
loadScripts($scripts, data, function() {});
}
if ($links.length) {
loadStyles($links);
}
$content.find("script[src],link[href]").remove();
// reset slideout header and body
$slideout.html(this.$slideoutTemplate);
$title = $slideout.find(".qor-slideout__title");
this.$body = $slideout.find(".qor-slideout__body");
$title.html($response.find(options.title).html());
replaceHtml(
$slideout.find(".qor-slideout__body")[0],
$content.html()
);
this.$body.find(CLASS_HEADER_LOCALE).remove();
$slideout
.one(EVENT_SHOWN, function() {
$(this).trigger("enable");
})
.one(EVENT_HIDDEN, function() {
$(this).trigger("disable");
});
$slideout.find(".qor-slideout__opennew").attr("href", url);
this.show();
// callback for after slider loaded HTML
// this callback is deprecated, use slideoutLoaded.qor.slideout event.
var qorSliderAfterShow = $.fn.qorSliderAfterShow;
if (qorSliderAfterShow) {
for (var name in qorSliderAfterShow) {
if (
qorSliderAfterShow.hasOwnProperty(name) &&
$.isFunction(qorSliderAfterShow[name])
) {
qorSliderAfterShow[name]["isLoaded"] = true;
qorSliderAfterShow[name].call(this, url, response);
}
}
}
// will trigger slideoutLoaded.qor.slideout event after slideout loaded
$slideout.trigger(EVENT_SLIDEOUT_LOADED, [url, response]);
} else {
if (data.returnUrl) {
this.load(data.returnUrl);
} else {
this.refresh();
}
}
}, this),
error: $.proxy(function() {
var errors;
$(CLASS_BODY_LOADING).remove();
if ($(".qor-error span").length > 0) {
errors = $(".qor-error span")
.map(function() {
return $(this).text();
})
.get()
.join(", ");
} else {
errors = QOR_Translations.serverError;
}
window.alert(errors);
}, this)
});
}, this);
if (this.slided) {
this.hide(true);
this.$slideout.one(EVENT_HIDDEN, load);
} else {
load();
}
},
open: function(options) {
this.addLoading();
this.load(options.url, options.data);
},
reload: function(url) {
this.hide();
this.load(url);
},
show: function() {
var $slideout = this.$slideout;
var showEvent;
if (this.slided) {
return;
}
showEvent = $.Event(EVENT_SHOW);
$slideout.trigger(showEvent);
if (showEvent.isDefaultPrevented()) {
return;
}
$slideout.removeClass(CLASS_MINI);
this.slideoutType == "mini" && $slideout.addClass(CLASS_MINI);
$slideout.addClass(CLASS_IS_SHOWN).get(0).offsetWidth;
$slideout
.one(EVENT_TRANSITIONEND, $.proxy(this.shown, this))
.addClass(CLASS_IS_SLIDED)
.scrollTop(0);
},
shown: function() {
this.slided = true;
// Disable to scroll body element
$("body").addClass(CLASS_OPEN);
this.$slideout
.trigger("beforeEnable.qor.slideout")
.trigger(EVENT_SHOWN)
.trigger("afterEnable.qor.slideout");
},
hide: function() {
let message = {
confirm: QOR_Translations.slideoutCloseWarning
};
if ($.fn.qorSlideoutBeforeHide) {
QOR.qorConfirm(
message,
function(confirm) {
if (confirm) {
this.hideSlideout();
}
}.bind(this)
);
} else {
this.hideSlideout();
}
this.removeSelectedClass();
},
hideSlideout: function() {
var $slideout = this.$slideout;
var hideEvent;
var $datePicker = $(".qor-datepicker").not(".hidden");
// remove onbeforeunload event
window.onbeforeunload = null;
$.fn.qorSlideoutBeforeHide = null;
this.submitXHR && this.submitXHR.abort();
if ($datePicker.length) {
$datePicker.addClass("hidden");
}
if (!this.slided) {
return;
}
hideEvent = $.Event(EVENT_HIDE);
$slideout.trigger(hideEvent);
if (hideEvent.isDefaultPrevented()) {
return;
}
$slideout
.one(EVENT_TRANSITIONEND, $.proxy(this.hidden, this))
.removeClass(`${CLASS_IS_SLIDED} qor-slideout__fullscreen`);
$slideout.trigger(EVENT_SLIDEOUT_CLOSED);
},
hidden: function() {
this.slided = false;
// Enable to scroll body element
$("body").removeClass(CLASS_OPEN);
this.$slideout.removeClass(CLASS_IS_SHOWN).trigger(EVENT_HIDDEN);
},
refresh: function() {
this.hide();
setTimeout(function() {
window.location.reload();
}, 350);
},
destroy: function() {
this.unbind();
this.unbuild();
this.$element.removeData(NAMESPACE);
}
};
QorSlideout.DEFAULTS = {
title: ".qor-form-title, .mdl-layout-title",
content: false
};
QorSlideout.TEMPLATE = `<div class="qor-slideout">
<div class="qor-slideout__header">
<div class="qor-slideout__header-link">
<a href="#" target="_blank" class="mdl-button mdl-button--icon mdl-js-button mdl-js-repple-effect qor-slideout__opennew"><i class="material-icons">open_in_new</i></a>
<a href="#" class="mdl-button mdl-button--icon mdl-js-button mdl-js-repple-effect qor-slideout__fullscreen">
<i class="material-icons">fullscreen</i>
<i class="material-icons" style="display: none;">fullscreen_exit</i>
</a>
</div>
<button type="button" class="mdl-button mdl-button--icon mdl-js-button mdl-js-repple-effect qor-slideout__close" data-dismiss="slideout">
<span class="material-icons">close</span>
</button>
<h3 class="qor-slideout__title"></h3>
</div>
<div class="qor-slideout__body"></div>
</div>`;
QorSlideout.TEMPLATE_LOADING = `<div class="qor-body__loading">
<div><div class="mdl-spinner mdl-js-spinner is-active qor-layout__bottomsheet-spinner"></div></div>
</div>`;
QorSlideout.plugin = function(options) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorSlideout(this, options)));
}
if (typeof options === "string" && $.isFunction((fn = data[options]))) {
fn.apply(data);
}
});
};
$.fn.qorSlideout = QorSlideout.plugin;
return QorSlideout;
});

View File

@@ -0,0 +1,110 @@
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function ($) {
'use strict';
var location = window.location;
var NAMESPACE = 'qor.sorter';
var EVENT_ENABLE = 'enable.' + NAMESPACE;
var EVENT_DISABLE = 'disable.' + NAMESPACE;
var EVENT_CLICK = 'click.' + NAMESPACE;
var CLASS_IS_SORTABLE = 'is-sortable';
function QorSorter(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorSorter.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorSorter.prototype = {
constructor: QorSorter,
init: function () {
this.$element.addClass(CLASS_IS_SORTABLE);
this.bind();
},
bind: function () {
this.$element.on(EVENT_CLICK, '> thead > tr > th', $.proxy(this.sort, this));
},
unbind: function () {
this.$element.off(EVENT_CLICK, this.sort);
},
sort: function (e) {
var $target = $(e.currentTarget);
var orderBy = $target.data('orderBy');
var search = location.search;
var param = 'order_by=' + orderBy;
// Stop when it is not sortable
if (!orderBy) {
return;
}
if (/order_by/.test(search)) {
search = search.replace(/order_by(=\w+)?/, function () {
return param;
});
} else {
search += search.indexOf('?') > -1 ? ('&' + param) : param;
}
location.search = search;
},
destroy: function () {
this.unbind();
this.$element.removeClass(CLASS_IS_SORTABLE).removeData(NAMESPACE);
}
};
QorSorter.DEFAULTS = {};
QorSorter.plugin = function (options) {
return this.each(function () {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorSorter(this, options)));
}
if (typeof options === 'string' && $.isFunction(fn = data[options])) {
fn.apply(data);
}
});
};
$(function () {
var selector = '.qor-js-table';
$(document)
.on(EVENT_DISABLE, function (e) {
QorSorter.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function (e) {
QorSorter.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorSorter;
});

View File

@@ -0,0 +1,210 @@
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function ($) {
'use strict';
var _ = window._;
var $body = $('body');
var NAMESPACE = 'qor.tabbar';
var EVENT_ENABLE = 'enable.' + NAMESPACE;
var EVENT_DISABLE = 'disable.' + NAMESPACE;
var EVENT_CLICK = 'click.' + NAMESPACE;
var CLASS_TAB = '.qor-layout__tab-button';
var CLASS_TAB_CONTENT = '.qor-layout__tab-content';
var CLASS_TAB_BAR = '.mdl-layout__tab-bar-container';
var CLASS_TAB_BAR_RIGHT = '.qor-layout__tab-right';
var CLASS_TAB_BAR_LEFT = '.qor-layout__tab-left';
var CLASS_ACTIVE = 'is-active';
function QorTab(element, options) {
this.$element = $(element);
this.options = $.extend({}, QorTab.DEFAULTS, $.isPlainObject(options) && options);
this.init();
}
QorTab.prototype = {
constructor: QorTab,
init: function () {
this.initTab();
this.bind();
},
bind: function () {
this.$element.on(EVENT_CLICK, CLASS_TAB, this.switchTab.bind(this));
this.$element.on(EVENT_CLICK, CLASS_TAB_BAR_RIGHT, this.scrollTabRight.bind(this));
this.$element.on(EVENT_CLICK, CLASS_TAB_BAR_LEFT, this.scrollTabLeft.bind(this));
},
unbind: function () {
this.$element.off(EVENT_CLICK, CLASS_TAB, this.switchTab);
this.$element.off(EVENT_CLICK, CLASS_TAB_BAR_RIGHT, this.scrollTabRight);
this.$element.off(EVENT_CLICK, CLASS_TAB_BAR_LEFT, this.scrollTabLeft);
},
initTab: function () {
var data = this.$element.data();
if (!data.scopeActive) {
$(CLASS_TAB).first().addClass(CLASS_ACTIVE);
$body.data('tabScopeActive',$(CLASS_TAB).first().data('name'));
} else {
$body.data('tabScopeActive',data.scopeActive);
}
this.tabWidth = 0;
this.slideoutWidth = $(CLASS_TAB_CONTENT).outerWidth();
_.each($(CLASS_TAB), function(ele) {
this.tabWidth = this.tabWidth + $(ele).outerWidth();
}.bind(this));
if (this.tabWidth > this.slideoutWidth) {
this.$element.find(CLASS_TAB_BAR).append(QorTab.ARROW_RIGHT);
}
},
scrollTabLeft: function (e) {
e.stopPropagation();
var $scrollBar = $(CLASS_TAB_BAR),
scrollLeft = $scrollBar.scrollLeft(),
jumpDistance = scrollLeft - this.slideoutWidth;
if (scrollLeft > 0){
$scrollBar.animate({scrollLeft:jumpDistance}, 400, function () {
$(CLASS_TAB_BAR_RIGHT).show();
if ($scrollBar.scrollLeft() == 0) {
$(CLASS_TAB_BAR_LEFT).hide();
}
});
}
},
scrollTabRight: function (e) {
e.stopPropagation();
var $scrollBar = $(CLASS_TAB_BAR),
scrollLeft = $scrollBar.scrollLeft(),
tabWidth = this.tabWidth,
slideoutWidth = this.slideoutWidth,
jumpDistance = scrollLeft + slideoutWidth;
if (jumpDistance < tabWidth){
$scrollBar.animate({scrollLeft:jumpDistance}, 400, function () {
$(CLASS_TAB_BAR_LEFT).show();
if ($scrollBar.scrollLeft() + slideoutWidth >= tabWidth) {
$(CLASS_TAB_BAR_RIGHT).hide();
}
});
!$(CLASS_TAB_BAR_LEFT).length && this.$element.find(CLASS_TAB_BAR).prepend(QorTab.ARROW_LEFT);
}
},
switchTab: function (e) {
var $target = $(e.target),
$element = this.$element,
data = $target.data(),
tabScopeActive = $body.data().tabScopeActive,
isInSlideout = $('.qor-slideout').is(':visible');
if (!isInSlideout) {
return;
}
if ($target.hasClass(CLASS_ACTIVE)){
return false;
}
$element.find(CLASS_TAB).removeClass(CLASS_ACTIVE);
$target.addClass(CLASS_ACTIVE);
$.ajax(data.tabUrl, {
method: 'GET',
dataType: 'html',
processData: false,
contentType: false,
beforeSend: function () {
$('.qor-layout__tab-spinner').remove();
var $spinner = '<div class="mdl-spinner mdl-js-spinner is-active qor-layout__tab-spinner"></div>';
$(CLASS_TAB_CONTENT).hide().before($spinner);
window.componentHandler.upgradeElement($('.qor-layout__tab-spinner')[0]);
},
success: function (html) {
$('.qor-layout__tab-spinner').remove();
$body.data('tabScopeActive',$target.data('name'));
var $content = $(html).find(CLASS_TAB_CONTENT).html();
$(CLASS_TAB_CONTENT).show().html($content).trigger('enable');
},
error: function () {
$('.qor-layout__tab-spinner').remove();
$body.data('tabScopeActive',tabScopeActive);
}
});
return false;
},
destroy: function () {
this.unbind();
$body.removeData('tabScopeActive');
}
};
QorTab.ARROW_RIGHT = '<a href="javascript://" class="qor-layout__tab-right"></a>';
QorTab.ARROW_LEFT = '<a href="javascript://" class="qor-layout__tab-left"></a>';
QorTab.DEFAULTS = {};
QorTab.plugin = function (options) {
return this.each(function () {
var $this = $(this);
var data = $this.data(NAMESPACE);
var fn;
if (!data) {
if (/destroy/.test(options)) {
return;
}
$this.data(NAMESPACE, (data = new QorTab(this, options)));
}
if (typeof options === 'string' && $.isFunction(fn = data[options])) {
fn.apply(data);
}
});
};
$(function () {
var selector = '[data-toggle="qor.tab"]';
$(document)
.on(EVENT_DISABLE, function (e) {
QorTab.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function (e) {
QorTab.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorTab;
});

View File

@@ -0,0 +1,262 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node / CommonJS
factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
})(function($) {
'use strict';
var NAMESPACE = 'qor.timepicker';
var EVENT_ENABLE = 'enable.' + NAMESPACE;
var EVENT_DISABLE = 'disable.' + NAMESPACE;
var EVENT_CLICK = 'click.' + NAMESPACE;
var EVENT_FOCUS = 'focus.' + NAMESPACE;
var EVENT_KEYDOWN = 'keydown.' + NAMESPACE;
var EVENT_BLUR = 'blur.' + NAMESPACE;
var EVENT_CHANGE_TIME = 'selectTime.' + NAMESPACE;
var CLASS_PARENT = '[data-picker-type]';
var CLASS_TIME_SELECTED = '.ui-timepicker-selected';
function QorTimepicker(element, options) {
this.$element = $(element);
this.options = $.extend(true, {}, QorTimepicker.DEFAULTS, $.isPlainObject(options) && options);
this.formatDate = null;
this.pickerData = this.$element.data();
this.parent = this.$element.closest(CLASS_PARENT);
this.isDateTimePicker = this.parent.data('picker-type') == 'datetime';
this.$targetInput = this.parent.find(this.pickerData.targetInput || (this.isDateTimePicker ? '.qor-datetimepicker__input' : '.qor-datepicker__input'));
this.init();
}
QorTimepicker.prototype = {
init: function() {
if (this.$targetInput.is(':disabled')) {
this.$element.remove();
return;
}
this.bind();
this.oldValue = this.$targetInput.val();
var dateNow = new Date();
var month = dateNow.getMonth() + 1;
var date = dateNow.getDate();
month = month < 8 ? '0' + month : month;
date = date < 10 ? '0' + date : date;
this.dateValueNow = dateNow.getFullYear() + '-' + month + '-' + date;
},
bind: function() {
var pickerOptions = {
timeFormat: 'H:i',
showOn: null,
wrapHours: false,
scrollDefault: 'now'
};
if (this.isDateTimePicker) {
this.$targetInput
.qorTimepicker(pickerOptions)
.on(EVENT_CHANGE_TIME, $.proxy(this.changeTime, this))
.on(EVENT_BLUR, $.proxy(this.blur, this))
.on(EVENT_FOCUS, $.proxy(this.focus, this))
.on(EVENT_KEYDOWN, $.proxy(this.keydown, this));
}
this.$element.on(EVENT_CLICK, $.proxy(this.show, this));
},
unbind: function() {
this.$element.off(EVENT_CLICK, this.show);
if (this.isDateTimePicker) {
this.$targetInput
.off(EVENT_CHANGE_TIME, this.changeTime)
.off(EVENT_BLUR, this.blur)
.off(EVENT_FOCUS, this.focus)
.off(EVENT_KEYDOWN, this.keydown);
}
},
focus: function() {},
blur: function() {
var inputValue = this.$targetInput.val();
var inputArr = inputValue.split(' ');
var inputArrLen = inputArr.length;
var tempValue;
var newDateValue;
var newTimeValue;
var isDate;
var isTime;
var splitSym;
var timeReg = /\d{1,2}:\d{1,2}/;
var dateReg = /^\d{4}-\d{1,2}-\d{1,2}/;
if (!inputValue) {
return;
}
if (inputArrLen == 1) {
if (dateReg.test(inputArr[0])) {
newDateValue = inputArr[0];
newTimeValue = '00:00';
}
if (timeReg.test(inputArr[0])) {
newDateValue = this.dateValueNow;
newTimeValue = inputArr[0];
}
} else {
for (var i = 0; i < inputArrLen; i++) {
// check for date && time
isDate = dateReg.test(inputArr[i]);
isTime = timeReg.test(inputArr[i]);
if (isDate) {
newDateValue = inputArr[i];
splitSym = '-';
}
if (isTime) {
newTimeValue = inputArr[i];
splitSym = ':';
}
tempValue = inputArr[i].split(splitSym);
for (var j = 0; j < tempValue.length; j++) {
if (tempValue[j].length < 2) {
tempValue[j] = '0' + tempValue[j];
}
}
if (isDate) {
newDateValue = tempValue.join(splitSym);
}
if (isTime) {
newTimeValue = tempValue.join(splitSym);
}
}
}
if (this.checkDate(newDateValue) && this.checkTime(newTimeValue)) {
this.$targetInput.val(newDateValue + ' ' + newTimeValue);
this.oldValue = this.$targetInput.val();
} else {
this.$targetInput.val(this.oldValue);
}
},
keydown: function(e) {
var keycode = e.keyCode;
var keys = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 8, 37, 38, 39, 40, 27, 32, 20, 189, 16, 186, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105];
if (keys.indexOf(keycode) == -1) {
e.preventDefault();
}
},
checkDate: function(value) {
var regCheckDate = /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{1,2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/;
return regCheckDate.test(value);
},
checkTime: function(value) {
var regCheckTime = /^([01]\d|2[0-3]):?([0-5]\d)$/;
return regCheckTime.test(value);
},
changeTime: function() {
var $targetInput = this.$targetInput;
var oldValue = this.oldValue;
var timeReg = /\d{1,2}:\d{1,2}/;
var hasTime = timeReg.test(oldValue);
var selectedTime = $targetInput
.data()
.timepickerObj.list.find(CLASS_TIME_SELECTED)
.html();
var newValue;
if (!oldValue) {
newValue = this.dateValueNow + ' ' + selectedTime;
} else if (hasTime) {
newValue = oldValue.replace(timeReg, selectedTime);
} else {
newValue = oldValue + ' ' + selectedTime;
}
$targetInput.val(newValue);
$targetInput.trigger('change');
},
show: function() {
if (!this.isDateTimePicker) {
return;
}
this.$targetInput.qorTimepicker('show');
this.oldValue = this.$targetInput.val();
},
destroy: function() {
this.unbind();
this.$targetInput.qorTimepicker('remove');
this.$element.removeData(NAMESPACE);
}
};
QorTimepicker.DEFAULTS = {};
QorTimepicker.plugin = function(option) {
return this.each(function() {
var $this = $(this);
var data = $this.data(NAMESPACE);
var options;
var fn;
if (!data) {
if (!$.fn.qorDatepicker) {
return;
}
if (/destroy/.test(option)) {
return;
}
options = $.extend(true, {}, $this.data(), typeof option === 'object' && option);
$this.data(NAMESPACE, (data = new QorTimepicker(this, options)));
}
if (typeof option === 'string' && $.isFunction((fn = data[option]))) {
fn.apply(data);
}
});
};
$(function() {
var selector = '[data-toggle="qor.timepicker"]';
$(document)
.on(EVENT_DISABLE, function(e) {
QorTimepicker.plugin.call($(selector, e.target), 'destroy');
})
.on(EVENT_ENABLE, function(e) {
QorTimepicker.plugin.call($(selector, e.target));
})
.triggerHandler(EVENT_ENABLE);
});
return QorTimepicker;
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
/*
Redactor Plugins
This plugin allows users to look through and edit text's HTML source code.
Developers may extend and enhance this plugin to bring even more HTML-related source code features to the users.
This plugin is only compatible with Redactor II 1.0.1 or higher.
https://imperavi.com/redactor/plugins/source/
*/
!function(t){t.Redactor.prototype.source=function(){return{init:function(){var e=this.button.addFirst("html","HTML");this.button.addCallback(e,this.source.toggle);var s={width:"100%",margin:"0",background:"#111","box-sizing":"border-box",color:"rgba(255, 255, 255, .8)","font-size":"14px",outline:"none",padding:"16px","line-height":"22px","font-family":'Menlo, Monaco, Consolas, "Courier New", monospace'};this.source.$textarea=t("<textarea />"),this.source.$textarea.css(s).hide(),"textarea"===this.opts.type?this.core.box().append(this.source.$textarea):this.core.box().after(this.source.$textarea),this.core.element().on("destroy.callback.redactor",t.proxy(function(){this.source.$textarea.remove()},this))},toggle:function(){return this.source.$textarea.hasClass("open")?this.source.hide():this.source.show()},setCaretOnShow:function(){this.source.offset=this.offset.get();t(window).scrollTop(),this.core.editor().innerWidth(),this.core.editor().innerHeight();this.source.start=0,this.source.end=0;var e=t("<div/>").append(t.parseHTML(this.core.editor().html(),document,!0)),s=e.find("span.redactor-selection-marker");if(s.length>0){var r=e.html().replace(/&amp;/g,"&");1===s.length?(this.source.start=this.utils.strpos(r,e.find("#selection-marker-1").prop("outerHTML")),this.source.end=this.source.start):2===s.length&&(this.source.start=this.utils.strpos(r,e.find("#selection-marker-1").prop("outerHTML")),this.source.end=this.utils.strpos(r,e.find("#selection-marker-2").prop("outerHTML"))-e.find("#selection-marker-1").prop("outerHTML").toString().length)}},setCaretOnHide:function(t){if(this.source.start=this.source.$textarea.get(0).selectionStart,this.source.end=this.source.$textarea.get(0).selectionEnd,this.source.start>this.source.end&&this.source.end>0){var e=this.source.end,s=this.source.start;this.source.start=e,this.source.end=s}if(this.source.start=this.source.enlargeOffset(t,this.source.start),this.source.end=this.source.enlargeOffset(t,this.source.end),t=t.substr(0,this.source.start)+this.marker.html(1)+t.substr(this.source.start),this.source.end>this.source.start){var r=this.marker.html(1).toString().length;t=t.substr(0,this.source.end+r)+this.marker.html(2)+t.substr(this.source.end+r)}return t},hide:function(){this.source.$textarea.removeClass("open").hide(),this.source.$textarea.off(".redactor-source");var t=this.source.$textarea.val();t=this.paragraphize.load(t),t=this.source.setCaretOnHide(t),this.code.start(t),this.button.enableAll(),this.core.editor().show().focus(),this.selection.restore()},show:function(){this.selection.save(),this.source.setCaretOnShow();var e=this.core.editor().innerHeight(),s=this.code.get();s=s.replace(/\n\n\n/g,"\n"),s=s.replace(/\n\n/g,"\n"),this.core.editor().hide(),this.button.disableAll("html"),this.source.$textarea.val(s).height(e).addClass("open").show(),this.source.$textarea.on("keyup.redactor-source",t.proxy(function(){"textarea"===this.opts.type&&this.core.textarea().val(this.source.$textarea.val())},this)),this.marker.remove(),t(window).scrollTop(scroll),this.source.$textarea[0].setSelectionRange&&this.source.$textarea[0].setSelectionRange(this.source.start,this.source.end),this.source.$textarea[0].scrollTop=0,setTimeout(t.proxy(function(){this.source.$textarea.focus()},this),0)},enlargeOffset:function(t,e){var s=t.length,r=0;if(">"===t[e])r++;else for(var o=e;s>=o&&(r++,">"!==t[o]);o++)if("<"===t[o]||o===s){r=0;break}return e+r}}}}(jQuery);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long