@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
5,515 lines • 194 kB
JavaScript
Object.defineProperties(exports, {
__esModule: { value: true },
[Symbol.toStringTag]: { value: "Module" }
});
require("./kendo.core-kmRaf_Lg.js");
require("./kendo.progressbar.js");
require("./kendo.icons.js");
require("./kendo.popup.js");
require("./kendo.list.js");
require("./kendo.dropdownlist.js");
require("./kendo.calendar.js");
require("./kendo.datepicker.js");
require("./kendo.numerictextbox.js");
require("./kendo.combobox.js");
require("./kendo.validator.js");
require("./kendo.binder.js");
require("./kendo.window.js");
require("./kendo.dom.js");
require("./kendo.ooxml.js");
require("./kendo.excel.js");
require("./kendo.sortable.js");
require("./kendo.dropdownbutton.js");
require("./kendo.togglebutton.js");
require("./kendo.toolbar.js");
require("./kendo.treeview.js");
require("./kendo.colorpicker.js");
require("./kendo.tabstrip.js");
require("./kendo.pdf.js");
require("./kendo.listview.js");
require("./kendo.datetimepicker.js");
require("./kendo.spreadsheet.common.js");
//#region ../src/spreadsheet/dialogs.js
(function(kendo) {
var $ = kendo.jQuery;
var ObservableObject = kendo.data.ObservableObject;
var MESSAGES = kendo.spreadsheet.messages.dialogs = {
apply: "Apply",
save: "Save",
cancel: "Cancel",
remove: "Remove",
retry: "Retry",
revert: "Revert",
okText: "OK",
formatCellsDialog: {
title: "Format",
categories: {
number: "Number",
currency: "Currency",
date: "Date"
}
},
fontFamilyDialog: { title: "Font" },
fontSizeDialog: { title: "Font size" },
bordersDialog: { title: "Borders" },
alignmentDialog: {
title: "Alignment",
buttons: {
justifyLeft: "Align left",
justifyCenter: "Center",
justifyRight: "Align right",
justifyFull: "Justify",
alignTop: "Align top",
alignMiddle: "Align middle",
alignBottom: "Align bottom"
}
},
mergeDialog: {
title: "Merge cells",
buttons: {
mergeCells: "Merge all",
mergeHorizontally: "Merge horizontally",
mergeVertically: "Merge vertically",
unmerge: "Unmerge"
}
},
freezeDialog: {
title: "Freeze panes",
buttons: {
freezePanes: "Freeze panes",
freezeRows: "Freeze rows",
freezeColumns: "Freeze columns",
unfreeze: "Unfreeze panes"
}
},
confirmationDialog: {
text: "Are you sure you want to remove this sheet?",
title: "Sheet remove"
},
validationDialog: {
title: "Data Validation",
hintMessage: "Please enter a valid {0} value {1}.",
hintTitle: "Validation {0}",
criteria: {
any: "Any value",
number: "Number",
text: "Text",
date: "Date",
custom: "Custom Formula",
list: "List"
},
comparers: {
greaterThan: "greater than",
lessThan: "less than",
between: "between",
notBetween: "not between",
equalTo: "equal to",
notEqualTo: "not equal to",
greaterThanOrEqualTo: "greater than or equal to",
lessThanOrEqualTo: "less than or equal to"
},
comparerMessages: {
greaterThan: "greater than {0}",
lessThan: "less than {0}",
between: "between {0} and {1}",
notBetween: "not between {0} and {1}",
equalTo: "equal to {0}",
notEqualTo: "not equal to {0}",
greaterThanOrEqualTo: "greater than or equal to {0}",
lessThanOrEqualTo: "less than or equal to {0}",
custom: "that satisfies the formula: {0}"
},
labels: {
criteria: "Criteria",
comparer: "Comparer",
min: "Min",
max: "Max",
value: "Value",
start: "Start",
end: "End",
onInvalidData: "On invalid data",
rejectInput: "Reject input",
showWarning: "Show warning",
showHint: "Show hint",
hintTitle: "Hint title",
hintMessage: "Hint message",
ignoreBlank: "Ignore blank",
showListButton: "Display button to show list",
showCalendarButton: "Display button to show calendar"
},
placeholders: {
typeTitle: "Type title",
typeMessage: "Type message"
}
},
exportAsDialog: {
title: "Export...",
defaultFileName: "Workbook",
xlsx: { description: "Excel Workbook (.xlsx)" },
pdf: {
description: "Portable Document Format (.pdf)",
area: {
workbook: "Entire Workbook",
sheet: "Active Sheet",
selection: "Selection"
},
paper: {
a2: "A2 (420 mm × 594 mm)",
a3: "A3 (297 mm x 420 mm)",
a4: "A4 (210 mm x 297 mm)",
a5: "A5 (148 mm x 210 mm)",
b3: "B3 (353 mm × 500 mm)",
b4: "B4 (250 mm x 353 mm)",
b5: "B5 (176 mm x 250 mm)",
folio: "Folio (8.5\" x 13\")",
legal: "Legal (8.5\" x 14\")",
letter: "Letter (8.5\" x 11\")",
tabloid: "Tabloid (11\" x 17\")",
executive: "Executive (7.25\" x 10.5\")"
},
margin: {
normal: "Normal",
narrow: "Narrow",
wide: "Wide"
}
},
labels: {
scale: "Scale",
fit: "Fit to page",
fileName: "File name",
saveAsType: "Save as type",
exportArea: "Export",
paperSize: "Paper size",
margins: "Margins",
orientation: "Orientation",
print: "Print",
guidelines: "Guidelines",
center: "Center",
horizontally: "Horizontally",
vertically: "Vertically"
}
},
modifyMergedDialog: { errorMessage: "Cannot change part of a merged cell." },
rangeDisabledDialog: { errorMessage: "Destination range contains disabled cells." },
intersectsArrayDialog: { errorMessage: "You cannot alter part of an array" },
incompatibleRangesDialog: { errorMessage: "Incompatible ranges" },
noFillDirectionDialog: { errorMessage: "Cannot determine fill direction" },
duplicateSheetNameDialog: { errorMessage: "Duplicate sheet name" },
overflowDialog: { errorMessage: "Cannot paste, because the copy area and the paste area are not the same size and shape." },
useKeyboardDialog: {
title: "Copying and pasting",
errorMessage: "These actions cannot be invoked through the menu. Please use the keyboard shortcuts instead:",
labels: {
forCopy: "for copy",
forCut: "for cut",
forPaste: "for paste"
}
},
unsupportedSelectionDialog: { errorMessage: "That action cannot be performed on multiple selection." },
linkDialog: {
title: "Hyperlink",
labels: {
text: "Text",
url: "Address",
removeLink: "Remove link"
}
},
sheetRenameDialog: {
title: "Rename Sheet",
labels: {
text: "Rename Sheet",
rename: "Rename"
}
},
insertCommentDialog: {
title: "Insert comment",
labels: {
comment: "Comment",
removeComment: "Remove comment"
}
},
insertImageDialog: {
title: "Insert image",
info: "Drag an image here, or click to select",
typeError: "Please select a JPEG, PNG or GIF image"
}
};
var registry = {};
kendo.spreadsheet.dialogs = {
register: function(name, dialogClass) {
registry[name] = dialogClass;
},
registered: function(name) {
return !!registry[name];
},
create: function(name, options) {
var dialogClass = registry[name];
if (dialogClass) return new dialogClass(options);
}
};
var SpreadsheetDialog = kendo.spreadsheet.SpreadsheetDialog = kendo.Observable.extend({
init: function(options) {
kendo.Observable.fn.init.call(this, options);
this.options = translate($.extend(true, {}, this.options, options));
this.bind(this.events, options);
},
events: ["close", "activate"],
options: { autoFocus: true },
dialog: function() {
if (!this._dialog) {
var options = {
autoFocus: false,
scrollable: false,
resizable: false,
modal: true,
visible: false,
width: this.options.width || 320,
title: this.options.title,
open: function() {
this.center();
},
close: this._onDialogClose.bind(this),
activate: this._onDialogActivate.bind(this),
deactivate: this._onDialogDeactivate.bind(this)
};
this._dialog = $("<div class='k-spreadsheet-window k-action-window k-popup-edit-form' />").addClass(this.options.className || "").append(kendo.template(this.options.template)({
messages: kendo.spreadsheet.messages.dialogs || MESSAGES,
ns: kendo.ns,
errors: this.options.errors
})).kendoWindow(options).data("kendoWindow");
}
return this._dialog;
},
_onDialogClose: function() {
this.trigger("close", { action: this._action });
},
_onDialogActivate: function() {
this.trigger("activate");
},
_onDialogDeactivate: function() {
this.trigger("deactivate");
this.destroy();
},
destroy: function() {
if (this._dialog) {
this._dialog.destroy();
this._dialog = null;
}
},
open: function() {
this.dialog().open();
this.dialog().element.find(".k-button-primary").trigger("focus");
},
apply: function() {
this.close();
},
close: function() {
this._action = "close";
this.dialog().close();
}
});
function formattedValue(value, format) {
return kendo.spreadsheet.formatting.text(value, format);
}
var FormatCellsViewModel = kendo.spreadsheet.FormatCellsViewModel = ObservableObject.extend({
init: function(options) {
ObservableObject.fn.init.call(this, options);
this.useCategory(this.category);
},
useCategory: function(category) {
var type = category && category.type || "number";
var formatCurrency = type == "currency";
this.category = category;
this.set("showCurrencyFilter", formatCurrency && this.currencies.length > 1);
if (!formatCurrency) this.set("formats", this.allFormats[type + "Formats"]);
else this.currency(this.currencies[0]);
this.useFirstFormat();
},
useFirstFormat: function() {
if (this.formats.length) this.set("format", this.formats[0].value);
},
currency: function(currency) {
if (currency !== void 0) {
this._currency = currency;
var info = currency.value;
var formats = [
{
currency: info,
decimals: true
},
{
currency: info,
decimals: true,
iso: true
},
{
currency: info,
decimals: false
}
];
formats = formats.map(function(format) {
format = FormatCellsViewModel.convert.currency(format);
return {
value: format,
name: formattedValue(1e3, format)
};
});
this.set("formats", formats);
this.useFirstFormat();
}
return this._currency || this.currencies[0];
},
categoryFilter: function(category) {
if (category !== void 0) this.useCategory(category);
return this.category;
},
preview: function() {
var format = this.get("format");
var value = this.value || 0;
if (format && format.length) return formattedValue(value, format);
else return value;
}
});
FormatCellsViewModel.convert = {
currency: function(options) {
function repeat(token, n) {
return new Array(n + 1).join(token);
}
var info = options.currency;
var format = info.pattern[1];
if (options.decimals) format = format.replace(/n/g, "n" + info["."] + repeat("0", info.decimals));
if (options.iso) format = "\"" + info.abbr + "\" " + format.replace(/\s*\$\s*/g, "");
else format = format.replace(/\$/g, JSON.stringify(info.symbol));
format = format.replace(/n/g, "?");
return format;
},
date: function(format) {
if (/T|Z/.test(format)) return "";
return format.toLowerCase().replace(/tt/g, "AM/PM").replace(/'/g, "\"");
}
};
function uniqueBy(field, array) {
var result = [];
var values = [];
for (var i = 0; i < array.length; i++) if ($.inArray(array[i][field], values) == -1) {
result.push(array[i]);
values.push(array[i][field]);
}
return result;
}
var FormatCellsDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.formatCellsDialog || MESSAGES;
var defaultOptions = {
title: messages.title,
categories: [
{
type: "number",
name: messages.categories.number
},
{
type: "currency",
name: messages.categories.currency
},
{
type: "date",
name: messages.categories.date
}
]
};
SpreadsheetDialog.fn.init.call(this, $.extend(defaultOptions, options));
this._generateFormats();
},
options: {
className: "k-spreadsheet-format-cells",
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-edit-form-container'><div class='k-root-tabs' data-${kendo.htmlEncode(data.ns)}role='tabstrip' data-${kendo.htmlEncode(data.ns)}text-field='name' data-${kendo.htmlEncode(data.ns)}bind='source: categories, value: categoryFilter' data-${kendo.htmlEncode(data.ns)}animation='false'></div>
<div class='k-spreadsheet-preview' data-${kendo.htmlEncode(data.ns)}bind='text: preview'></div><select data-${kendo.htmlEncode(data.ns)}role='dropdownlist' class='k-format-filter' data-${kendo.htmlEncode(data.ns)}text-field='description' data-${kendo.htmlEncode(data.ns)}value-field='value.name' data-${kendo.htmlEncode(data.ns)}bind='visible: showCurrencyFilter, value: currency, source: currencies'></select><ul data-${kendo.htmlEncode(data.ns)}role='staticlist' tabindex='0' id='formats-list' aria-label='formats list' class='k-list k-reset' bind:data-${kendo.htmlEncode(data.ns)}template='formatItemTemplate' data-${kendo.htmlEncode(data.ns)}value-primitive='true' data-${kendo.htmlEncode(data.ns)}value-field='value' data-${kendo.htmlEncode(data.ns)}bind='source: formats, value: format'></ul>
<div class='k-actions'><button class='k-button k-button-primary' data-${kendo.htmlEncode(data.ns)}bind='click: apply'><span class='k-button-text'>${kendo.htmlEncode(data.messages.apply)}</span></button><button class='k-button' data-${kendo.htmlEncode(data.ns)}bind='click: close'><span class='k-button-text'>${kendo.htmlEncode(data.messages.cancel)}</span></button></div>
</div>`;
return $kendoOutput;
}
},
_generateFormats: function() {
var options = this.options;
if (!options.currencies) options.currencies = FormatCellsDialog.currenciesFrom(kendo.cultures);
if (!options.numberFormats) options.numberFormats = [
{
value: "#.00%",
name: "100.00%"
},
{
value: "#%",
name: "100%"
},
{
value: "#.00",
name: "1024.00"
},
{
value: "#,###.00",
name: "1,024.00"
}
];
if (!options.dateFormats) {
var calendarPatterns = kendo.cultures.current.calendars.standard.patterns;
options.dateFormats = uniqueBy("value", $.map(calendarPatterns, function(format) {
format = FormatCellsViewModel.convert.date(format);
if (!format) return;
return {
value: format,
name: formattedValue(34567.7678, format)
};
}));
}
},
open: function(range) {
var options = this.options;
var value = range.value();
var categories = options.categories.slice(0);
var element;
this.viewModel = new FormatCellsViewModel({
currencies: options.currencies.slice(0),
allFormats: {
numberFormats: options.numberFormats.slice(0),
dateFormats: options.dateFormats.slice(0)
},
categories,
format: range.format(),
category: value instanceof Date ? categories[2] : categories[0],
apply: this.apply.bind(this),
close: this.close.bind(this),
value,
formatItemTemplate: (data) => kendo.htmlEncode(data.name)
});
SpreadsheetDialog.fn.open.call(this);
element = this.dialog().element;
kendo.bind(element, this.viewModel);
var currencyFilter = element.find("select.k-format-filter").data("kendoDropDownList");
if (options.currencies.length > 10) currencyFilter.setOptions({ filter: "contains" });
element.find(kendo.roleSelector("staticlist")).parent().addClass("k-list-wrapper");
element.find(".k-tabstrip-content").remove();
},
apply: function() {
var format = this.viewModel.format;
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "PropertyChangeCommand",
options: {
property: "format",
value: format
}
});
}
});
FormatCellsDialog.currenciesFrom = function(cultures) {
return uniqueBy("description", $.map(cultures, function(culture, name) {
if (!/-/.test(name)) return;
var currency = culture.numberFormat.currency;
return {
description: kendo.format("{0} ({1}, {2})", currency.name, currency.abbr, currency.symbol),
value: currency
};
}));
};
kendo.spreadsheet.dialogs.register("formatCells", FormatCellsDialog);
kendo.spreadsheet.dialogs.FormatCellsDialog = FormatCellsDialog;
var MessageDialog = SpreadsheetDialog.extend({
options: {
className: "k-spreadsheet-message",
title: "",
messageId: "",
text: "",
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-spreadsheet-message-content' data-${kendo.htmlEncode(data.ns)}bind='text: text'></div>
<div class='k-actions'><button class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='click: close'><span
class='k-button-text'>${data.messages.okText}</span></button></div>`;
return $kendoOutput;
}
},
open: function() {
SpreadsheetDialog.fn.open.call(this);
var options = this.options;
var text = options.text;
if (options.messageId) text = kendo.getter(options.messageId, true)(kendo.spreadsheet.messages.dialogs);
kendo.bind(this.dialog().element, {
text,
close: this.close.bind(this)
});
}
});
kendo.spreadsheet.dialogs.register("message", MessageDialog);
var ConfirmationDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.confirmationDialog || MESSAGES;
var defaultOptions = {
title: messages.title,
text: messages.text
};
SpreadsheetDialog.fn.init.call(this, $.extend(defaultOptions, options));
},
options: {
className: "k-spreadsheet-message",
messageId: "",
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-spreadsheet-message-content' data-${kendo.htmlEncode(data.ns)}bind='text: text'></div>
<div class='k-actions'><button class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='click: confirm'><span
class='k-button-text'>${data.messages.okText}</span></button><button
class='k-button'
data-${kendo.htmlEncode(data.ns)}bind='click: cancel'><span
class='k-button-text'>${data.messages.cancel}</span></button></div>`;
return $kendoOutput;
}
},
open: function() {
SpreadsheetDialog.fn.open.call(this);
var options = this.options;
var text = options.text;
if (options.messageId) text = kendo.getter(options.messageId, true)(kendo.spreadsheet.messages.dialogs);
kendo.bind(this.dialog().element, {
text,
confirm: this.confirm.bind(this),
cancel: this.close.bind(this)
});
},
isConfirmed: function() {
return this._confirmed;
},
confirm: function() {
this._confirmed = true;
this.close();
}
});
kendo.spreadsheet.dialogs.register("confirmation", ConfirmationDialog);
var ValidationErrorDialog = SpreadsheetDialog.extend({
options: {
className: "k-spreadsheet-message",
title: "",
messageId: "",
text: "",
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-spreadsheet-message-content' data-${kendo.htmlEncode(data.ns)}bind='text: text'></div><div class='k-actions'><button class='k-button k-button-primary' data-${kendo.htmlEncode(data.ns)}bind='click: retry'><span class='k-button-text'>${data.messages.retry}</span></button><button class='k-button' data-${kendo.htmlEncode(data.ns)}bind='click: cancel'><span class='k-button-text'>${data.messages.cancel}</span></button></div>`;
return $kendoOutput;
}
},
open: function() {
SpreadsheetDialog.fn.open.call(this);
var options = this.options;
var text = options.text;
if (options.messageId) text = kendo.getter(options.messageId, true)(kendo.spreadsheet.messages.dialogs);
kendo.bind(this.dialog().element, {
text,
retry: this.retry.bind(this),
cancel: this.close.bind(this)
});
},
retry: function() {
this._retry = true;
this.close();
}
});
kendo.spreadsheet.dialogs.register("validationError", ValidationErrorDialog);
var FontFamilyDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.fontFamilyDialog || MESSAGES;
SpreadsheetDialog.fn.init.call(this, $.extend({ title: messages.title }, options));
this._list();
},
options: { template: () => "<ul class='k-list k-reset'></ul>" },
_list: function() {
var ul = this.dialog().element.find("ul");
var fonts = this.options.options;
var defaultFont = this.options.default;
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: fonts }),
template: (data) => kendo.htmlEncode(data),
value: defaultFont,
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function(e) {
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "PropertyChangeCommand",
options: {
property: "fontFamily",
value: e.sender.value()[0]
}
});
}
});
kendo.spreadsheet.dialogs.register("fontFamily", FontFamilyDialog);
var FontSizeDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.fontSizeDialog || MESSAGES;
SpreadsheetDialog.fn.init.call(this, $.extend({ title: messages.title }, options));
this._list();
},
options: { template: () => "<ul class='k-list k-reset'></ul>" },
_list: function() {
var ul = this.dialog().element.find("ul");
var sizes = this.options.options;
var defaultSize = this.options.default;
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: sizes }),
template: (data) => kendo.htmlEncode(data),
value: defaultSize,
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function(e) {
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "PropertyChangeCommand",
options: {
property: "fontSize",
value: kendo.parseInt(e.sender.value()[0])
}
});
}
});
kendo.spreadsheet.dialogs.register("fontSize", FontSizeDialog);
var BordersDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.bordersDialog || MESSAGES;
SpreadsheetDialog.fn.init.call(this, $.extend({ title: messages.title }, options));
this.element = this.dialog().element;
this._borderPalette();
this.viewModel = kendo.observable({
apply: this.apply.bind(this),
close: this.close.bind(this)
});
kendo.bind(this.element.find(".k-actions"), this.viewModel);
},
options: { template: (data) => {
let $kendoOutput;
$kendoOutput = `<div></div>
<div class='k-actions'><button class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='click: apply'><span
class='k-button-text'>${kendo.htmlEncode(data.messages.apply)}</span></button><button
class='k-button'
data-${kendo.htmlEncode(data.ns)}bind='click: close'><span
class='k-button-text'>${kendo.htmlEncode(data.messages.cancel)}</span></button></div>`;
return $kendoOutput;
} },
apply: function() {
SpreadsheetDialog.fn.apply.call(this);
var state = this.borderPalette.value();
if (state.color && state.type) this.trigger("action", {
command: "BorderChangeCommand",
options: {
border: state.type,
style: {
size: 1,
color: state.color
}
}
});
},
_borderPalette: function() {
var element = this.dialog().element.find("div").first();
this.borderPalette = new kendo.spreadsheet.BorderPalette(element, { change: this.value.bind(this) });
},
value: function(state) {
if (state === void 0) return this._state;
else this._state = state;
}
});
kendo.spreadsheet.dialogs.register("borders", BordersDialog);
var ColorChooser = SpreadsheetDialog.extend({
init: function(options) {
SpreadsheetDialog.fn.init.call(this, options);
this.element = this.dialog().element;
this.property = options.property;
this.options.title = options.title;
this.viewModel = kendo.observable({
apply: this.apply.bind(this),
close: this.close.bind(this)
});
kendo.bind(this.element.find(".k-actions"), this.viewModel);
},
options: { template: (data) => {
let $kendoOutput;
$kendoOutput = `<div></div>
<div class='k-actions'><button class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='click: apply'><span
class='k-button-text'>${kendo.htmlEncode(data.messages.apply)}</span></button><button
class='k-button'
data-${kendo.htmlEncode(data.ns)}bind='click: close'><span
class='k-button-text'>${kendo.htmlEncode(data.messages.cancel)}</span></button></div>`;
return $kendoOutput;
} },
apply: function() {
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "PropertyChangeCommand",
options: {
property: this.property,
value: this.value()
}
});
},
value: function(e) {
if (e === void 0) return this._value;
else this._value = e.value;
}
});
var ColorPickerDialog = ColorChooser.extend({
init: function(options) {
options.width = 177;
ColorChooser.fn.init.call(this, options);
this._colorPalette();
},
_colorPalette: function() {
var element = this.dialog().element.find("div").first();
this.colorPalette = element.kendoColorPalette({
palette: [
"#ffffff",
"#000000",
"#d6ecff",
"#4e5b6f",
"#7fd13b",
"#ea157a",
"#feb80a",
"#00addc",
"#738ac8",
"#1ab39f",
"#f2f2f2",
"#7f7f7f",
"#a7d6ff",
"#d9dde4",
"#e5f5d7",
"#fad0e4",
"#fef0cd",
"#c5f2ff",
"#e2e7f4",
"#c9f7f1",
"#d8d8d8",
"#595959",
"#60b5ff",
"#b3bcca",
"#cbecb0",
"#f6a1c9",
"#fee29c",
"#8be6ff",
"#c7d0e9",
"#94efe3",
"#bfbfbf",
"#3f3f3f",
"#007dea",
"#8d9baf",
"#b2e389",
"#f272af",
"#fed46b",
"#51d9ff",
"#aab8de",
"#5fe7d5",
"#a5a5a5",
"#262626",
"#003e75",
"#3a4453",
"#5ea226",
"#af0f5b",
"#c58c00",
"#0081a5",
"#425ea9",
"#138677",
"#7f7f7f",
"#0c0c0c",
"#00192e",
"#272d37",
"#3f6c19",
"#750a3d",
"#835d00",
"#00566e",
"#2c3f71",
"#0c594f"
],
change: this.value.bind(this)
}).data("kendoColorPalette");
}
});
kendo.spreadsheet.dialogs.register("colorPicker", ColorPickerDialog);
var CustomColorDialog = ColorChooser.extend({
init: function(options) {
options.width = 268;
ColorChooser.fn.init.call(this, options);
this.dialog().setOptions({ animation: false });
this.dialog().one("activate", this._colorPicker.bind(this));
},
_colorPicker: function() {
var element = this.dialog().element.find("div").first();
this.colorPicker = element.kendoFlatColorPicker({ change: this.value.bind(this) }).data("kendoFlatColorPicker");
}
});
kendo.spreadsheet.dialogs.register("customColor", CustomColorDialog);
var AlignmentDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.alignmentDialog || MESSAGES;
var defaultOptions = {
title: messages.title,
buttons: [
{
property: "textAlign",
value: "left",
iconClass: "align-left",
text: messages.buttons.justifyLeft
},
{
property: "textAlign",
value: "center",
iconClass: "align-center",
text: messages.buttons.justifyCenter
},
{
property: "textAlign",
value: "right",
iconClass: "align-right",
text: messages.buttons.justifyRight
},
{
property: "textAlign",
value: "justify",
iconClass: "align-justify",
text: messages.buttons.justifyFull
},
{
property: "verticalAlign",
value: "top",
iconClass: "align-top",
text: messages.buttons.alignTop
},
{
property: "verticalAlign",
value: "center",
iconClass: "align-middle",
text: messages.buttons.alignMiddle
},
{
property: "verticalAlign",
value: "bottom",
iconClass: "align-bottom",
text: messages.buttons.alignBottom
}
]
};
SpreadsheetDialog.fn.init.call(this, $.extend(defaultOptions, options));
this._list();
},
options: { template: () => "<ul class='k-list k-reset'></ul>" },
_list: function() {
var ul = this.dialog().element.find("ul");
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: this.options.buttons }),
template: (data) => `<a role='button' title='${data.text}' data-property='${data.property}' data-value='${data.value}'>
${kendo.ui.icon(data.iconClass)} ${data.text}
</a>`,
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function(e) {
var dataItem = e.sender.value()[0];
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "PropertyChangeCommand",
options: {
property: dataItem.property,
value: dataItem.value
}
});
}
});
kendo.spreadsheet.dialogs.register("alignment", AlignmentDialog);
var MergeDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.mergeDialog || MESSAGES;
var defaultOptions = {
title: messages.title,
buttons: [
{
value: "cells",
iconClass: "cells-merge",
text: messages.buttons.mergeCells
},
{
value: "horizontally",
iconClass: "cells-merge-horizontally",
text: messages.buttons.mergeHorizontally
},
{
value: "vertically",
iconClass: "cells-merge-vertically",
text: messages.buttons.mergeVertically
},
{
value: "unmerge",
iconClass: "table-unmerge",
text: messages.buttons.unmerge
}
]
};
SpreadsheetDialog.fn.init.call(this, $.extend(defaultOptions, options));
this._list();
},
options: { template: () => "<ul class='k-list k-reset'></ul>" },
_list: function() {
var ul = this.dialog().element.find("ul");
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: this.options.buttons }),
template: (data) => `<a role='button' title='${data.text}' data-value='${data.value}'>${kendo.ui.icon(data.iconClass)}${data.text}</a>`,
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function(e) {
var dataItem = e.sender.value()[0];
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "MergeCellCommand",
options: { value: dataItem.value }
});
}
});
kendo.spreadsheet.dialogs.register("merge", MergeDialog);
var FreezeDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.freezeDialog || MESSAGES;
var defaultOptions = {
title: messages.title,
buttons: [
{
value: "panes",
iconClass: "pane-freeze",
text: messages.buttons.freezePanes
},
{
value: "rows",
iconClass: "row-freeze",
text: messages.buttons.freezeRows
},
{
value: "columns",
iconClass: "column-freeze",
text: messages.buttons.freezeColumns
},
{
value: "unfreeze",
iconClass: "table-unmerge",
text: messages.buttons.unfreeze
}
]
};
SpreadsheetDialog.fn.init.call(this, $.extend(defaultOptions, options));
this._list();
},
options: { template: () => "<ul class='k-list k-reset'></ul>" },
_list: function() {
var ul = this.dialog().element.find("ul");
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: this.options.buttons }),
template: (data) => `<a role='button' title='${data.text}' data-value='${data.value}'>${kendo.ui.icon(data.iconClass)}${data.text}</a>`,
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function(e) {
var dataItem = e.sender.value()[0];
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "FreezePanesCommand",
options: { value: dataItem.value }
});
}
});
kendo.spreadsheet.dialogs.register("freeze", FreezeDialog);
var ValidationViewModel = kendo.spreadsheet.ValidationCellsViewModel = ObservableObject.extend({
init: function(options) {
ObservableObject.fn.init.call(this, options);
this.bind("change", (function(e) {
if (e.field === "criterion") {
this.reset();
if (this.criterion === "custom" || this.criterion === "list") this.setHintMessageTemplate();
}
if (e.field === "comparer") this.setHintMessageTemplate();
if ((e.field == "hintMessage" || e.field == "hintTitle") && !this._mute) this.shouldBuild = false;
if ((e.field == "from" || e.field == "to" || e.field == "hintMessageTemplate" || e.field == "type") && this.shouldBuild) this.buildMessages();
}).bind(this));
this.reset();
},
buildMessages: function() {
this._mute = true;
this.set("hintTitle", this.hintTitleTemplate ? kendo.format(this.hintTitleTemplate, this.type) : "");
this.set("hintMessage", this.hintMessageTemplate ? kendo.format(this.hintMessageTemplate, this.from, this.to) : "");
this._mute = false;
},
reset: function() {
this.setComparers();
this.set("comparer", this.comparers[0].type);
this.set("from", null);
this.set("to", null);
this.set("useCustomMessages", false);
this.shouldBuild = true;
this.hintTitleTemplate = this.defaultHintTitle;
this.buildMessages();
},
setComparers: function() {
var all = this.defaultComparers;
var comparers = [];
if (this.criterion === "text") {
var text_comparers = ["equalTo", "notEqualTo"];
for (var idx = 0; idx < all.length; idx++) if (text_comparers[0] == all[idx].type) {
comparers.push(all[idx]);
text_comparers.shift();
}
} else comparers = all.slice();
this.set("comparers", comparers);
},
setHintMessageTemplate: function() {
if (this.criterion !== "custom" && this.criterion !== "list") this.set("hintMessageTemplate", kendo.format(this.defaultHintMessage, this.criterion, this.comparerMessages[this.comparer]));
else {
this.set("hintMessageTemplate", "");
this.set("hintMessage", "");
}
},
isAny: function() {
return this.get("criterion") === "any";
},
isNumber: function() {
return this.get("criterion") === "number";
},
showToForNumber: function() {
return this.showTo() && this.isNumber();
},
showToForDate: function() {
return this.showTo() && this.isDate();
},
isText: function() {
return this.get("criterion") === "text";
},
isDate: function() {
return this.get("criterion") === "date";
},
isList: function() {
return this.get("criterion") === "list";
},
isCustom: function() {
return this.get("criterion") === "custom";
},
showRemove: function() {
return this.get("hasValidation");
},
showTo: function() {
return this.get("comparer") == "between" || this.get("comparer") == "notBetween";
},
update: function(validation) {
this.set("hasValidation", !!validation);
if (validation) this.fromValidationObject(validation);
},
fromValidationObject: function(validation) {
this.set("criterion", validation.dataType);
this.set("comparer", validation.comparerType);
this.set("from", validation.from);
this.set("to", validation.to);
this.set("type", validation.type);
this.set("ignoreBlank", validation.allowNulls);
this.set("showButton", validation.showButton);
if (validation.messageTemplate || validation.titleTemplate) {
this.hintMessageTemplate = validation.messageTemplate;
this.hintMessage = validation.messageTemplate;
this.hintTitleTemplate = validation.titleTemplate;
this.hintTitle = validation.titleTemplate;
this.useCustomMessages = true;
this.buildMessages();
} else this.useCustomMessages = false;
},
toValidationObject: function() {
if (this.criterion === "any") return null;
var options = {
type: this.type,
dataType: this.criterion,
comparerType: this.comparer,
from: this.from,
to: this.to,
allowNulls: this.ignoreBlank,
showButton: this.showButton
};
if (this.useCustomMessages) {
options.messageTemplate = this.shouldBuild ? this.hintMessageTemplate : this.hintMessage;
options.titleTemplate = this.hintTitle;
}
return options;
}
});
var ValidationDialog = SpreadsheetDialog.extend({
init: function(options) {
var messages = kendo.spreadsheet.messages.dialogs.validationDialog || MESSAGES;
var defaultOptions = {
title: messages.title,
hintMessage: messages.hintMessage,
hintTitle: messages.hintTitle,
criteria: [
{
type: "any",
name: messages.criteria.any
},
{
type: "number",
name: messages.criteria.number
},
{
type: "text",
name: messages.criteria.text
},
{
type: "date",
name: messages.criteria.date
},
{
type: "custom",
name: messages.criteria.custom
},
{
type: "list",
name: messages.criteria.list
}
],
comparers: [
{
type: "greaterThan",
name: messages.comparers.greaterThan
},
{
type: "lessThan",
name: messages.comparers.lessThan
},
{
type: "between",
name: messages.comparers.between
},
{
type: "notBetween",
name: messages.comparers.notBetween
},
{
type: "equalTo",
name: messages.comparers.equalTo
},
{
type: "notEqualTo",
name: messages.comparers.notEqualTo
},
{
type: "greaterThanOrEqualTo",
name: messages.comparers.greaterThanOrEqualTo
},
{
type: "lessThanOrEqualTo",
name: messages.comparers.lessThanOrEqualTo
}
],
comparerMessages: messages.comparerMessages
};
SpreadsheetDialog.fn.init.call(this, $.extend(defaultOptions, options));
},
options: {
width: 450,
criterion: "any",
type: "reject",
ignoreBlank: true,
showButton: true,
useCustomMessages: false,
errorTemplate: (data) => `<div class="k-tooltip k-tooltip-error k-validator-tooltip">
${kendo.ui.icon({
icon: "exclamation-circle",
iconClass: "k-tooltip-icon"
})}
<span class="k-tooltip-content">${data.message}</span>
<span class="k-callout k-callout-n"></span>
</div>`,
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class="k-edit-form-container">
<div class="k-edit-label"><label for="criteria">${kendo.htmlEncode(data.messages.validationDialog.labels.criteria)}:</label></div>
<div class="k-edit-field"><select id="criteria" data-${kendo.htmlEncode(data.ns)}role="dropdownlist" title="${kendo.htmlEncode(data.messages.validationDialog.labels.criteria)}" data-${kendo.htmlEncode(data.ns)}text-field="name" data-${kendo.htmlEncode(data.ns)}value-field="type" data-${kendo.htmlEncode(data.ns)}bind="value: criterion, source: criteria"></select></div>
<div data-${kendo.htmlEncode(data.ns)}bind="visible: isNumber">
<div class="k-edit-label"><label for="number-comparer">${kendo.htmlEncode(data.messages.validationDialog.labels.comparer)}:</label></div>
<div class="k-edit-field"><select id="number-comparer" data-${kendo.htmlEncode(data.ns)}role="dropdownlist" title="${kendo.htmlEncode(data.messages.validationDialog.labels.comparer)}" data-${kendo.htmlEncode(data.ns)}text-field="name" data-${kendo.htmlEncode(data.ns)}value-field="type" data-${kendo.htmlEncode(data.ns)}bind="value: comparer, source: comparers"></select></div>
<div class="k-edit-label"><label for="comparer-min">${kendo.htmlEncode(data.messages.validationDialog.labels.min)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="comparer-min" name="${kendo.htmlEncode(data.messages.validationDialog.labels.min)}" title="${kendo.htmlEncode(data.messages.validationDialog.labels.min)}" placeholder="e.g. 10" class="k-input-inner" data-${kendo.htmlEncode(data.ns)}bind="value: from, enabled: isNumber" required="required" /></span></div>
<div data-${kendo.htmlEncode(data.ns)}bind="visible: showTo">
<div class="k-edit-label"><label for="comparer-max">${kendo.htmlEncode(data.messages.validationDialog.labels.max)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="comparer-max" name="${kendo.htmlEncode(data.messages.validationDialog.labels.max)}" title="${kendo.htmlEncode(data.messages.validationDialog.labels.max)}" placeholder="e.g. 100" class="k-input-inner" data-${kendo.htmlEncode(data.ns)}bind="value: to, enabled: showToForNumber" required="required" /></span></div>
</div>
</div><div data-${kendo.htmlEncode(data.ns)}bind="visible: isText">
<div class="k-edit-label"><label for="text-comparer">${kendo.htmlEncode(data.messages.validationDialog.labels.comparer)}:</label></div>
<div class="k-edit-field"><select id="text-comparer" data-${kendo.htmlEncode(data.ns)}role="dropdownlist" title="${kendo.htmlEncode(data.messages.validationDialog.labels.comparer)}" data-${kendo.htmlEncode(data.ns)}text-field="name" data-${kendo.htmlEncode(data.ns)}value-field="type" data-${kendo.htmlEncode(data.ns)}bind="value: comparer, source: comparers"></select></div>
<div class="k-edit-label"><label for="text-comparer-value">${kendo.htmlEncode(data.messages.validationDialog.labels.value)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="text-comparer-value" name="${kendo.htmlEncode(data.messages.validationDialog.labels.value)}" title="${kendo.htmlEncode(data.messages.validationDialog.labels.value)}" class="k-input-inner" data-${kendo.htmlEncode(data.ns)}bind="value: from, enabled: isText" required="required" /></span></div>
</div><div data-${kendo.htmlEncode(data.ns)}bind="visible: isDate">
<div class="k-edit-label"><label for="date-comparer">${kendo.htmlEncode(data.messages.validationDialog.labels.comparer)}:</label></div>
<div class="k-edit-field"><select id="date-comparer" data-${kendo.htmlEncode(data.ns)}role="dropdownlist" title="${kendo.htmlEncode(data.messages.validationDialog.labels.comparer)}" data-${kendo.htmlEncode(data.ns)}text-field="name" data-${kendo.htmlEncode(data.ns)}value-field="type" data-${kendo.htmlEncode(data.ns)}bind="value: comparer, source: comparers"></select></div>
<div class="k-edit-label"><label for="date-comparer-start">${kendo.htmlEncode(data.messages.validationDialog.labels.start)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="date-comparer-start" name="${kendo.htmlEncode(data.messages.validationDialog.labels.start)}" title="${kendo.htmlEncode(data.messages.validationDialog.labels.start)}" class="k-input-inner" data-${kendo.htmlEncode(data.ns)}bind="value: from, enabled: isDate" required="required" /></span></div>
<div data-${kendo.htmlEncode(data.ns)}bind="visible: showTo">
<div class="k-edit-label"><label for="date-comparer-end">${kendo.htmlEncode(data.messages.validationDialog.labels.end)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="date-comparer-end" name="${kendo.htmlEncode(data.messages.validationDialog.labels.end)}" title="${kendo.htmlEncode(data.messages.validationDialog.labels.end)}" class="k-input-inner" data-${kendo.htmlEncode(data.ns)}bind="value: to, enabled: showToForDate" required="required" /></span></div>
</div></div><div data-${kendo.htmlEncode(data.ns)}bind="visible: isCustom">
<div class="k-edit-label"><label for="custom-comparer-value">${kendo.htmlEncode(data.messages.validationDialog.labels.value)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="custom-comparer-value" name="${kendo.htmlEncode(data.messages.validationDialog.labels.value)}" title="${kendo.htmlEncode(data.messages.validationDialog.labels.value)}" class="k-input-inner" data-${kendo.htmlEncode(data.ns)}bind="value: from, enabled: isCustom" required="required" /></span></div>
</div><div data-${kendo.htmlEncode(data.ns)}bind="visible: isList">
<div class="k-edit-label"><label for="list-comparer-value">${kendo.htmlEncode(data.messages.validationDialog.labels.value)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="list-comparer-value" name="${kendo.htmlEncode(data.messages.validationDialog.labels.value)}" title="${kendo.htmlEncode(data.messages.validationDialog.labels.value)}" class="k-input-inner" data-${kendo.htmlEncode(data.ns)}bind="value: from, enabled: isList" required="required" /></span></div>
</div><div data-${kendo.htmlEncode(data.ns)}bind="visible: isList">
<div class="k-edit-field"><input type="checkbox" name="showButton" id="listShowButton" class="k-checkbox" data-${kendo.htmlEncode(data.ns)}bind="checked: showButton" /><label for="listShowButton" class="k-checkbox-label"> ${kendo.htmlEncode(data.messages.validationDialog.labels.showListButton)}</label></div>
</div><div data-${kendo.htmlEncode(data.ns)}bind="visible: isDate">
<div class="k-edit-field"><input type="checkbox" name="showButton" id="dateShowButton" class="k-checkbox" data-${kendo.htmlEncode(data.ns)}bind="checked: showButton" /><label for="dateShowButton" class="k-checkbox-label"> ${kendo.htmlEncode(data.messages.validationDialog.labels.showCalendarButton)}</label></div>
</div><div data-${kendo.htmlEncode(data.ns)}bind="invisible: isAny">
<div class="k-edit-field"><input type="checkbox" title="${kendo.htmlEncode(data.messages.validationDialog.labels.ignoreBlank)}" name="ignoreBlank" id="ignoreBlank" class="k-checkbox" data-${kendo.htmlEncode(data.ns)}bind="checked: ignoreBlank" /><label for="ignoreBlank" class="k-checkbox-label"> ${kendo.htmlEncode(data.messages.validationDialog.labels.ignoreBlank)}</label></div>
</div><div data-${kendo.htmlEncode(data.ns)}bind="invisible: isAny">
<div class="k-hr"></div>
<div class="k-edit-label"><label>${kendo.htmlEncode(data.messages.validationDialog.labels.onInvalidData)}:</label></div>
<div class="k-edit-field"><input type="radio" title="${kendo.htmlEncode(data.messages.validationDialog.labels.rejectInput)}" id="validationTypeReject" name="validationType" value="reject" data-${kendo.htmlEncode(data.ns)}bind="checked: type" class="k-radio" /><label for="validationTypeReject" class="k-radio-label">${kendo.htmlEncode(data.messages.validationDialog.labels.rejectInput)}</label> <input type="radio" title="${kendo.htmlEncode(data.messages.validationDialog.labels.showWarning)}" id="validationTypeWarning" name="validationType" value="warning" data-${kendo.htmlEncode(data.ns)}bind="checked: type" class="k-radio" /><label for="validationTypeWarning" class="k-radio-label">${kendo.htmlEncode(data.messages.validationDialog.labels.showWarning)}</label></div>
</div><div data-${kendo.htmlEncode(data.ns)}bind="invisible: isAny" class="hint-wrapper">
<div class="k-edit-field"><input type="checkbox" title="${kendo.htmlEncode(data.messages.validationDialog.labels.showHint)}" name="useCustomMessages" id="useCustomMessages" class="k-checkbox" data-${kendo.htmlEncode(data.ns)}bind="checked: useCustomMessages" /><label class="k-checkbox-label" for="useCustomMessages"> ${kendo.htmlEncode(data.messages.validationDialog.labels.showHint)}</label></div>
<div data-${kendo.htmlEncode(data.ns)}bind="visible: useCustomMessages">
<div class="k-edit-label"><label for="hint-title">${kendo.htmlEncode(data.messages.validationDialog.labels.hintTitle)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="hint-title" name="hint-title" class="k-input-inner" title="${kendo.htmlEncode(data.messages.validationDialog.labels.hintTitle)}" placeholder="${kendo.htmlEncode(data.messages.validationDialog.placeholders.typeTitle)}" data-${kendo.htmlEncode(data.ns)}bind="value: hintTitle" /></span></div>
<div class="k-edit-label"><label for="hint-message">${kendo.htmlEncode(data.messages.validationDialog.labels.hintMessage)}:</label></div>
<div class="k-edit-field"><span class="k-textbox k-input"><input id="hint-message" class="k-input-inner" title="${kendo.htmlEncode(data.messages.validationDialog.labels.hintMessage)}" placeholder="${kendo.htmlEncode(data.messages.validationDialog.placeholders.typeMessage)}" data-${kendo.htmlEncode(data.ns)}bind="value: hintMessage" /></span></div>
</div></div>
<div class="k-actions"><button class="k-button" data-${kendo.htmlEncode(data.ns)}bind="visible: showRemove, click: remove"><span class="k-button-text">${kendo.htmlEncode(data.messages.remove)}</span></button><button class="k-button k-button-primary" data-${kendo.htmlEncode(data.ns)}bind="click: apply"><span class="k-button-text">${kendo.htmlEncode(data.messages.apply)}</span></button><button class="k-button" data-${kendo.htmlEncode(data.ns)}bind="click: close"><span class="k-button-text">${kendo.htmlEncode(data.messages.cancel)}</span></button></div>
</div>`;
return $kendoOutput;
}
},
open: function(range) {
var options = this.options;
var element;
this.viewModel = new ValidationViewModel({
type: options.type,
defaultHintMessage: options.hintMessage,
defaultHintTitle: options.hintTitle,
defaultComparers: options.comparers.slice(0),
comparerMessages: options.comparerMessages,
criteria: options.criteria.slice(0),
criterion: options.criterion,
ignoreBlank: options.ignoreBlank,
showButton: options.showButton,
apply: this.apply.bind(this),
close: this.close.bind(this),
remove: this.remove.bind(this)
});
this.viewModel.update(range.validation());
SpreadsheetDialog.fn.open.call(this);
element = this.dialog().element;
if (this.validatable) this.validatable.destroy();
kendo.bind(element, this.viewModel);
this.validatable = new kendo.ui.Validator(element.find(".k-edit-form-container"), {
validateOnBlur: false,
errorTemplate: this.options.errorTemplate || void 0
});
},
apply: function() {
if (this.validatable.validate()) {
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "EditValidationCommand",
options: { value: this.viewModel.toValidationObject() }
});
}
},
remove: function() {
this.viewModel.set("criterion", "any");
this.apply();
}
});
kendo.spreadsheet.dialogs.register("validation", ValidationDialog);
kendo.spreadsheet.dialogs.ValidationDialog = ValidationDialog;
function PDF_PAPER_SIZE(size) {
return {
value: size,
text: TEXT("exportAsDialog.pdf.paper." + size)
};
}
var ExportAsDialog = SpreadsheetDialog.extend({
init: function(options) {
SpreadsheetDialog.fn.init.call(this, options);
options = this.options;
this.viewModel = kendo.observable({
title: options.title,
name: options.name,
extension: options.extension,
fileFormats: options.fileFormats,
excel: options.excelExport,
pdf: {
proxyURL: options.pdfExport.proxyURL,
forceProxy: options.pdfExport.forceProxy,
title: options.pdfExport.title,
author: options.pdfExport.author,
autoPrint: options.pdfExport.autoPrint,
subject: options.pdfExport.subject,
keywords: options.pdfExport.keywords,
creator: options.pdfExport.creator,
date: options.pdfExport.date,
fitWidth: options.pdf.fitWidth,
area: options.pdf.area,
areas: options.pdf.areas,
paperSize: options.pdf.paperSize,
paperSizes: options.pdf.paperSizes,
margin: options.pdf.margin,
margins: options.pdf.margins,
landscape: options.pdf.landscape,
guidelines: options.pdf.guidelines,
hCenter: options.pdf.hCenter,
vCenter: options.pdf.vCenter
},
apply: this.apply.bind(this),
close: this.close.bind(this)
});
var dialog = this.dialog();
this.viewModel.bind("change", function(e) {
if (e.field === "extension") {
this.set("showPdfOptions", this.extension === ".pdf" ? true : false);
dialog.center();
}
});
kendo.bind(dialog.element, this.viewModel);
},
options: {
title: TEXT("exportAsDialog.title", "Export..."),
name: TEXT("exportAsDialog.defaultFileName", "Workbook"),
extension: ".xlsx",
fileFormats: [{
description: TEXT("exportAsDialog.xlsx.description", "Excel Workbook (.xlsx)"),
extension: ".xlsx"
}, {
description: TEXT("exportAsDialog.pdf.description", "Portable Document Format (.pdf)"),
extension: ".pdf"
}],
pdf: {
fitWidth: true,
area: "workbook",
areas: [
{
area: "workbook",
text: TEXT("exportAsDialog.pdf.area.workbook", "Entire Workbook")
},
{
area: "sheet",
text: TEXT("exportAsDialog.pdf.area.sheet", "Active Sheet")
},
{
area: "selection",
text: TEXT("exportAsDialog.pdf.area.selection", "Selection")
}
],
paperSize: "a4",
paperSizes: [
"a2",
"a3",
"a4",
"a5",
"b3",
"b4",
"b5",
"folio",
"legal",
"letter",
"tabloid",
"executive"
].map(PDF_PAPER_SIZE),
margin: {
bottom: "0.75in",
left: "0.7in",
right: "0.7in",
top: "0.75in"
},
margins: [
{
value: {
bottom: "0.75in",
left: "0.7in",
right: "0.7in",
top: "0.75in"
},
text: TEXT("exportAsDialog.pdf.margin.normal", "Normal")
},
{
value: {
bottom: "0.75in",
left: "0.25in",
right: "0.25in",
top: "0.75in"
},
text: TEXT("exportAsDialog.pdf.margin.narrow", "Narrow")
},
{
value: {
bottom: "1in",
left: "1in",
right: "1in",
top: "1in"
},
text: TEXT("exportAsDialog.pdf.margin.wide", "Wide")
}
],
landscape: true,
guidelines: true,
hCenter: true,
vCenter: true
},
width: 520,
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-edit-label'><label id='name-label'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.fileName)}:</label></div>
<div class='k-edit-field'><span class='k-textbox k-input'><input aria-labelledby='name-label' class='k-input-inner' data-${kendo.htmlEncode(data.ns)}bind='value: name' /></span></div>
<div >
<div class='k-edit-label'><label id='file-format-label'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.saveAsType)}:</label></div>
<div class='k-edit-field'><select aria-labelledby='file-format-label' data-${kendo.htmlEncode(data.ns)}role='dropdownlist' class='k-file-format' data-${kendo.htmlEncode(data.ns)}text-field='description' data-${kendo.htmlEncode(data.ns)}value-field='extension' data-${kendo.htmlEncode(data.ns)}bind='value: extension, source: fileFormats'></select></div>
</div>
<div class='k-export-config' data-${kendo.htmlEncode(data.ns)}bind='visible: showPdfOptions'>
<hr class='k-hr' />
<div class='k-edit-label'><label id='export-area-label'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.exportArea)}:</label></div>
<div class='k-edit-field'><select aria-labelledby='export-area-label' data-${kendo.htmlEncode(data.ns)}role='dropdownlist' class='k-file-format' data-${kendo.htmlEncode(data.ns)}text-field='text' data-${kendo.htmlEncode(data.ns)}value-field='area' data-${kendo.htmlEncode(data.ns)}bind='value: pdf.area, source: pdf.areas'></select></div>
<div class='k-edit-label'><label id='paper-size-label'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.paperSize)}:</label></div>
<div class='k-edit-field'><select aria-labelledby='paper-size-label' data-${kendo.htmlEncode(data.ns)}role='dropdownlist' class='k-file-format' data-${kendo.htmlEncode(data.ns)}text-field='text' data-${kendo.htmlEncode(data.ns)}value-field='value' data-${kendo.htmlEncode(data.ns)}bind='value: pdf.paperSize, source: pdf.paperSizes'></select></div>
<div class='k-edit-label'><label id='margins-label'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.margins)}:</label></div>
<div class='k-edit-field'><select aria-labelledby='margins-label' data-${kendo.htmlEncode(data.ns)}role='dropdownlist' class='k-file-format' data-${kendo.htmlEncode(data.ns)}value-primitive='true'data-${kendo.htmlEncode(data.ns)}text-field='text' data-${kendo.htmlEncode(data.ns)}value-field='value' data-${kendo.htmlEncode(data.ns)}bind='value: pdf.margin, source: pdf.margins'></select></div>
<div class='k-edit-label'><label>${kendo.htmlEncode(data.messages.exportAsDialog.labels.orientation)}:</label></div>
<div class='k-edit-field'>
<div class='k-button-group'>
<input type='radio' id='k-orientation-portrait' aria-label='orientation portrait' name='orientation' data-${kendo.htmlEncode(data.ns)}type='boolean' data-${kendo.htmlEncode(data.ns)}bind='checked: pdf.landscape' value='false' />
<label class='k-button k-icon-button k-group-start k-orientation-button' for='k-orientation-portrait'>
${kendo.ui.icon({
icon: "file",
iconClass: "k-button-icon"
})}
</label>
<input type='radio' id='k-orientation-landscape' aria-label='orientation landscape' name='orientation' data-${kendo.htmlEncode(data.ns)}type='boolean' data-${kendo.htmlEncode(data.ns)}bind='checked: pdf.landscape' value='true' />
<label class='k-button k-icon-button k-group-end k-orientation-button' for='k-orientation-landscape'>
${kendo.ui.icon({
icon: "file-horizontal",
iconClass: "k-button-icon"
})}
</label>
</div>
</div>
<div class='k-edit-label'><label>${kendo.htmlEncode(data.messages.exportAsDialog.labels.print)}:</label></div>
<div class='k-edit-field'><input class='k-checkbox' id='guidelines' type='checkbox' data-${kendo.htmlEncode(data.ns)}bind='checked: pdf.guidelines'/><label class='k-checkbox-label' for='guidelines'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.guidelines)}</label></div>
<div class='k-edit-label'><label>${kendo.htmlEncode(data.messages.exportAsDialog.labels.scale)}:</label></div>
<div class='k-edit-field'><input class='k-checkbox' id='fitWidth' type='checkbox' data-${kendo.htmlEncode(data.ns)}bind='checked: pdf.fitWidth'/><label class='k-checkbox-label' for='fitWidth'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.fit)}</label></div>
<div class='k-edit-label'><label>${kendo.htmlEncode(data.messages.exportAsDialog.labels.center)}:</label></div>
<div class='k-edit-field'><input class='k-checkbox' id='hCenter' type='checkbox' data-${kendo.htmlEncode(data.ns)}bind='checked: pdf.hCenter'/><label class='k-checkbox-label' for='hCenter'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.horizontally)}</label><input class='k-checkbox' id='vCenter' type='checkbox' data-${kendo.htmlEncode(data.ns)}bind='checked: pdf.vCenter'/><label class='k-checkbox-label' for='vCenter'>${kendo.htmlEncode(data.messages.exportAsDialog.labels.vertically)}</label></div>
<div class='k-page-orientation'>
${kendo.ui.icon($(`<span data-${data.ns}bind='invisible: pdf.landscape'></span>`), { icon: "file" })}
${kendo.ui.icon($(`<span data-${data.ns}bind='visible: pdf.landscape'></span>`), { icon: "file-horizontal" })}
</div>
</div>
<div class='k-actions'><button class='k-button k-button-primary' data-${kendo.htmlEncode(data.ns)}bind='click: apply'><span class='k-button-text'>${kendo.htmlEncode(data.messages.save)}</span></button><button class='k-button' data-${kendo.htmlEncode(data.ns)}bind='click: close'><span class='k-button-text'>${kendo.htmlEncode(data.messages.cancel)}</span></button></div>`;
return $kendoOutput;
}
},
apply: function() {
SpreadsheetDialog.fn.apply.call(this);
this.trigger("action", {
command: "SaveAsCommand",
options: this.viewModel
});
}
});
kendo.spreadsheet.dialogs.register("exportAs", ExportAsDialog);
function basicErrorDialog(id, msg) {
kendo.spreadsheet.dialogs.register(id, MessageDialog.extend({ options: { messageId: msg } }));
}
basicErrorDialog("modifyMerged", "modifyMergedDialog.errorMessage");
basicErrorDialog("rangeDisabled", "rangeDisabledDialog.errorMessage");
basicErrorDialog("intersectsArray", "intersectsArrayDialog.errorMessage");
basicErrorDialog("overflow", "overflowDialog.errorMessage");
basicErrorDialog("unsupportedSelection", "unsupportedSelectionDialog.errorMessage");
basicErrorDialog("incompatibleRanges", "incompatibleRangesDialog.errorMessage");
basicErrorDialog("noFillDirection", "noFillDirectionDialog.errorMessage");
basicErrorDialog("duplicateSheetName", "duplicateSheetNameDialog.errorMessage");
var ImportErrorDialog = MessageDialog.extend({ options: {
width: 640,
title: "Errors in import",
template: (data) => {
let $kendoOutput;
const errors = data.errors;
$kendoOutput = `<div class='k-spreadsheet-message-content k-spreadsheet-import-errors'><div class='k--header-message'>We encountered ${errors.length} errors while reading this file. Please be aware that some formulas might be missing, or contain invalid results.</div><div class='k--errors'><table><thead><tr><th>Context</th><th>Error message</th></tr></thead>`;
for (let i = 0; i < errors.length; ++i) {
$kendoOutput += ``;
let err = errors[i];
$kendoOutput += `<tr><td>${kendo.htmlEncode(err.context)}</td><td>${kendo.htmlEncode(err.error)}</td></tr>`;
}
$kendoOutput += `</table></div></div><div class='k-actions'><button class='k-button k-button-primary' data-${kendo.htmlEncode(data.ns)}bind='click: close'><span class='k-button-text'>${kendo.htmlEncode(data.messages.okText)}</span></button></div>`;
return $kendoOutput;
}
} });
kendo.spreadsheet.dialogs.register("importError", ImportErrorDialog);
var UseKeyboardDialog = MessageDialog.extend({ options: {
title: TEXT("useKeyboardDialog.title", "Copying and pasting"),
template: (data) => {
let $kendoOutput;
$kendoOutput = `${kendo.htmlEncode(data.messages.useKeyboardDialog.errorMessage)}
<div>Ctrl+C ${kendo.htmlEncode(data.messages.useKeyboardDialog.labels.forCopy)}</div>
<div>Ctrl+X ${kendo.htmlEncode(data.messages.useKeyboardDialog.labels.forCut)}</div>
<div>Ctrl+V ${kendo.htmlEncode(data.messages.useKeyboardDialog.labels.forPaste)}</div>
<div class="k-actions"><button class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='click: close'><span
class='k-button-text'>${data.messages.okText}</span></button></div>`;
return $kendoOutput;
}
} });
kendo.spreadsheet.dialogs.register("useKeyboard", UseKeyboardDialog);
var HyperlinkDialog = SpreadsheetDialog.extend({
options: {
title: TEXT("linkDialog.title", "Hyperlink"),
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-edit-label'><label id='url-label'>${kendo.htmlEncode(data.messages.linkDialog.labels.url)}:</label></div>
<div class='k-edit-field'><span class='k-textbox k-input'><input
class='k-input-inner' data-${kendo.htmlEncode(data.ns)}bind='value: url'
title='${kendo.htmlEncode(data.messages.linkDialog.labels.url)}' aria-labelledby='url-label' /></span></div>
<div class='k-actions'><button class='k-button k-left'
data-${kendo.htmlEncode(data.ns)}bind='click: remove'><span
class='k-button-text'>${data.messages.linkDialog.labels.removeLink}</span></button><button
class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='click: apply'><span
class='k-button-text'>${data.messages.okText}</span></button><button
class='k-button'
data-${kendo.htmlEncode(data.ns)}bind='click: cancel'><span
class='k-button-text'>${data.messages.cancel}</span></button></div>`;
return $kendoOutput;
},
autoFocus: false
},
open: function(range) {
var self = this;
SpreadsheetDialog.fn.open.apply(self, arguments);
var element = self.dialog().element;
var model = kendo.observable({
url: range.link(),
apply: function() {
if (!/\S/.test(model.url)) model.url = null;
self.trigger("action", {
command: "HyperlinkCommand",
options: { link: model.url }
});
self.close();
},
remove: function() {
model.url = null;
model.apply();
},
cancel: self.close.bind(self)
});
kendo.bind(element, model);
element.find("input").trigger("focus").on("keydown", function(ev) {
if (ev.keyCode == 13) {
model.url = $(this).val();
ev.stopPropagation();
ev.preventDefault();
model.apply();
} else if (ev.keyCode == 27) {
ev.stopPropagation();
ev.preventDefault();
model.cancel();
}
});
}
});
kendo.spreadsheet.dialogs.register("hyperlink", HyperlinkDialog);
var SheetRenameDialog = SpreadsheetDialog.extend({
options: {
title: TEXT("sheetRenameDialog.title", "Rename Sheet"),
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-edit-label'><label id='sheet-name-label'>${kendo.htmlEncode(data.messages.sheetRenameDialog.labels.text)}:</label></div>
<div class='k-edit-field'><span class='k-textbox k-input'><input
class='k-input-inner' data-${kendo.htmlEncode(data.ns)}bind='value: sheetName'
title='${kendo.htmlEncode(data.messages.sheetRenameDialog.labels.text)}' aria-labelledby='sheet-name-label' /></span></div>
<div class='k-actions'><button class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='click: apply'><span
class='k-button-text'>${data.messages.sheetRenameDialog.labels.rename}</span></button><button
class='k-button'
data-${kendo.htmlEncode(data.ns)}bind='click: cancel'><span
class='k-button-text'>${data.messages.cancel}</span></button></div>`;
return $kendoOutput;
},
autoFocus: false
},
open: function(range, args) {
let sheet = range.sheet();
let self = this;
SpreadsheetDialog.fn.open.apply(self, arguments);
let element = self.dialog().element;
let model = kendo.observable({
sheetName: args?._oldSheetName || sheet.name(),
apply: function() {
self._newSheetName = model.sheetName;
self.close();
},
cancel: self.close.bind(self)
});
kendo.bind(element, model);
element.find("input").trigger("focus").on("keydown", function(ev) {
if (ev.keyCode == 13) {
model.sheetName = $(this).val();
ev.stopPropagation();
ev.preventDefault();
model.apply();
} else if (ev.keyCode == 27) {
ev.stopPropagation();
ev.preventDefault();
model.cancel();
}
});
}
});
kendo.spreadsheet.dialogs.register("renameSheet", SheetRenameDialog);
var InsertCommentDialog = SpreadsheetDialog.extend({
options: {
className: "k-spreadsheet-insert-comment",
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-edit-label'><label id='comment-label'>${kendo.htmlEncode(data.messages.insertCommentDialog.labels.comment)}:</label></div>
<div class='k-edit-field'><span class='k-input k-textarea'><textarea
aria-labelledby='comment-label' rows='5' class='k-input-inner'
data-${kendo.htmlEncode(data.ns)}bind='value: comment'></textarea></span></div>
<div class='k-actions'> <button class='k-button k-left'
data-${kendo.htmlEncode(data.ns)}bind='click: remove'><span
class='k-button-text'>${kendo.htmlEncode(data.messages.insertCommentDialog.labels.removeComment)}</span></button>
<button class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='click: apply'><span
class='k-button-text'>${kendo.htmlEncode(data.messages.okText)}</span></button> <button
class='k-button'
data-${kendo.htmlEncode(data.ns)}bind='click: cancel'><span
class='k-button-text'>${data.messages.cancel}</span></button></div>`;
return $kendoOutput;
},
title: TEXT("insertCommentDialog.title", "Insert comment"),
autoFocus: false,
width: 450
},
open: function(range) {
var self = this;
SpreadsheetDialog.fn.open.apply(self, arguments);
var element = self.dialog().element;
var model = kendo.observable({
comment: range.comment(),
apply: function() {
if (!/\S/.test(model.comment)) model.comment = null;
self.trigger("action", {
command: "InsertCommentCommand",
options: { value: model.comment }
});
self.close();
},
remove: function() {
model.comment = null;
model.apply();
},
cancel: self.close.bind(self)
});
kendo.bind(element, model);
element.find("textarea").trigger("focus");
}
});
kendo.spreadsheet.dialogs.register("insertComment", InsertCommentDialog);
var InsertImageDialog = SpreadsheetDialog.extend({
options: {
template: (data) => {
let $kendoOutput;
$kendoOutput = `<div class='k-spreadsheet-insert-image-dialog'> <label
data-${kendo.htmlEncode(data.ns)}bind='style: { background-image: imageUrl }, css: { k-spreadsheet-has-image: hasImage, k-hover: isHovered }, events: { dragenter: dragEnter, dragover: stopEvent, dragleave: dragLeave, drop: drop }'>
<div data-${kendo.htmlEncode(data.ns)}bind='text: info'></div>
<input type='file' data-${kendo.htmlEncode(data.ns)}bind='events: { change: change }'
accept='image/png, image/jpeg, image/gif' />
</label></div>
<div class='k-actions'> <button class='k-button k-button-primary'
data-${kendo.htmlEncode(data.ns)}bind='enabled: okEnabled, click: apply'><span
class='k-button-text'>${kendo.htmlEncode(data.messages.okText)}</span></button> <button
class='k-button'
data-${kendo.htmlEncode(data.ns)}bind='click: cancel'><span
class='k-button-text'>${data.messages.cancel}</span></button></div>`;
return $kendoOutput;
},
title: TEXT("insertImageDialog.title", "Insert image"),
width: "auto"
},
open: function() {
var self = this;
SpreadsheetDialog.fn.open.apply(self, arguments);
var element = self.dialog().element;
var model = kendo.observable({
okEnabled: false,
info: kendo.spreadsheet.messages.dialogs.insertImageDialog.info,
imageUrl: "",
hasImage: false,
isHovered: false,
_url: null,
_image: null,
apply: function() {
window.URL.revokeObjectURL(model._url);
self.trigger("action", {
command: "InsertImageCommand",
options: {
blob: model._image,
width: model._width,
height: model._height
}
});
self.close();
},
cancel: self.close.bind(self),
stopEvent: function(ev) {
ev.stopPropagation();
ev.preventDefault();
},
drop: function(ev) {
model.stopEvent(ev);
model.selectFile(ev.originalEvent.dataTransfer.files);
model.set("isHovered", false);
},
dragEnter: function(ev) {
model.stopEvent(ev);
model.set("isHovered", true);
},
dragLeave: function(ev) {
model.stopEvent(ev);
model.set("isHovered", false);
},
change: function(ev) {
model.selectFile(ev.target.files);
},
selectFile: function(files) {
var image;
for (var i = 0; i < files.length; ++i) if (/^image\//i.test(files[i].type)) {
image = files[i];
break;
}
if (model._url) window.URL.revokeObjectURL(model._url);
if (image) {
model._image = image;
model._url = window.URL.createObjectURL(image);
var img = new Image();
img.src = model._url;
img.onload = function() {
model._width = img.width;
model._height = img.height;
model.set("info", kendo.spreadsheet.messages.dialogs.insertImageDialog.info);
model.set("okEnabled", true);
model.set("imageUrl", "url('" + model._url + "')");
model.set("hasImage", true);
};
} else {
model._image = null;
model.set("info", kendo.spreadsheet.messages.dialogs.insertImageDialog.typeError);
model.set("okEnabled", false);
model.set("imageUrl", "");
model.set("hasImage", false);
}
}
});
kendo.bind(element, model);
}
});
kendo.spreadsheet.dialogs.register("insertImage", InsertImageDialog);
function Localizable(path, def) {
this.path = path.split(".");
this.def = def;
}
Localizable.prototype.trans = function() {
var msg = kendo.spreadsheet.messages.dialogs;
for (var i = 0; i < this.path.length; ++i) {
msg = msg[this.path[i]];
if (!msg) return this.def;
}
return msg;
};
function TEXT(path, def) {
return new Localizable(path, def);
}
function translate(thing) {
if (thing instanceof Localizable) return thing.trans();
else if (Array.isArray(thing)) return thing.map(translate);
else if (thing != null && typeof thing == "object") return Object.keys(thing).reduce(function(ret, key) {
ret[key] = translate(thing[key]);
return ret;
}, {});
return thing;
}
})(window.kendo);
//#endregion
//#region ../src/spreadsheet/borderpalette.js
(function(kendo) {
var $ = kendo.jQuery;
var BORDER_TYPES = [
"allBorders",
"insideBorders",
"insideHorizontalBorders",
"insideVerticalBorders",
"outsideBorders",
"leftBorder",
"topBorder",
"rightBorder",
"bottomBorder",
"noBorders"
];
var BORDER_TYPES_ICONS = {
allBorders: "bordersAll",
insideBorders: "bordersInside",
insideHorizontalBorders: "bordersInsideHorizontal",
insideVerticalBorders: "bordersInsideVertical",
outsideBorders: "bordersOutside",
leftBorder: "borderLeft",
topBorder: "borderTop",
rightBorder: "borderRight",
bottomBorder: "borderBottom",
noBorders: "bordersNone"
};
var BORDER_PALETTE_MESSAGES = kendo.spreadsheet.messages.borderPalette = {
allBorders: "All borders",
insideBorders: "Inside borders",
insideHorizontalBorders: "Inside horizontal borders",
insideVerticalBorders: "Inside vertical borders",
outsideBorders: "Outside borders",
leftBorder: "Left border",
topBorder: "Top border",
rightBorder: "Right border",
bottomBorder: "Bottom border",
noBorders: "No border"
};
var colorPickerPalette = [
"#ffffff",
"#000000",
"#d6ecff",
"#4e5b6f",
"#7fd13b",
"#ea157a",
"#feb80a",
"#00addc",
"#738ac8",
"#1ab39f",
"#f2f2f2",
"#7f7f7f",
"#a7d6ff",
"#d9dde4",
"#e5f5d7",
"#fad0e4",
"#fef0cd",
"#c5f2ff",
"#e2e7f4",
"#c9f7f1",
"#d8d8d8",
"#595959",
"#60b5ff",
"#b3bcca",
"#cbecb0",
"#f6a1c9",
"#fee29c",
"#8be6ff",
"#c7d0e9",
"#94efe3",
"#bfbfbf",
"#3f3f3f",
"#007dea",
"#8d9baf",
"#b2e389",
"#f272af",
"#fed46b",
"#51d9ff",
"#aab8de",
"#5fe7d5",
"#a5a5a5",
"#262626",
"#003e75",
"#3a4453",
"#5ea226",
"#af0f5b",
"#c58c00",
"#0081a5",
"#425ea9",
"#138677",
"#7f7f7f",
"#0c0c0c",
"#00192e",
"#272d37",
"#3f6c19",
"#750a3d",
"#835d00",
"#00566e",
"#2c3f71",
"#0c594f"
];
var BorderPalette = kendo.ui.Widget.extend({
init: function(element, options) {
kendo.ui.Widget.call(this, element, options);
this.element = element;
this.color = "#000";
this.element.addClass("k-spreadsheet-popup");
this._borderTypePalette();
this._borderColorPalette();
},
options: { name: "BorderPalette" },
events: ["change"],
destroy: function() {
this.colorChooser.destroy();
kendo.destroy(this.element.find(".k-spreadsheet-border-type-palette"));
},
value: function() {
return {
type: this.type,
color: this.color
};
},
_borderTypePalette: function() {
var that = this;
var messages = BORDER_PALETTE_MESSAGES;
var element = $("<div />", { "class": "k-spreadsheet-border-type-palette" });
$("<span class=\"k-column-menu-group-header\"><span class=\"k-column-menu-group-header-text\">Border type</span></span>").appendTo(this.element);
element.appendTo(this.element);
BORDER_TYPES.map(function(type) {
$("<button title=\"" + messages[type] + "\" aria-label=\"" + messages[type] + "\" data-border-type=\"" + type + "\">").appendTo(element).kendoToggleButton({
icon: kendo.toHyphens(BORDER_TYPES_ICONS[type]),
toggle: that._toggle.bind(that)
});
});
},
_borderColorPalette: function() {
var element = $("<div />", { "class": "k-spreadsheet-border-color-palette" });
$("<span class=\"k-column-menu-group-header\"><span class=\"k-column-menu-group-header-text\">Border color</span></span>").appendTo(this.element);
element.appendTo(this.element);
this.colorChooser = new kendo.ui.FlatColorPicker(element, {
buttons: !this.options.change,
color: this.color,
view: "palette",
palette: colorPickerPalette,
input: false,
change: this._change.bind(this)
});
this.colorChooser.wrapper.find(".k-coloreditor-apply").on("click", this._apply.bind(this));
this.colorChooser.wrapper.find(".k-coloreditor-cancel").on("click", this._cancel.bind(this));
},
_change: function() {
this.color = this.colorChooser.value();
},
_toggle: function(e) {
var type = e.target.data("borderType"), previous = e.target.siblings(".k-selected").data("kendoToggleButton");
if (e.checked === true) {
if (previous) previous.toggle(false);
this.type = type;
} else this.type = null;
},
_apply: function() {
this.trigger("change", {
type: this.type,
color: this.color
});
},
_cancel: function() {
this.trigger("change", {
type: null,
color: null
});
}
});
kendo.spreadsheet.BorderPalette = BorderPalette;
})(window.kendo);
//#endregion
//#region ../src/spreadsheet/toolbar.js
(function(kendo) {
var $ = kendo.jQuery;
function getDefaultToolElement(firstIconName) {
return `<button role="button">${kendo.ui.icon({
icon: firstIconName,
iconClass: "k-button-icon"
})}<span class="k-button-text">${kendo.ui.icon("chevron-down")}</span></button>`;
}
var ToolBar = kendo.ui.ToolBar;
var MESSAGES = kendo.spreadsheet.messages.toolbar = {
addColumnLeft: "Add column left",
addColumnRight: "Add column right",
addRowAbove: "Add row above",
addRowBelow: "Add row below",
alignment: "Alignment",
alignmentButtons: {
justifyLeft: "Align left",
justifyCenter: "Center",
justifyRight: "Align right",
justifyFull: "Justify",
alignTop: "Align top",
alignMiddle: "Align middle",
alignBottom: "Align bottom"
},
backgroundColor: "Background",
increaseFontSize: "Increase font size",
decreaseFontSize: "Decrease font size",
bold: "Bold",
borders: "Borders",
copy: "Copy",
cut: "Cut",
deleteColumn: "Delete column",
deleteRow: "Delete row",
filter: "Filter",
fontFamily: "Font",
fontSize: "Font size",
format: "Custom format...",
formatTypesSamples: {
number: "1,499.99",
percent: "14.50%",
financial: "(1,000.12)",
currency: "$1,499.99",
date: "4/21/2012",
time: "5:49:00 PM",
dateTime: "4/21/2012 5:49:00",
duration: "168:05:00"
},
formatTypes: {
automatic: "Automatic",
text: "Text",
number: "Number",
percent: "Percent",
financial: "Financial",
currency: "Currency",
date: "Date",
time: "Time",
dateTime: "Date time",
duration: "Duration",
moreFormats: "More formats..."
},
formatDecreaseDecimal: "Decrease decimal",
formatIncreaseDecimal: "Increase decimal",
freeze: "Freeze panes",
freezeButtons: {
freezePanes: "Freeze panes",
freezeRows: "Freeze rows",
freezeColumns: "Freeze columns",
unfreeze: "Unfreeze panes"
},
insertComment: "Insert comment",
insertImage: "Insert image",
italic: "Italic",
merge: "Merge cells",
mergeButtons: {
mergeCells: "Merge all",
mergeHorizontally: "Merge horizontally",
mergeVertically: "Merge vertically",
unmerge: "Unmerge"
},
open: "Open...",
paste: "Paste",
redo: "Redo",
undo: "Undo",
exportAs: "Export...",
toggleGridlines: "Toggle gridlines",
sort: "Sort",
sortButtons: {
sortRangeAsc: "Sort range A to Z",
sortRangeDesc: "Sort range Z to A"
},
textColor: "Text Color",
textWrap: "Wrap text",
underline: "Underline",
validation: "Data validation...",
hyperlink: "Link"
};
var defaultTools = {
file: ["open", "exportAs"],
format: [
"format",
"formatDecreaseDecimal",
"formatIncreaseDecimal"
],
home: [
["undo", "redo"],
"separator",
[
"cut",
"copy",
"paste"
],
"separator",
"fontFamily",
"fontSize",
"increaseFontSize",
"decreaseFontSize",
"separator",
[
"bold",
"italic",
"underline"
],
"separator",
"textColor",
"separator",
"backgroundColor",
"borders",
"separator",
"alignment",
"textWrap"
],
insert: [
"insertComment",
"separator",
"hyperlink",
"separator",
"insertImage",
"separator",
[
"addColumnLeft",
"addColumnRight",
"addRowBelow",
"addRowAbove"
],
"separator",
["deleteColumn", "deleteRow"]
],
data: [
"sort",
"separator",
"filter",
"separator",
"validation"
],
view: [
"freeze",
"merge",
"toggleGridlines"
]
};
var defaultFormats = kendo.spreadsheet.formats = {
automatic: null,
text: "@",
number: "#,0.00",
percent: "0.00%",
financial: "_(\"$\"* #,##0.00_);_(\"$\"* (#,##0.00);_(\"$\"* \"-\"??_);_(@_)",
currency: "$#,##0.00;[Red]$#,##0.00",
date: "m/d/yyyy",
time: "h:mm:ss AM/PM",
dateTime: "m/d/yyyy h:mm",
duration: "[h]:mm:ss"
};
var colorPickerPalette = [
"#ffffff",
"#000000",
"#d6ecff",
"#4e5b6f",
"#7fd13b",
"#ea157a",
"#feb80a",
"#00addc",
"#738ac8",
"#1ab39f",
"#f2f2f2",
"#7f7f7f",
"#a7d6ff",
"#d9dde4",
"#e5f5d7",
"#fad0e4",
"#fef0cd",
"#c5f2ff",
"#e2e7f4",
"#c9f7f1",
"#d8d8d8",
"#595959",
"#60b5ff",
"#b3bcca",
"#cbecb0",
"#f6a1c9",
"#fee29c",
"#8be6ff",
"#c7d0e9",
"#94efe3",
"#bfbfbf",
"#3f3f3f",
"#007dea",
"#8d9baf",
"#b2e389",
"#f272af",
"#fed46b",
"#51d9ff",
"#aab8de",
"#5fe7d5",
"#a5a5a5",
"#262626",
"#003e75",
"#3a4453",
"#5ea226",
"#af0f5b",
"#c58c00",
"#0081a5",
"#425ea9",
"#138677",
"#7f7f7f",
"#0c0c0c",
"#00192e",
"#272d37",
"#3f6c19",
"#750a3d",
"#835d00",
"#00566e",
"#2c3f71",
"#0c594f"
];
var COLOR_PICKER_MESSAGES = kendo.spreadsheet.messages.colorPicker = {
reset: "Reset color",
customColor: "Custom color...",
apply: "Apply",
cancel: "Cancel"
};
function getToolDefaults() {
return {
undo: {
type: "button",
name: "undo",
icon: "undo",
command: "undo"
},
redo: {
type: "button",
name: "redo",
icon: "redo",
command: "redo"
},
separator: { type: "separator" },
open: {
type: "open",
name: "open",
icon: "folder-open",
extensions: ".xlsx",
command: "OpenCommand"
},
exportAs: {
type: "button",
name: "exportAs",
dialog: "exportAs",
overflow: "never",
icon: "download"
},
bold: {
type: "button",
command: "PropertyChangeCommand",
property: "bold",
value: true,
icon: "bold",
togglable: true
},
italic: {
type: "button",
command: "PropertyChangeCommand",
property: "italic",
value: true,
icon: "italic",
togglable: true
},
underline: {
type: "button",
command: "PropertyChangeCommand",
property: "underline",
value: true,
icon: "underline",
togglable: true
},
formatDecreaseDecimal: {
type: "button",
name: "formatDecreaseDecimal",
command: "AdjustDecimalsCommand",
value: -1,
icon: "decimal-decrease"
},
formatIncreaseDecimal: {
type: "button",
name: "formatIncreaseDecimal",
command: "AdjustDecimalsCommand",
value: 1,
icon: "decimal-increase"
},
textWrap: {
type: "button",
name: "textWrap",
command: "TextWrapCommand",
property: "wrap",
value: true,
icon: "text-wrap-arrow",
togglable: true
},
cut: {
type: "button",
name: "cut",
command: "ToolbarCutCommand",
icon: "cut"
},
copy: {
type: "button",
name: "copy",
command: "ToolbarCopyCommand",
icon: "copy"
},
paste: {
type: "button",
name: "paste",
command: "ToolbarPasteCommand",
icon: "clipboard"
},
alignment: {
type: "component",
name: "alignment",
property: "alignment",
component: "DropDownButton",
element: getDefaultToolElement("align-left"),
overflowComponent: {
type: "button",
dialog: "alignment",
icon: "align-left"
},
componentOptions: {
fillMode: "flat",
items: [
{
attributes: {
"data-value": "left",
"data-property": "textAlign",
"data-command": "PropertyChangeCommand"
},
icon: "align-left",
text: MESSAGES.alignmentButtons.justifyLeft
},
{
attributes: {
"data-value": "center",
"data-property": "textAlign",
"data-command": "PropertyChangeCommand"
},
icon: "align-center",
text: MESSAGES.alignmentButtons.justifyCenter
},
{
attributes: {
"data-value": "right",
"data-property": "textAlign",
"data-command": "PropertyChangeCommand"
},
icon: "align-right",
text: MESSAGES.alignmentButtons.justifyRight
},
{
attributes: {
"data-value": "justify",
"data-property": "textAlign",
"data-command": "PropertyChangeCommand"
},
icon: "align-justify",
text: MESSAGES.alignmentButtons.justifyFull
},
{ attributes: { class: "k-separator" } },
{
attributes: {
"data-value": "top",
"data-property": "verticalAlign",
"data-command": "PropertyChangeCommand"
},
icon: "align-top",
text: MESSAGES.alignmentButtons.alignTop
},
{
attributes: {
"data-value": "center",
"data-property": "verticalAlign",
"data-command": "PropertyChangeCommand"
},
icon: "align-middle",
text: MESSAGES.alignmentButtons.alignMiddle
},
{
attributes: {
"data-value": "bottom",
"data-property": "verticalAlign",
"data-command": "PropertyChangeCommand"
},
icon: "align-bottom",
text: MESSAGES.alignmentButtons.alignBottom
}
],
commandOn: "click"
}
},
backgroundColor: {
type: "component",
name: "backgroundColor",
commandOn: "change",
command: "PropertyChangeCommand",
property: "background",
component: "ColorPicker",
componentOptions: {
view: "palette",
toolIcon: "droplet",
fillMode: "flat",
palette: colorPickerPalette,
clearButton: true,
messages: COLOR_PICKER_MESSAGES,
input: false,
commandOn: "change"
},
overflowComponent: {
type: "button",
dialog: "colorPicker",
icon: "droplet",
property: "background"
}
},
textColor: {
type: "component",
name: "textColor",
commandOn: "change",
command: "PropertyChangeCommand",
property: "color",
component: "ColorPicker",
componentOptions: {
view: "palette",
fillMode: "flat",
toolIcon: "foreground-color",
palette: colorPickerPalette,
clearButton: true,
messages: COLOR_PICKER_MESSAGES,
input: false,
commandOn: "change"
},
overflowComponent: {
type: "button",
dialog: "colorPicker",
icon: "foreground-color",
property: "color"
}
},
fontFamily: {
type: "component",
name: "fontFamily",
command: "PropertyChangeCommand",
property: "fontFamily",
component: "DropDownList",
overflowComponent: {
type: "button",
dialog: "fontFamily",
icon: "font-family"
},
componentOptions: {
dataSource: [
"Arial",
"Courier New",
"Georgia",
"Times New Roman",
"Trebuchet MS",
"Verdana"
],
value: "Arial",
fillMode: "flat",
commandOn: "change"
}
},
fontSize: {
type: "component",
name: "fontSize",
command: "PropertyChangeCommand",
property: "fontSize",
component: "ComboBox",
overflowComponent: {
type: "button",
dialog: "fontSize",
icon: "font-size"
},
componentOptions: {
dataSource: [
8,
9,
10,
11,
12,
13,
14,
16,
18,
20,
22,
24,
26,
28,
36,
48,
72
],
value: 12,
fillMode: "flat",
commandOn: "change"
}
},
increaseFontSize: {
type: "button",
name: "increaseFontSize",
command: "IncreaseFontSize",
property: "fontSize",
icon: "font-grow"
},
decreaseFontSize: {
type: "button",
name: "decreaseFontSize",
command: "DecreaseFontSize",
property: "fontSize",
icon: "font-shrink"
},
format: {
type: "component",
name: "format",
component: "DropDownButton",
element: getDefaultToolElement("custom-format"),
overflowComponent: {
type: "button",
dialog: "formatCells",
icon: "custom-format"
},
componentOptions: {
fillMode: "flat",
items: [
{
attributes: {
"data-value": defaultFormats.automatic,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.automatic
},
{
attributes: {
"data-value": defaultFormats.text,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.text
},
{
attributes: {
"data-value": defaultFormats.number,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.number,
sample: MESSAGES.formatTypesSamples.number
},
{
attributes: {
"data-value": defaultFormats.percent,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.percent,
sample: MESSAGES.formatTypesSamples.percent
},
{
attributes: {
"data-value": defaultFormats.financial,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.financial,
sample: MESSAGES.formatTypesSamples.financial
},
{
attributes: {
"data-value": defaultFormats.currency,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.currency,
sample: MESSAGES.formatTypesSamples.currency
},
{
attributes: {
"data-value": defaultFormats.date,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.date,
sample: MESSAGES.formatTypesSamples.date
},
{
attributes: {
"data-value": defaultFormats.time,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.time,
sample: MESSAGES.formatTypesSamples.time
},
{
attributes: {
"data-value": defaultFormats.dateTime,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.dateTime,
sample: MESSAGES.formatTypesSamples.dateTime
},
{
attributes: {
"data-value": defaultFormats.duration,
"data-command": "PropertyChangeCommand",
"data-property": "format"
},
text: MESSAGES.formatTypes.duration,
sample: MESSAGES.formatTypesSamples.duration
},
{
attributes: {
"data-value": "popup",
"data-popup": "formatCells"
},
text: MESSAGES.formatTypes.moreFormats
}
],
itemTemplate: (data) => {
let $kendoOutput = `<span class="k-link k-menu-link"><span class="k-menu-link-text">`;
if (data.sample) $kendoOutput += `<span class='k-spreadsheet-sample'>${kendo.htmlEncode(data.sample)}</span> `;
$kendoOutput += `${kendo.htmlEncode(data.text)}</span></span>`;
return $kendoOutput;
},
commandOn: "click"
}
},
filter: {
type: "button",
name: "filter",
property: "hasFilter",
icon: "filter",
command: "FilterCommand",
togglable: true,
enable: false
},
merge: {
type: "component",
name: "merge",
component: "DropDownButton",
element: getDefaultToolElement("cells-merge"),
overflowComponent: {
type: "button",
dialog: "merge",
icon: "cells-merge"
},
componentOptions: {
fillMode: "flat",
items: [
{
attributes: {
"data-value": "cells",
"data-command": "MergeCellCommand"
},
icon: "cells-merge",
text: MESSAGES.mergeButtons.mergeCells
},
{
attributes: {
"data-value": "horizontally",
"data-command": "MergeCellCommand"
},
icon: "cells-merge-horizontally",
text: MESSAGES.mergeButtons.mergeHorizontally
},
{
attributes: {
"data-value": "vertically",
"data-command": "MergeCellCommand"
},
icon: "cells-merge-vertically",
text: MESSAGES.mergeButtons.mergeVertically
},
{
attributes: {
"data-value": "unmerge",
"data-command": "MergeCellCommand"
},
icon: "table-unmerge",
text: MESSAGES.mergeButtons.unmerge
}
],
commandOn: "click"
}
},
freeze: {
type: "component",
name: "freeze",
component: "DropDownButton",
element: getDefaultToolElement("pane-freeze"),
overflowComponent: {
type: "button",
dialog: "freeze",
icon: "pane-freeze"
},
componentOptions: {
fillMode: "flat",
items: [
{
attributes: {
"data-value": "panes",
"data-command": "FreezePanesCommand"
},
icon: "pane-freeze",
text: MESSAGES.freezeButtons.freezePanes
},
{
attributes: {
"data-value": "rows",
"data-command": "FreezePanesCommand"
},
icon: "row-freeze",
text: MESSAGES.freezeButtons.freezeRows
},
{
attributes: {
"data-value": "columns",
"data-command": "FreezePanesCommand"
},
icon: "column-freeze",
text: MESSAGES.freezeButtons.freezeColumns
},
{
attributes: {
"data-value": "unfreeze",
"data-command": "FreezePanesCommand"
},
icon: "table-unmerge",
text: MESSAGES.freezeButtons.unfreeze
}
],
commandOn: "click"
}
},
borders: {
type: "popupButton",
name: "borders",
icon: "borders-all",
popupComponent: kendo.spreadsheet.BorderPalette,
commandOn: "change",
command: "BorderChangeCommand",
overflowComponent: {
type: "button",
dialog: "borders"
}
},
formatCells: {
type: "button",
dialog: "formatCells",
overflow: "never"
},
hyperlink: {
type: "button",
name: "hyperlink",
dialog: "hyperlink",
icon: "link"
},
toggleGridlines: {
type: "button",
name: "toggleGridlines",
command: "GridLinesChangeCommand",
property: "gridLines",
value: true,
icon: "borders-none",
togglable: true,
selected: true
},
insertComment: {
type: "button",
name: "insertComment",
dialog: "insertComment",
property: "comment",
togglable: true,
icon: "comment"
},
insertImage: {
type: "button",
name: "insertImage",
dialog: "insertImage",
icon: "image"
},
addColumnLeft: {
type: "button",
name: "addColumnLeft",
command: "AddColumnCommand",
value: "left",
icon: "table-column-insert-left"
},
addColumnRight: {
type: "button",
name: "addColumnRight",
command: "AddColumnCommand",
value: "right",
icon: "table-column-insert-right"
},
addRowBelow: {
type: "button",
name: "addRowBelow",
command: "AddRowCommand",
value: "below",
icon: "table-row-insert-below"
},
addRowAbove: {
type: "button",
name: "addRowAbove",
command: "AddRowCommand",
value: "above",
icon: "table-row-insert-above"
},
deleteColumn: {
type: "button",
name: "deleteColumn",
command: "DeleteColumnCommand",
icon: "table-column-delete"
},
deleteRow: {
type: "button",
name: "deleteRow",
command: "DeleteRowCommand",
icon: "table-row-delete"
},
sort: {
type: "component",
name: "sort",
component: "DropDownButton",
element: getDefaultToolElement("sort-desc"),
overflowComponent: {
type: "button",
dialog: "sort",
icon: "sort-desc"
},
componentOptions: {
fillMode: "flat",
items: [{
attributes: {
"data-value": "asc",
"data-command": "SortCommand"
},
sheet: false,
text: MESSAGES.sortButtons.sortRangeAsc,
icon: "sort-asc"
}, {
attributes: {
"data-value": "desc",
"data-command": "SortCommand"
},
sheet: false,
text: MESSAGES.sortButtons.sortRangeDesc,
icon: "sort-desc"
}],
commandOn: "click"
}
},
validation: {
type: "button",
name: "validation",
dialog: "validation",
icon: "exclamation-circle"
}
};
}
var SpreadsheetToolBar = ToolBar.extend({
init: function(element, options) {
let toolDefaults = getToolDefaults();
Object.keys(toolDefaults).forEach((t) => {
if (t !== "validation") toolDefaults[t].showText = "overflow";
});
options.tools = options.tools || SpreadsheetToolBar.prototype.options.tools[options.toolbarName];
options.parentMessages = MESSAGES;
options.defaultTools = toolDefaults;
ToolBar.fn.init.call(this, element, options);
var handleClick = this._click.bind(this);
this.element.addClass("k-spreadsheet-toolbar");
this.bind({
click: handleClick,
toggle: handleClick,
change: handleClick
});
ToolBar.fn.endInit.call(this);
},
_click: function(e) {
var target = e.target, property = target.data("property"), value = e.value || target.data("value") || e.target.val(), commandType = target.data("command"), dialog = target.data("dialog"), options = target.data("options") || {};
if (value === "popup") dialog = target.data("popup");
if (commandType === "IncreaseFontSize") {
commandType = "PropertyChangeCommand";
value++;
}
if (commandType === "DecreaseFontSize") {
commandType = "PropertyChangeCommand";
value--;
}
options.property = property || null;
options.value = value || null;
if (dialog) {
this.dialog({
name: dialog,
options
});
return;
}
if (!commandType) return;
var args = {
command: commandType,
options
};
if (typeof args.options.value === "boolean") args.options.value = e.checked ? true : null;
this.action(args);
},
events: ["action", "dialog"],
options: {
name: "SpreadsheetToolBar",
resizable: true,
tools: defaultTools,
fillMode: "flat"
},
action: function(args) {
this.trigger("action", args);
},
dialog: function(args) {
this.trigger("dialog", args);
},
refresh: function(activeCell) {
var range = activeCell, tools = this._tools();
for (var i = 0; i < tools.length; i++) {
var property = tools[i].property, tool = tools[i].tool, value = kendo.isFunction(range[property]) ? range[property]() : range;
if (property == "gridLines") value = range.sheet().showGridLines();
this._updateTool(tool, value, property, range);
}
this.resize(true);
},
_tools: function() {
return this.element.find("[data-property]").toArray().map(function(element) {
element = $(element);
return {
property: element.attr("data-property"),
tool: this._getItem(element)
};
}.bind(this));
},
_updateTool: function(tool, value, property, range) {
var component = tool.component, toolbarEl = tool.toolbarEl, widget = kendo.widgetInstance(toolbarEl.find("[data-role]")), menuItem = tool.menuItem, toggle = false, vertical, text, menu, selection, enabled, label;
if (property === "hasFilter") {
selection = range.sheet().selection();
if (selection && selection._ref && selection._ref.height) {
enabled = value || selection._ref.height() > 1;
this.enable(toolbarEl, enabled);
}
} else if (property === "alignment") {
vertical = value.verticalAlign();
text = value.textAlign();
menu = component.menu.element;
menu.find(".k-item .k-link").removeClass("k-selected");
menu.find(".k-item[data-property=textAlign][data-value=" + text + "] .k-link").addClass("k-selected");
menu.find(".k-item[data-property=verticalAlign][data-value=" + vertical + "] .k-link").addClass("k-selected");
} else if (property === "background" || property === "color") widget.value(value);
else if (property === "fontFamily" || property === "fontSize") {
if (toolbarEl.is("button")) {
toolbarEl.attr("data-value", value);
toolbarEl.data("value", value);
return;
}
label = menuItem.find(".k-menu-link-text").text().split("(")[0].trim();
menuItem.find(".k-menu-link-text").text(label + " (" + value + ") ...");
widget.value(value);
}
if (component && component.toggle) {
if (typeof value === "boolean") toggle = !!value;
else if (typeof value === "string") if (toolbarEl.data("value")) toggle = toolbarEl.data("value") === value;
else toggle = value != null;
this.toggle(toolbarEl, toggle);
}
}
});
kendo.cssProperties.propertyDictionary["SpreadsheetToolBar"] = kendo.cssProperties.propertyDictionary["ToolBar"];
kendo.spreadsheet.ToolBar = SpreadsheetToolBar;
kendo.spreadsheet.Menu = kendo.ui.Menu;
})(window.kendo);
//#endregion
//#region ../src/spreadsheet/print.js
function clone(hash, target) {
if (!target) target = {};
if (Object.assign) return Object.assign(target, hash);
return Object.keys(hash).reduce(function(copy, key) {
copy[key] = hash[key];
return copy;
}, target);
}
function drawTabularData(options) {
var progress = new $.Deferred();
var promise = progress.promise();
options = clone(options, {
dataSource: null,
guidelines: true,
guideColor: "#000",
columns: null,
headerBackground: "#999",
headerColor: "#000",
oddBackground: null,
evenBackground: null,
fontFamily: "Arial",
fontSize: 12,
paperSize: "A4",
margin: "1cm",
landscape: true,
fitWidth: false,
scale: 1,
rowHeight: 20,
maxEmpty: 1,
useGridFormat: true
});
kendo.drawing.pdf.defineFont(kendo.drawing.drawDOM.getFontFaces(document));
var charWidth = charWidthFunction(options.fontFamily, options.fontSize);
function textWidth(value) {
if (value != null) {
var width = 12;
for (var i = value.length; --i >= 0;) width += charWidth(value.charAt(i));
return width;
}
return 0;
}
var border = options.guidelines ? {
size: 1,
color: options.guideColor
} : null;
function mkCell(data) {
if (!border) return data;
return clone(data, {
borderLeft: border,
borderTop: border,
borderRight: border,
borderBottom: border
});
}
options.dataSource.fetch(function() {
var data = options.dataSource.data();
if (!data.length) return progress.reject("Empty dataset");
var columns = options.columns.map(function(col) {
if (typeof col == "string") return {
title: col,
field: col
};
else return col;
});
var columnTitles = columns.map(function(col) {
return col.title || col.field;
});
var columnWidths = columnTitles.map(textWidth);
var rows = data.map(function(row, rowIndex) {
return { cells: columns.map(function(col, colIndex) {
var value = row[col.field];
if (options.useGridFormat) {
if (value != null) if (col.format) value = kendo.format(col.format, value);
else value += "";
columnWidths[colIndex] = Math.max(textWidth(value), columnWidths[colIndex]);
}
return mkCell({
value,
format: options.useGridFormat ? null : col.format,
background: rowIndex % 2 ? options.evenBackground : options.oddBackground
});
}) };
});
rows.unshift({ cells: columnTitles.map(function(label) {
return mkCell({
value: label,
background: options.headerBackground,
color: options.headerColor
});
}) });
var sheet = new kendo.spreadsheet.Sheet(rows.length + 1, columns.length + 1, options.rowHeight, 50, 20, 20, {
fontFamily: options.fontFamily,
fontSize: options.fontSize,
verticalAlign: "center"
});
sheet.fromJSON({
name: "Sheet1",
rows,
columns: columnWidths.map(function(w, i) {
return {
index: i,
width: w
};
})
});
sheet.draw({
paperSize: options.paperSize,
landscape: options.landscape,
margin: options.margin,
guidelines: false,
scale: options.scale,
fitWidth: options.fitWidth,
maxEmpty: options.maxEmpty,
headerRows: 1
}, progress.resolve.bind(progress));
});
return promise;
}
var CACHE_CHAR_WIDTH = {};
var charWidthFunction = function(fontFamily, fontSize) {
var id = fontSize + ":" + fontFamily;
var func = CACHE_CHAR_WIDTH[id];
if (!func) {
var span, div = document.createElement("div");
div.style.position = "fixed";
div.style.left = "-10000px";
div.style.top = "-10000px";
div.style.fontFamily = fontFamily;
div.style.fontSize = fontSize + "px";
div.style.whiteSpace = "pre";
for (var i = 32; i < 128; ++i) {
span = document.createElement("span");
span.appendChild(document.createTextNode(String.fromCharCode(i)));
div.appendChild(span);
}
document.body.appendChild(div);
var widths = {};
for (i = 32, span = div.firstChild; i < 128 && span; ++i, span = span.nextSibling) widths[i] = span.offsetWidth;
while (span = div.firstChild) div.removeChild(span);
func = CACHE_CHAR_WIDTH[id] = function(ch) {
var code = ch.charCodeAt(0);
var width = widths[code];
if (width == null) {
span = document.createElement("span");
span.appendChild(document.createTextNode(String.fromCharCode(code)));
div.appendChild(span);
width = widths[code] = span.offsetWidth;
div.removeChild(span);
}
return width;
};
}
return func;
};
kendo.spreadsheet.drawTabularData = drawTabularData;
//#endregion
//#region ../src/spreadsheet/customeditors.js
(function(kendo) {
"use strict";
let registerEditor = kendo.spreadsheet.registerEditor;
var $ = kendo.jQuery;
registerEditor("_validation_date", function() {
var context, calendar, popup;
function create() {
if (!calendar) {
calendar = $("<div>").kendoCalendar();
popup = $("<div>").kendoPopup();
calendar.appendTo(popup);
calendar = calendar.getKendoCalendar();
popup = popup.getKendoPopup();
calendar.bind("change", function() {
popup.close();
var date = calendar.value();
if (!context.range.format()) context.range.format("yyyy-mm-dd");
context.callback(kendo.spreadsheet.dateToNumber(date));
});
}
popup.setOptions({
anchor: context.view.element.querySelector(".k-spreadsheet-editor-button"),
origin: context.alignLeft ? "bottom right" : "bottom left",
position: context.alignLeft ? "top right" : "top left"
});
}
function open() {
create();
var date = context.range.value();
var sheet = context.range.sheet();
if (date != null) calendar.value(kendo.spreadsheet.numberToDate(date));
else calendar.value(null);
var val = context.validation;
if (val) {
var min = kendo.ui.Calendar.fn.options.min;
var max = kendo.ui.Calendar.fn.options.max;
var fromValidation = val.from;
var toValidation = val.to;
var formula = kendo.spreadsheet.calc.runtime.Formula;
if (/^(?:greaterThan|between)/.test(val.comparerType)) if (fromValidation instanceof formula && _rowAndColPresent(fromValidation.value)) min = kendo.spreadsheet.numberToDate(sheet.range(fromValidation.value.row, fromValidation.value.col).value());
else min = kendo.spreadsheet.numberToDate(fromValidation.value);
if (val.comparerType == "between") if (toValidation instanceof formula && _rowAndColPresent(toValidation.value)) max = kendo.spreadsheet.numberToDate(sheet.range(toValidation.value.row, toValidation.value.col).value());
else max = kendo.spreadsheet.numberToDate(val.to.value);
if (val.comparerType == "lessThan" || val.comparerType == "lessThanOrEqualTo") if (fromValidation instanceof formula && _rowAndColPresent(fromValidation.value)) max = kendo.spreadsheet.numberToDate(sheet.range(fromValidation.value.row, fromValidation.value.col).value());
else max = kendo.spreadsheet.numberToDate(val.from.value);
calendar.setOptions({
disableDates: function(date) {
var from, to;
if (fromValidation && fromValidation instanceof formula && _rowAndColPresent(fromValidation.value)) from = sheet.range(fromValidation.value.row, fromValidation.value.col).value();
else from = fromValidation ? fromValidation.value | 0 : 0;
if (toValidation && toValidation instanceof formula && _rowAndColPresent(toValidation.value)) to = sheet.range(toValidation.value.row, toValidation.value.col).value();
else to = toValidation ? toValidation.value | 0 : 0;
date = kendo.spreadsheet.dateToNumber(date) | 0;
return !kendo.spreadsheet.validation.validationComparers[val.comparerType](date, from, to);
},
min,
max
});
} else calendar.setOptions({
disableDates: null,
min: null,
max: null
});
popup.open();
}
function _rowAndColPresent(value) {
return value && value.row !== null && value.col !== null && value.row > -1 && value.col > -1;
}
return {
edit: function(options) {
context = options;
open();
},
icon: "calendar"
};
});
registerEditor("_validation_list", function() {
var context, list, popup;
function normalizeValue(value) {
if (typeof value === "string" && /^'/.test(value)) return value.substring(1);
return value;
}
function create() {
if (!list) {
list = $("<ul class='k-list k-reset'/>").kendoStaticList({
template: function(data) {
return data.text;
},
selectable: true,
autoBind: false
});
popup = $("<div class='k-spreadsheet-list-popup'>").kendoPopup();
list.appendTo(popup);
popup = popup.getKendoPopup();
list = list.getKendoStaticList();
list.bind("change", function() {
popup.close();
var item = list.value()[0];
if (item) context.callback(item.value);
});
}
popup.setOptions({
anchor: context.view.element.querySelector(".k-spreadsheet-editor-button"),
origin: context.alignLeft ? "bottom right" : "bottom left",
position: context.alignLeft ? "top right" : "top left"
});
}
function open() {
create();
var items = context.validation.from.value;
var data = [], add = function(el) {
data.push({
text: normalizeValue(el),
value: el
});
};
if (items instanceof kendo.spreadsheet.calc.runtime.Matrix) items.each(add);
else (items + "").split(/\s*,\s*/).forEach(add);
var dataSource = new kendo.data.DataSource({ data });
list.setDataSource(dataSource);
dataSource.read();
popup.open();
}
return {
edit: function(options) {
context = options;
open();
},
icon: "chevron-down"
};
});
})(window.kendo);
//#endregion
//#region ../src/spreadsheet/sheetsbar.js
(function(kendo) {
var $ = kendo.jQuery;
var outerWidth = kendo._outerWidth;
var DOT = ".";
var EMPTYCHAR = " ";
function getSheetBarMessages() {
var spreadsheetMessages = kendo.spreadsheet.messages;
var viewMessages = spreadsheetMessages.view || {};
var menuMessages = spreadsheetMessages.menus || {};
var renameMessages = ((spreadsheetMessages.dialogs || {}).sheetRenameDialog || {}).labels || {};
var sheetBarMessages = viewMessages.sheetBar || {};
return {
addSheet: sheetBarMessages.addSheet || "Add new sheet",
deleteSheet: sheetBarMessages.deleteSheet || menuMessages.delete || "Delete",
duplicateSheet: sheetBarMessages.duplicateSheet || "Duplicate",
renameSheet: sheetBarMessages.renameSheet || renameMessages.rename || "Rename",
hideSheet: sheetBarMessages.hideSheet || menuMessages.hide || "Hide",
moveRight: sheetBarMessages.moveRight || "Move Right",
moveLeft: sheetBarMessages.moveLeft || "Move Left"
};
}
var sheetsBarClassNames = {
sheetsBarWrapper: "k-spreadsheet-sheets-bar",
sheetsBarSheetsWrapper: "k-tabstrip k-tabstrip-bottom",
sheetsBarAdd: "k-spreadsheet-sheet-add",
sheetsBarSheetsMenu: "k-spreadsheet-sheets-menu",
sheetsBarRemove: "k-spreadsheet-sheets-remove",
sheetsBarItems: "k-spreadsheet-sheets",
sheetsBarEditor: "k-spreadsheet-sheets-editor",
sheetsBarScrollable: "k-tabstrip-scrollable",
sheetsBarNext: "k-tabstrip-next",
sheetsBarPrev: "k-tabstrip-prev",
sheetsBarKItem: "k-item",
sheetsBarKTabstripItem: "k-tabstrip-item",
sheetsBarKActive: "k-active",
sheetsBarKTextbox: "k-textbox",
sheetsBarKLink: "k-link",
sheetsBarKLinkText: "k-link-text",
sheetsBarKIcon: "k-icon",
sheetsBarKFontIcon: "k-icon",
sheetsBarKButton: "k-button k-button-sm k-icon-button",
sheetsBarKButtonDefaults: "",
sheetsBarKButtonBare: "k-button-flat",
sheetsBarArrowWIcon: "chevron-left",
sheetsBarArrowEIcon: "chevron-right",
sheetsBarKReset: "k-reset k-tabstrip-items k-tabstrip-items-start",
sheetsBarXIcon: "x",
sheetsBarMoreIcon: "chevron-down",
sheetsBarKSprite: "k-sprite",
sheetsBarPlusIcon: "plus",
sheetsBarMenuIcon: "menu",
sheetsBarHintWrapper: "k-tabstrip k-tabstrip-bottom k-spreadsheet-sheets-items-hint",
sheetsBarKResetItems: "k-reset k-tabstrip-items k-tabstrip-items-start"
};
var SheetsBar = kendo.ui.Widget.extend({
init: function(element, options) {
var classNames = SheetsBar.classNames;
kendo.ui.Widget.call(this, element, options);
element = this.element;
element.addClass(classNames.sheetsBarWrapper);
this._openDialog = options.openDialog;
this._addButton();
this._menuButton();
this._tree = new kendo.dom.Tree(element[0]);
this._tree.render([this._createSheetsWrapper([])]);
this._initSheetDropDownButtons();
this._toggleScrollEvents(true);
this._createSortable();
this._sortable.bind("start", this._onSheetReorderStart.bind(this));
this._sortable.bind("end", this._onSheetReorderEnd.bind(this));
element.on("click", "[ref-sheetsbar-more-button]", this._onSheetContextMenu.bind(this));
element.on("click", "li", this._onSheetSelect.bind(this));
element.on("dblclick", "li" + DOT + classNames.sheetsBarKItem + DOT + classNames.sheetsBarKItem, this._createEditor.bind(this));
},
options: {
name: "SheetsBar",
scrollable: { distance: 200 }
},
events: [
"select",
"reorder",
"rename"
],
_createEditor: function() {
if (this._editor) return;
this._renderSheets(this._sheets, this._selectedIndex, true);
this._editor = this.element.find(kendo.format("input{0}{1}", DOT, SheetsBar.classNames.sheetsBarEditor)).trigger("focus").on("keydown", this._onEditorKeydown.bind(this)).on("blur", this._onEditorBlur.bind(this));
},
_destroyEditor: function(canceled) {
var newSheetName = canceled ? null : this._editor.val();
this._editor.off();
this._editor = null;
this._renderSheets(this._sheets, this._selectedIndex, false);
this._onSheetRename(newSheetName);
},
renderSheets: function(sheets, selectedIndex) {
if (!sheets || selectedIndex < 0) return;
this._renderSheets(sheets, selectedIndex, false);
},
_renderSheets: function(sheets, selectedIndex, isInEditMode) {
var that = this;
var classNames = SheetsBar.classNames;
that._isRtl = kendo.support.isRtl(that.element);
that._sheets = sheets;
that._selectedIndex = selectedIndex;
that._renderHtml(isInEditMode, true);
if (!that._scrollableAllowed()) return;
that._sheetsWrapper().addClass(classNames.sheetsBarScrollable + EMPTYCHAR + classNames.sheetsBarSheetsWrapper);
that._toggleScrollButtons();
},
_toggleScrollButtons: function(toggle) {
var that = this;
var ul = that._sheetsGroup();
var wrapper = that._sheetsWrapper();
var scrollLeft = kendo.scrollLeft(ul);
var prev = wrapper.find(DOT + SheetsBar.classNames.sheetsBarPrev);
var next = wrapper.find(DOT + SheetsBar.classNames.sheetsBarNext);
if (toggle === false) {
prev.addClass("k-disabled");
next.addClass("k-disabled");
} else {
prev.toggleClass("k-disabled", !(that._isRtl ? scrollLeft < ul[0].scrollWidth - ul[0].offsetWidth - 1 : scrollLeft !== 0));
next.toggleClass("k-disabled", !(that._isRtl ? scrollLeft !== 0 : scrollLeft < ul[0].scrollWidth - ul[0].offsetWidth - 1));
}
},
_toggleScrollEvents: function(toggle) {
var that = this;
var classNames = SheetsBar.classNames;
var options = that.options;
var scrollPrevButton;
var scrollNextButton;
var sheetsWrapper = that._sheetsWrapper();
scrollPrevButton = sheetsWrapper.find(DOT + classNames.sheetsBarPrev);
scrollNextButton = sheetsWrapper.find(DOT + classNames.sheetsBarNext);
if (toggle) {
scrollPrevButton.on("mousedown", function(event) {
event.preventDefault();
event.stopPropagation();
that._nowScrollingSheets = true;
that._scrollSheetsByDelta(options.scrollable.distance * (that._isRtl ? 1 : -1));
});
scrollNextButton.on("mousedown", function(event) {
event.preventDefault();
event.stopPropagation();
that._nowScrollingSheets = true;
that._scrollSheetsByDelta(options.scrollable.distance * (that._isRtl ? -1 : 1));
});
scrollPrevButton.add(scrollNextButton).on("mouseup", function() {
that._nowScrollingSheets = false;
});
} else {
scrollPrevButton.off();
scrollNextButton.off();
}
},
_renderHtml: function(isInEditMode, renderScrollButtons) {
var idx;
var sheetElements = [];
var dom = kendo.dom;
var element = dom.element;
var sheets = this._sheets;
var selectedIndex = this._selectedIndex;
var classNames = SheetsBar.classNames;
for (idx = 0; idx < sheets.length; idx++) {
var sheet = sheets[idx];
var isSelectedSheet = idx === selectedIndex;
var attr = {
className: classNames.sheetsBarKItem + EMPTYCHAR + classNames.sheetsBarKTabstripItem + EMPTYCHAR,
role: "tab"
};
var elementContent = [];
if (sheet.state() !== "visible") attr.className += "k-hidden ";
if (isSelectedSheet) attr.className += classNames.sheetsBarKActive;
if (isSelectedSheet && isInEditMode) elementContent.push(element("input", {
type: "text",
value: sheet.name(),
className: classNames.sheetsBarKTextbox + EMPTYCHAR + classNames.sheetsBarEditor,
maxlength: 50
}, []));
else {
elementContent.push(element("span", {
className: classNames.sheetsBarKLink,
title: sheet.name()
}, [element("span", { className: classNames.sheetsBarKLinkText }, [dom.text(sheet.name())])]));
let contextMenuButton = element($(kendo.html.renderButton($(`<button ref-sheetsbar-more-button data-sheet-name="${sheet.name()}" class="k-menu-button"></button>`), {
icon: classNames.sheetsBarMoreIcon,
fillMode: "flat",
size: "small"
}))[0]);
elementContent.push(element("span", {
className: "k-item-actions",
"data-type": "context-menu"
}, [contextMenuButton]));
}
sheetElements.push(element("li", attr, elementContent));
}
kendo.destroy(this._sheetsWrapper());
this._addButton();
this._menuButton();
this._tree.render([this._createSheetsWrapper(sheetElements, renderScrollButtons)]);
this._initSheetDropDownButtons();
},
_initSheetDropDownButtons: function() {
let that = this;
let messages = getSheetBarMessages();
this.element.find("[ref-sheetsbar-more-button]").each(function(ind, btnEl) {
let el = $(btnEl);
let allSheets = that._sheets || [];
let visibleSheets = allSheets.filter((sheet) => sheet.state() === "visible");
let isSingleVisibleSheet = !that._sheets || that._sheets && visibleSheets.length < 2;
let sheetName = el.data("sheetName");
let shouldAllowMoveRight = !(isSingleVisibleSheet || that._sheets && ind == allSheets.length - 1);
let shouldAllowMoveLeft = !(isSingleVisibleSheet || that._sheets && ind === 0);
el.kendoDropDownButton({
icon: SheetsBar.classNames.sheetsBarMoreIcon,
fillMode: "flat",
size: "small",
items: [
{
text: messages.deleteSheet,
icon: "trash",
attributes: {
"data-command": "delete",
"data-sheet-name": sheetName
},
enabled: !isSingleVisibleSheet
},
{
text: messages.duplicateSheet,
icon: "copy",
attributes: {
"data-command": "duplicate",
"data-sheet-name": sheetName
}
},
{
text: messages.renameSheet,
icon: "pencil",
attributes: {
"data-command": "rename",
"data-sheet-name": sheetName
}
},
{
text: messages.hideSheet,
icon: "eye-slash",
attributes: {
"data-command": "hide",
"data-sheet-name": sheetName
},
enabled: !isSingleVisibleSheet
},
{
text: messages.moveRight,
icon: "arrow-right",
attributes: {
"data-command": "move-right",
"data-sheet-name": sheetName
},
enabled: shouldAllowMoveRight
},
{
text: messages.moveLeft,
icon: "arrow-left",
attributes: {
"data-command": "move-left",
"data-sheet-name": sheetName
},
enabled: shouldAllowMoveLeft
}
],
click: that._onSheetContextMenu.bind(that)
});
});
},
_createSheetsWrapper: function(sheetElements, renderScrollButtons) {
var element = kendo.dom.element;
var classNames = SheetsBar.classNames;
var itemsWrapper = element("div", { className: "k-tabstrip-items-wrapper k-hstack" });
var childrenElements = [
element("ul", {
className: classNames.sheetsBarKReset,
role: "tablist"
}, sheetElements),
null,
null
];
renderScrollButtons = true;
if (renderScrollButtons) {
var baseButtonClass = classNames.sheetsBarKButton + EMPTYCHAR + classNames.sheetsBarKButtonBare + EMPTYCHAR;
childrenElements[1] = element("span", {
ariaHidden: "true",
tabIndex: -1,
className: baseButtonClass + classNames.sheetsBarPrev
}, [element($(kendo.ui.icon({
icon: classNames.sheetsBarArrowWIcon,
iconClass: "k-button-icon"
}))[0])]);
childrenElements[2] = element("span", {
ariaHidden: "true",
tabIndex: -1,
className: baseButtonClass + classNames.sheetsBarNext
}, [element($(kendo.ui.icon({
icon: classNames.sheetsBarArrowEIcon,
iconClass: "k-button-icon"
}))[0])]);
}
itemsWrapper.children = childrenElements;
return element("div", { className: classNames.sheetsBarItems }, [itemsWrapper]);
},
_createSortable: function() {
var classNames = SheetsBar.classNames;
this._sortable = new kendo.ui.Sortable(this.element, {
filter: `ul li.${classNames.sheetsBarKItem}`,
container: DOT + classNames.sheetsBarItems,
axis: "x",
animation: false,
ignore: "input",
end: function() {
if (this.draggable.hint) this.draggable.hint.remove();
},
hint: function(element) {
return $(element).clone().attr("ref-sheetsbar-sortable-hint", "").wrap("<div class='" + classNames.sheetsBarHintWrapper + "'><ul class='" + classNames.sheetsBarKResetItems + "'></ul></div>").closest("div");
}
});
},
_onEditorKeydown: function(e) {
if (this._editor) {
if (e.which === 13) this._destroyEditor();
if (e.which === 27) this._destroyEditor(true);
}
},
_onEditorBlur: function() {
if (this._editor) this._destroyEditor();
},
_onSheetReorderEnd: function(e) {
e.preventDefault();
this.trigger("reorder", {
oldIndex: e.oldIndex,
newIndex: e.newIndex
});
},
_onSheetReorderStart: function(e) {
if (this._editor) e.preventDefault();
},
_onSheetContextMenu: function(e) {
let sheetName = $(e.target).closest("li").data("sheetName");
let command = $(e.target).closest("li").data("command");
if (this._editor) this._destroyEditor();
if (sheetName && command) switch (command) {
case "delete":
this._onSheetRemove(e);
break;
case "duplicate":
this._onSheetDuplicate(sheetName);
break;
case "rename":
this._renamePrompt(sheetName);
break;
case "hide":
this._hideSheet(sheetName);
break;
case "move-right":
this._moveSheet(sheetName, 1);
break;
case "move-left":
this._moveSheet(sheetName, -1);
break;
}
},
_onSheetDuplicate: function(sheetName) {
this.trigger("duplicate", { name: sheetName });
},
_renamePrompt: function(sheetName) {
let renameSheetIndex = this._sheets.findIndex((sh) => sh.name() == sheetName);
let closeCallback = function(e) {
let dlg = e.sender;
if (dlg._newSheetName && dlg._newSheetName !== sheetName) this.trigger("rename", {
name: dlg._newSheetName,
sheetIndex: renameSheetIndex
});
}.bind(this);
this._openDialog("renameSheet", {
close: closeCallback,
_oldSheetName: sheetName
});
},
_hideSheet: function(sheetName) {
this.trigger("hide", { name: sheetName });
},
_moveSheet: function(sheetName, direction) {
let sheetIndex = this._sheets.findIndex((sheet) => sheet.name() === sheetName);
let newSheetIndex = sheetIndex + direction;
if (newSheetIndex < 0 || newSheetIndex >= this._sheets.length) return;
this.trigger("reorder", {
oldIndex: sheetIndex,
newIndex: newSheetIndex
});
},
_onSheetRemove: function(e) {
var removedSheetName = $(e.target).closest("li").data("sheetName");
if (this._editor) this._destroyEditor();
var closeCallback = function(e) {
if (e.sender.isConfirmed()) this.trigger("remove", {
name: removedSheetName,
confirmation: true
});
}.bind(this);
this._openDialog("confirmation", { close: closeCallback });
},
_onSheetSelect: function(e) {
var selectedSheetText = $(e.target).text();
if ($(e.target).is(DOT + SheetsBar.classNames.sheetsBarEditor) || !selectedSheetText) {
e.preventDefault();
return;
}
if (this._editor) this._destroyEditor();
this._scrollSheetsToItem($(e.target).closest("li"));
this.trigger("select", {
name: selectedSheetText,
isAddButton: false
});
},
_onSheetRename: function(newSheetName) {
if (this._sheets[this._selectedIndex].name() === newSheetName || newSheetName === null) return;
this.trigger("rename", {
name: newSheetName,
sheetIndex: this._selectedIndex
});
},
_onAddSelect: function(ev) {
ev.sender.element.removeClass("k-focus");
this.trigger("select", { isAddButton: true });
},
_onMenuSelect: function(ev) {
let sheetName = $(ev.target).closest("li").data("sheetName");
if (sheetName) this.trigger("show", { name: sheetName });
},
_addButton: function() {
var classNames = SheetsBar.classNames;
var messages = getSheetBarMessages();
let addButton = this.element.find("." + classNames.sheetsBarAdd);
if (!addButton.length) addButton = $(`<button class="${classNames.sheetsBarAdd}"></button>`).appendTo(this.element);
else kendo.destroy(addButton);
addButton.attr("aria-label", messages.addSheet);
addButton.kendoButton({
icon: classNames.sheetsBarPlusIcon,
fillMode: "flat",
size: "small",
click: this._onAddSelect.bind(this)
});
},
_menuButton: function() {
var classNames = SheetsBar.classNames;
let menuButton = this.element.find("." + classNames.sheetsBarSheetsMenu);
if (!menuButton.length) menuButton = $(`<button class="${classNames.sheetsBarSheetsMenu}"></button>`).appendTo(this.element);
else kendo.destroy(menuButton);
menuButton.kendoDropDownButton({
icon: classNames.sheetsBarMenuIcon,
fillMode: "flat",
size: "small",
items: (this._sheets || []).map((sheet) => ({
text: sheet.name(),
attributes: { "data-sheet-name": sheet.name() },
icon: sheet.state() === "visible" ? "eye" : "eye-slash",
cssClass: classNames
})),
click: this._onMenuSelect.bind(this)
});
},
destroy: function() {
this._sortable.destroy();
},
_scrollableAllowed: function() {
var options = this.options;
return options.scrollable && !isNaN(options.scrollable.distance);
},
_scrollSheetsToItem: function(item) {
var that = this;
var sheetsGroup = that._sheetsGroup();
var currentScrollOffset = kendo.scrollLeft(sheetsGroup);
var itemWidth = outerWidth(item);
var itemOffset = that._isRtl ? item.position().left : item.position().left - sheetsGroup.children().first().position().left;
var sheetsGroupWidth = sheetsGroup[0].offsetWidth;
var itemPosition;
if (that._isRtl) {
if (itemOffset < 0) itemPosition = currentScrollOffset + itemOffset - (sheetsGroupWidth - currentScrollOffset);
else if (itemOffset + itemWidth > sheetsGroupWidth) itemPosition = currentScrollOffset + itemOffset - itemWidth;
} else if (currentScrollOffset + sheetsGroupWidth < itemOffset + itemWidth) itemPosition = itemOffset + itemWidth - sheetsGroupWidth;
else if (currentScrollOffset > itemOffset) itemPosition = itemOffset;
sheetsGroup.finish().animate({ "scrollLeft": itemPosition }, "fast", "linear", function() {
that._toggleScrollButtons();
});
},
_sheetsGroup: function() {
return this._sheetsWrapper().find("ul");
},
_sheetsWrapper: function() {
return this.element.find(DOT + SheetsBar.classNames.sheetsBarItems);
},
_scrollSheetsByDelta: function(delta) {
var that = this;
var sheetsGroup = that._sheetsGroup();
var scrLeft = kendo.scrollLeft(sheetsGroup);
sheetsGroup.finish().animate({ "scrollLeft": scrLeft + delta }, "fast", "linear", function() {
if (that._nowScrollingSheets) that._scrollSheetsByDelta(delta);
else that._toggleScrollButtons();
});
}
});
kendo.spreadsheet.SheetsBar = SheetsBar;
$.extend(true, SheetsBar, { classNames: sheetsBarClassNames });
})(window.kendo);
//#endregion
//#region ../src/spreadsheet/filtermenu.js
(function(kendo) {
var $ = kendo.jQuery;
var Widget = kendo.ui.Widget;
var classNames = {
details: "k-details",
button: "k-button",
detailsSummary: "k-details-summary",
detailsContent: "k-details-content",
icon: "k-icon",
iconCollapseName: "caret-br",
iconExpandName: "chevron-right",
iconSearchName: "search",
textbox: "k-textbox",
wrapper: "k-spreadsheet-filter-menu",
filterByCondition: "k-spreadsheet-condition-filter",
filterByValue: "k-spreadsheet-value-filter",
valuesTreeViewWrapper: "k-spreadsheet-value-treeview-wrapper",
actionButtons: "k-actions"
};
kendo.spreadsheet.messages.filterMenu = {
all: "All",
sortAscending: "Sort range A to Z",
sortDescending: "Sort range Z to A",
filterByValue: "Filter by value",
filterByCondition: "Filter by condition",
apply: "Apply",
search: "Search",
addToCurrent: "Add to current selection",
clear: "Clear",
blanks: "(Blanks)",
operatorNone: "None",
and: "AND",
or: "OR",
operators: {
string: {
contains: "Text contains",
doesnotcontain: "Text does not contain",
startswith: "Text starts with",
endswith: "Text ends with",
matches: "Text matches",
doesnotmatch: "Text does not match"
},
date: {
eq: "Date is",
neq: "Date is not",
lt: "Date is before",
gt: "Date is after"
},
number: {
eq: "Is equal to",
neq: "Is not equal to",
gte: "Is greater than or equal to",
gt: "Is greater than",
lte: "Is less than or equal to",
lt: "Is less than"
}
}
};
var Details = Widget.extend({
init: function(element, options) {
Widget.fn.init.call(this, element, options);
this.element.addClass(FilterMenu.classNames.details);
this._summary = this.element.find("." + FilterMenu.classNames.detailsSummary).on("click", this._toggle.bind(this));
var iconName = options.expanded ? FilterMenu.classNames.iconCollapseName : FilterMenu.classNames.iconExpandName;
this._icon = $(kendo.ui.icon(iconName)).prependTo(this._summary);
this._container = kendo.wrap(this._summary.next(), true);
if (!options.expanded) this._container.hide();
Widget.fn.endInit.call(this);
},
options: { name: "Details" },
events: ["toggle"],
visible: function() {
return this.options.expanded;
},
toggle: function(show) {
kendo.fx(this._container).expand("vertical").stop()[show ? "reverse" : "play"]();
kendo.ui.icon(this._icon, { icon: show ? FilterMenu.classNames.iconExpandName : FilterMenu.classNames.iconCollapseName });
this.options.expanded = !show;
},
_toggle: function() {
var show = this.visible();
this.toggle(show);
this.trigger("toggle", { show });
}
});
kendo.data.binders.spreadsheetFilterValue = kendo.data.Binder.extend({
init: function(element, bindings, options) {
kendo.data.Binder.fn.init.call(this, element, bindings, options);
this._change = this.change.bind(this);
$(this.element).on("change", this._change);
},
refresh: function() {
var that = this, value = that.bindings.spreadsheetFilterValue.get();
$(that.element).val(value instanceof Date ? "" : value);
},
change: function() {
var value = this.element.value;
this.bindings.spreadsheetFilterValue.set(value);
}
});
kendo.data.binders.widget.spreadsheetFilterValue = kendo.data.Binder.extend({
init: function(widget, bindings, options) {
kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);
this.widget = widget;
this._change = this.change.bind(this);
this.widget.first("change", this._change);
},
refresh: function() {
var value = this.bindings.spreadsheetFilterValue.get(), type = $(this.widget.element).data("filterType");
if (type === "date" && value instanceof Date || type === "number" && !isNaN(value)) this.widget.value(value);
else this.widget.value(null);
},
change: function() {
var value = this.widget.value();
this.bindings.spreadsheetFilterValue.set(value);
}
});
var templates = {
filterByValue: (data) => `<div class='${classNames.detailsSummary}'>${data.messages.filterByValue}</div><div class='${classNames.detailsContent}'><div class='k-searchbox k-input'>` + kendo.ui.icon({
icon: "search",
iconClass: "k-input-icon"
}) + `<input class='k-input-inner' autocomplete='off' placeholder='${data.messages.search}' data-${data.ns}bind='events: { input: filterValues }' /></div><div data-${data.ns}bind='visible: hasActiveSearch'><input class='k-checkbox' type='checkbox' data-${data.ns}bind='checked: appendToSearch' id='_${data.guid}'/><label class='k-checkbox-label' for='_${data.guid}'>${data.messages.addToCurrent}</label></div><div class='${classNames.valuesTreeViewWrapper}'><div data-${data.ns}role='treeview' bind:data-${data.ns}checkboxes='checkboxesConfig' data-${data.ns}bind='source: valuesDataSource, events: { check: valuesChange, select: valueSelect }' ></div></div></div>`,
filterByCondition: (data) => `<div class='${classNames.detailsSummary}'>${data.messages.filterByCondition}</div><div class='${classNames.detailsContent}'><div><select aria-label="${data.messages.filterByCondition}" data-${data.ns}role="dropdownlist"data-${data.ns}bind="value: operator, source: operators, events: { change: operatorChange } "data-${data.ns}value-primitive="false"data-${data.ns}option-label="${data.messages.operatorNone}"data-${data.ns}height="auto"data-${data.ns}text-field="text"data-${data.ns}value-field="unique"></select></div><div data-${data.ns}bind="visible: isString"><input aria-label="string-value" data-filter-type="string" data-${data.ns}bind="spreadsheetFilterValue: customFilter.criteria[0].value" class="k-textbox" /></div><div data-${data.ns}bind="visible: isNumber"><input aria-label="number-value" data-filter-type="number" data-${data.ns}role="numerictextbox" data-${data.ns}bind="spreadsheetFilterValue: customFilter.criteria[0].value" /></div><div data-${data.ns}bind="visible: isDate"><input aria-label="date-value" data-filter-type="date" data-${data.ns}role="datepicker" data-${data.ns}bind="spreadsheetFilterValue: customFilter.criteria[0].value" /></div></div>`,
menuItem: (data) => `<li data-command='${data.command}' data-dir='${data.dir}'>${kendo.ui.icon(data.iconClass)}${data.text}</li>`,
actionButtons: (data) => `<button data-${data.ns}bind='click: apply' class='k-button k-button-primary'><span class='k-button-text'>${data.messages.apply}</span></button><button data-${data.ns}bind='click: clear' class='k-button'><span class='k-button-text'>${data.messages.clear}</span></button>`
};
function distinctValues(values) {
var hash = {};
var result = [];
for (var i = 0; i < values.length; i++) if (!hash[values[i].value]) {
hash[values[i].value] = values[i];
result.push(values[i]);
} else if (!hash[values[i].value].checked && values[i].checked) hash[values[i].value].checked = true;
return result;
}
function filter(dataSource, query) {
var hasVisibleChildren = false;
var data = dataSource instanceof kendo.data.HierarchicalDataSource && dataSource.data();
var valuesFilter = this;
var values = this.values;
for (var i = 0; i < data.length; i++) {
var item = data[i];
var text = item.text.toString().toLocaleLowerCase(kendo.culture().name);
var itemVisible = query === true || query === "" || text.indexOf(query) >= 0;
var anyVisibleChildren = filter.bind(valuesFilter)(item.children, query);
hasVisibleChildren = hasVisibleChildren || anyVisibleChildren || itemVisible;
item.hidden = !itemVisible && !anyVisibleChildren;
if (query.length || values && !values.length) item.checked = !item.hidden;
else if (values && values.indexOf(item.text) != -1) item.checked = true;
}
if (data) dataSource.filter({
field: "hidden",
operator: "neq",
value: true
});
return hasVisibleChildren;
}
function uncheckAll(dataSource) {
var data = dataSource instanceof kendo.data.HierarchicalDataSource && dataSource.data();
for (var i = 0; i < data.length; i++) {
var item = data[i];
item.checked = false;
if (item.hasChildren) uncheckAll(item.children);
}
}
var FilterMenuViewModel = kendo.spreadsheet.FilterMenuViewModel = kendo.data.ObservableObject.extend({
valuesChange: function(e) {
var dataSource = e ? e.sender.dataSource : this.valuesDataSource;
var checked = function(item) {
return item.checked;
};
var value = function(item) {
return item.dataType === "date" ? kendo.spreadsheet.dateToNumber(item.value) : item.value;
};
var unique = function(value, index, array) {
return array.lastIndexOf(value) === index;
};
var values = dataSource.data().toJSON()[0].items;
var blanks = values.filter(function(item) {
return item.dataType === "blank";
});
blanks = blanks.length ? blanks[0].checked : false;
values = values.filter(checked).map(value);
if (this.appendToSearch && this.valueFilter && this.valueFilter.values.length) values = values.concat(this.valueFilter.values.toJSON()).sort().filter(unique);
this.set("valueFilter", {
values,
blanks
});
},
valueSelect: function(e) {
e.preventDefault();
var node = e.sender.dataItem(e.node);
node.set("checked", !node.checked);
},
hasActiveSearch: false,
appendToSearch: false,
filterValues: function(e) {
var query = typeof e == "string" ? e : $(e.target).val().toLocaleLowerCase(kendo.culture().name);
var dataSource = this.valuesDataSource;
this.set("hasActiveSearch", !!query);
var filterSpread = filter.bind(this.valueFilter);
uncheckAll(dataSource);
filterSpread(dataSource, query);
},
reset: function() {
this.set("customFilter", {
logic: "and",
criteria: [{
operator: null,
value: null
}]
});
this.set("valueFilter", { values: [] });
},
operatorChange: function(e) {
var dataItem = e.sender.dataItem();
this.set("operatorType", dataItem.type);
if (!this.get("customFilter")) this.reset();
this.set("customFilter.criteria[0].operator", dataItem.value);
},
isNone: function() {
return this.get("operatorType") === void 0;
},
isString: function() {
return this.get("operatorType") === "string";
},
isNumber: function() {
return this.get("operatorType") === "number";
},
isDate: function() {
return this.get("operatorType") === "date";
}
});
function flattenOperators(operators) {
var messages = kendo.spreadsheet.messages.filterMenu.operators;
var result = [];
for (var type in operators) {
if (!operators.hasOwnProperty(type)) continue;
for (var operator in operators[type]) {
if (!operators[type].hasOwnProperty(operator)) continue;
result.push({
text: messages[type][operator],
value: operator,
unique: type + "_" + operator,
type
});
}
}
return result;
}
var FilterMenuController = kendo.spreadsheet.FilterMenuController = {
valuesTree: function(range, column) {
return [{
text: kendo.spreadsheet.messages.filterMenu.all,
expanded: true,
checked: false,
items: this.values(range.resize({ top: 1 }), column)
}];
},
values: function(range, column) {
var values = [];
var messages = kendo.spreadsheet.messages.filterMenu;
var columnRange = range.column(column);
var sheet = range.sheet();
columnRange.forEachCell(function(row, col, cell) {
var checked = true;
if (sheet.isHiddenRow(row)) checked = false;
var value = cell.value;
var dataType = cell.dataType;
var text = cell.text;
if (value === void 0) dataType = "blank";
else if (cell.format) dataType = kendo.spreadsheet.formatting.type(value, cell.format);
else dataType = typeof value;
if (value !== null && cell.format) text = kendo.spreadsheet.formatting.text(value, cell.format);
else text = dataType == "blank" ? messages.blanks : value;
if (dataType === "percent" || dataType === "currency") dataType = "number";
if (dataType === "date") value = kendo.spreadsheet.numberToDate(value);
values.push({
dataType,
value,
text,
checked
});
});
values = distinctValues(values);
values.sort(function(a, b) {
if (a.dataType === b.dataType) return 0;
if (a.dataType === "blank" || b.dataType === "blank") return a.dataType === "blank" ? -1 : 1;
if (a.dataType === "number" || b.dataType === "number") return a.dataType === "number" ? -1 : 1;
if (a.dataType === "date" || b.dataType === "date") return a.dataType === "date" ? -1 : 1;
return 0;
});
return values;
},
filterType: function(range, column) {
var sheet = range.sheet();
var filter = this.filterForColumn(column, sheet);
var type;
filter = filter && filter.filter.toJSON();
if (filter && filter.filter == "custom") {
var value = filter.criteria[0].value;
if (value instanceof Date) type = "date";
else if (typeof value == "string") type = "string";
else if (typeof value == "number") type = "number";
}
if (!type) {
var topValue = this.values(range.row(1), column)[0];
type = topValue && topValue.dataType;
if (type == "blank") type = null;
}
return type;
},
filterForColumn: function(column, sheet) {
var allFilters = sheet.filter();
var filters;
if (allFilters) filters = allFilters.columns.filter(function(item) {
return item.index === column;
})[0];
return filters;
},
filter: function(column, sheet) {
var columnFilters = this.filterForColumn(column, sheet);
if (!columnFilters) return;
var options = columnFilters.filter.toJSON();
var type = options.filter;
delete options.filter;
var result = {
type,
options
};
var criteria = options.criteria;
if (criteria && criteria.length) result.operator = criteria[0].operator;
return result;
}
};
var FilterMenu = Widget.extend({
init: function(element, options) {
Widget.call(this, element, options);
this.element.addClass(FilterMenu.classNames.wrapper);
this.viewModel = new FilterMenuViewModel({
active: "value",
checkboxesConfig: { checkChildren: true },
operator: null,
operators: flattenOperators(this.options.operators),
clear: this.clear.bind(this),
apply: this.apply.bind(this)
});
this._filterInit();
this._popup();
this._sort();
this._filterByCondition();
this._filterByValue();
this._actionButtons();
},
options: {
name: "FilterMenu",
column: 0,
range: null,
operators: {
string: {
contains: "Text contains",
doesnotcontain: "Text does not contain",
startswith: "Text starts with",
endswith: "Text ends with",
matches: "Text matches",
doesnotmatch: "Text does not match"
},
date: {
eq: "Date is",
neq: "Date is not",
lt: "Date is before",
gt: "Date is after"
},
number: {
eq: "Is equal to",
neq: "Is not equal to",
gte: "Is greater than or equal to",
gt: "Is greater than",
lte: "Is less than or equal to",
lt: "Is less than"
}
}
},
events: ["action"],
destroy: function() {
Widget.fn.destroy.call(this);
this.menu.destroy();
this.valuesTreeView.destroy();
this.popup.destroy();
},
openFor: function(anchor, event) {
if ($(anchor).hasClass("k-spreadsheet-view-size")) this.popup.open(event.pageX, event.pageY);
else {
this.popup.setOptions({ anchor });
this.popup.open();
}
},
close: function() {
this.popup.close();
},
clear: function() {
this.action({
command: "ClearFilterCommand",
options: { column: this.options.column }
});
this.viewModel.reset();
this.close();
},
apply: function() {
this._active();
var options = {
operatingRange: this.options.range,
column: this.options.column
};
var valueFilter;
var customFilter;
if (this.viewModel.active === "value") {
this.viewModel.valuesChange({ sender: this.valuesTreeView });
valueFilter = this.viewModel.valueFilter.toJSON();
if (valueFilter.blanks || valueFilter.values && valueFilter.values.length) options.valueFilter = valueFilter;
} else if (this.viewModel.active === "custom") {
customFilter = this.viewModel.customFilter.toJSON();
if (customFilter.criteria.length && customFilter.criteria[0].value !== null) options.customFilter = customFilter;
}
if (options.valueFilter || options.customFilter) this.action({
command: "ApplyFilterCommand",
options
});
},
action: function(options) {
this.trigger("action", $.extend({}, options));
},
_filterInit: function() {
var column = this.options.column;
var range = this.options.range;
var sheet = range.sheet();
var activeFilter = FilterMenuController.filter(column, sheet);
if (activeFilter) {
var filterType = FilterMenuController.filterType(range, column);
this.viewModel.set("active", activeFilter.type);
this.viewModel.set(activeFilter.type + "Filter", activeFilter.options);
if (activeFilter.type == "custom") {
this.viewModel.set("operator", filterType + "_" + activeFilter.operator);
this.viewModel.set("operatorType", filterType);
}
} else this.viewModel.reset();
},
_popup: function() {
this.popup = this.element.kendoPopup({ copyAnchorStyles: false }).data("kendoPopup");
},
_sort: function() {
var template = kendo.template(FilterMenu.templates.menuItem);
var messages = kendo.spreadsheet.messages.filterMenu;
var items = [{
command: "sort",
dir: "asc",
text: messages.sortAscending,
iconClass: "sort-asc"
}, {
command: "sort",
dir: "desc",
text: messages.sortDescending,
iconClass: "sort-desc"
}];
var ul = $("<ul></ul>", { "html": kendo.render(template, items) }).appendTo(this.element);
this.menu = ul.kendoMenu({
orientation: "vertical",
select: function(e) {
var options = {
value: $(e.item).data("dir"),
sheet: false,
operatingRange: this.options.range.resize({ top: 1 }),
column: this.options.column
};
this.action({
command: "SortCommand",
options
});
}.bind(this)
}).data("kendoMenu");
},
_appendTemplate: function(template, className, details, expanded) {
var compiledTemplate = kendo.template(template);
var wrapper = $("<div class='" + className + "'/>").html(compiledTemplate({
messages: kendo.spreadsheet.messages.filterMenu,
guid: kendo.guid(),
ns: kendo.ns
}));
this.element.append(wrapper);
if (details) details = new Details(wrapper, {
expanded,
toggle: this._detailToggle.bind(this)
});
kendo.bind(wrapper, this.viewModel);
return wrapper;
},
_detailToggle: function(e) {
this.element.find("[" + kendo.attr("role") + "=details]").not(e.sender.element).data("kendoDetails").toggle(!e.show);
},
_filterByCondition: function() {
var isExpanded = this.viewModel.active === "custom";
this._appendTemplate(FilterMenu.templates.filterByCondition, FilterMenu.classNames.filterByCondition, true, isExpanded);
},
_filterByValue: function() {
var isExpanded = this.viewModel.active === "value";
var wrapper = this._appendTemplate(FilterMenu.templates.filterByValue, FilterMenu.classNames.filterByValue, true, isExpanded);
this.valuesTreeView = wrapper.find("[" + kendo.attr("role") + "=treeview]").data("kendoTreeView");
var values = FilterMenuController.valuesTree(this.options.range, this.options.column);
this.viewModel.set("valuesDataSource", new kendo.data.HierarchicalDataSource({
data: values,
accentFoldingFiltering: kendo.culture().name
}));
},
_actionButtons: function() {
this._appendTemplate(FilterMenu.templates.actionButtons, FilterMenu.classNames.actionButtons, false);
},
_active: function() {
var activeContainer = this.element.find("[" + kendo.attr("role") + "=details]").filter(function(index, element) {
return $(element).data("kendoDetails").visible();
});
if (activeContainer.hasClass(FilterMenu.classNames.filterByValue)) this.viewModel.set("active", "value");
else if (activeContainer.hasClass(FilterMenu.classNames.filterByCondition)) this.viewModel.set("active", "custom");
}
});
kendo.spreadsheet.FilterMenu = FilterMenu;
$.extend(true, FilterMenu, {
classNames,
templates
});
})(window.kendo);
//#endregion
//#region ../src/spreadsheet/messages.js
(function(kendo) {
kendo.spreadsheet.messages.workbook = { defaultSheetName: "Sheet" };
kendo.spreadsheet.messages.view = {
nameBox: "Name Box",
formulaInput: "Formula Input",
errors: {
openUnsupported: "Unsupported format. Please select an .xlsx file.",
shiftingNonblankCells: "Cannot insert cells due to data loss possibility. Select another insert location or delete the data from the end of your worksheet.",
insertColumnWhenRowIsSelected: "Cannot insert column when all columns are selected.",
insertRowWhenColumnIsSelected: "Cannot insert row when all rows are selected.",
filterRangeContainingMerges: "Cannot create a filter within a range containing merges",
sortRangeContainingMerges: "Cannot sort a range containing merges",
cantSortMultipleSelection: "Cannot sort multiple selection",
cantSortNullRef: "Cannot sort empty selection",
cantSortMixedCells: "Cannot sort range containing cells of mixed shapes",
validationError: "The value that you entered violates the validation rules set on the cell.",
cannotModifyDisabled: "Cannot modify disabled cells.",
insertRowBelowLastRow: "Cannot insert row below the last row.",
insertColAfterLastCol: "Cannot insert column to the right of the last column."
},
tabs: {
file: "File",
home: "Home",
insert: "Insert",
format: "Format",
data: "Data",
view: "View"
},
sheetBar: {
addSheet: "Add new sheet",
deleteSheet: "Delete",
duplicateSheet: "Duplicate",
renameSheet: "Rename",
hideSheet: "Hide",
moveRight: "Move Right",
moveLeft: "Move Left"
}
};
kendo.spreadsheet.messages.menus = {
"cut": "Cut",
"copy": "Copy",
"paste": "Paste",
"merge": "Merge",
"unmerge": "Unmerge",
"delete": "Delete",
"hide": "Hide",
"unhide": "Unhide",
"bringToFront": "Bring to front",
"sendToBack": "Send to back"
};
})(window.kendo);
//#endregion
//#region ../src/spreadsheet/workbook.js
(function(kendo) {
let $ = kendo.jQuery;
if (kendo.PDFMixin) {
let override_drawPDF = function(options) {
var result = new $.Deferred();
var callback = function(group) {
result.resolve(group);
};
switch (options.area) {
case "workbook":
options.workbook.draw(options, callback);
break;
case "sheet":
options.workbook.activeSheet().draw(options, callback);
break;
case "selection":
options.workbook.activeSheet().selection().draw(options, callback);
break;
}
return result.promise();
};
let overrideSaveAsPDF = function(options) {
if (this.events.indexOf("pdfExport") === -1) {
kendo.PDFMixin.extend(this);
this.saveAsPDF = overrideSaveAsPDF;
this._drawPDF = override_drawPDF;
}
var progress = new $.Deferred();
var promise = progress.promise();
var args = { promise };
if (this.trigger("pdfExport", args)) return;
this._drawPDF(options, progress).then(function(root) {
let pdfResultPromise = options.forceProxy ? kendo.pdf.exportPDF(root) : kendo.pdf.exportPDFToBlob(root);
return kendo.convertPromiseToDeferred(pdfResultPromise);
}).done(function(dataURI) {
kendo.saveAs({
dataURI,
fileName: options.fileName,
proxyURL: options.proxyURL,
forceProxy: options.forceProxy,
proxyTarget: options.proxyTarget
});
progress.resolve();
}).fail(function(err) {
progress.reject(err);
});
return promise;
};
kendo.spreadsheet.Workbook.prototype.saveAsPDF = overrideSaveAsPDF;
kendo.spreadsheet.Workbook.prototype._drawPDF = override_drawPDF;
}
})(kendo);
//#endregion
//#region ../src/kendo.spreadsheet.js
const __meta__ = {
id: "spreadsheet",
name: "Spreadsheet",
category: "web",
description: "Spreadsheet component",
depends: [
"core",
"binder",
"colorpicker",
"combobox",
"data",
"dom",
"dropdownlist",
"menu",
"ooxml",
"popup",
"sortable",
"tabstrip",
"toolbar",
"treeview",
"window",
"validator",
"excel",
"pdf",
"drawing",
"list",
"spreadsheet.common"
]
};
(function(kendo, undefined) {
if (kendo.support.browser.msie && kendo.support.browser.version < 9) return;
const K_ACTIVE = "k-active";
let $ = kendo.jQuery;
let Widget = kendo.ui.Widget;
let DOT = ".";
let commonEngine = kendo.spreadsheet.commonEngine;
let FormulaInput = kendo.spreadsheet.FormulaInput;
let SheetsBar = kendo.spreadsheet.SheetsBar;
function toActionSelector(selectors) {
return selectors.map(function(action) {
return "[data-action=\"" + action + "\"]";
}).join(",");
}
function convertSpreadsheetDeferredToJQueryDeferred(spreadsheetDeferred) {
const deferred = $.Deferred();
spreadsheetDeferred.then(function(value) {
deferred.resolve(value);
}, function(reason) {
deferred.reject(reason);
});
if (typeof spreadsheetDeferred.progress === "function") spreadsheetDeferred.progress(function(val) {
deferred.notify(val);
});
const promise = deferred.promise();
promise.progress = function(fn) {
deferred.progress(fn);
return promise;
};
return promise;
}
function removeEventsFromOptions(options, eventNames) {
const sanitized = {};
for (let key in options) if (options.hasOwnProperty(key) && eventNames.indexOf(key) === -1) sanitized[key] = options[key];
return sanitized;
}
let COMPOSITE_UNAVAILABLE_ACTION_SELECTORS = toActionSelector([
"cut",
"copy",
"paste",
"insert-left",
"insert-right",
"insert-above",
"insert-below"
]);
let UNHIDE_ACTION_SELECTORS = toActionSelector(["unhide-row", "unhide-column"]);
let classNames = { wrapper: "k-spreadsheet" };
let viewClassNames = commonEngine.View.classNames;
const SPREADSHEET_CONTENT_HTML_TEMPLATE = ({ messages }) => `
<div ref-header-container class="k-spreadsheet-header"><div ref-header-menu></div><div ref-header-toolbar></div></div>
<div class="k-spreadsheet-action-bar">
<div class="k-spreadsheet-name-editor">
<input ref-namebox-input title="${messages.nameBox || "Name Box"}" aria-label="${messages.nameBox || "Name Box"}"></input>
</div>
<div class="k-spreadsheet-formula-bar">
${kendo.ui.icon("formula-fx")}
<div class="k-spreadsheet-formula-input"
role="combobox"
title="${messages.view.formulaInput}"
aria-haspopup="menu"
aria-expanded="false"
contentEditable="true"
spellCheck="false">
</div>
</div>
</div>
<div class="k-spreadsheet-view">
<div class="k-spreadsheet-fixed-container"></div>
<div class="k-spreadsheet-scroller">
<div class="k-spreadsheet-view-size"></div>
</div>
<div tabIndex="0" class="k-spreadsheet-clipboard" contentEditable="true" ></div>
<div contentEditable="true"
spellCheck="false"
role="combobox"
title="${messages.view.formulaInput}"
aria-haspopup="menu"
aria-expanded="false"
class="k-spreadsheet-formula-input k-spreadsheet-cell-editor">
</div>
</div>
<div ref-sheets-bar></div>`;
const CELL_CONTEXT_MENU = ({ messages }) => `
<ul class="${viewClassNames.cellContextMenu}">
<li data-action="cut">${messages.menus.cut}</li>
<li data-action="copy">${messages.menus.copy}</li>
<li data-action="paste">${messages.menus.paste}</li>
<li class="k-separator"></li>
<li data-action="merge">${messages.menus.merge}</li>
<li data-action="unmerge">${messages.menus.unmerge}</li>
</ul>`;
const ROW_HEADER_CONTEXT_MENU = ({ messages }) => `
<ul class="${viewClassNames.rowHeaderContextMenu}">
<li data-action="cut">${messages.menus.cut}</li>
<li data-action="copy">${messages.menus.copy}</li>
<li data-action="paste">${messages.menus.paste}</li>
<li class="k-separator"></li>
<li data-action="delete-row">${messages.menus.delete}</li>
<li data-action="hide-row">${messages.menus.hide}</li>
<li data-action="unhide-row">${messages.menus.unhide}</li>
</ul>`;
const COL_HEADER_CONTEXT_MENU = ({ messages }) => `
<ul class="${viewClassNames.colHeaderContextMenu}">
<li data-action="cut">${messages.menus.cut}</li>
<li data-action="copy">${messages.menus.copy}</li>
<li data-action="paste">${messages.menus.paste}</li>
<li class="k-separator"></li>
<li data-action="delete-column">${messages.menus.delete}</li>
<li data-action="hide-column">${messages.menus.hide}</li>
<li data-action="unhide-column">${messages.menus.unhide}</li>
</ul>`;
const DRAWING_CONTEXT_MENU = ({ messages }) => `
<ul class="${viewClassNames.drawingContextMenu}">
<li data-action="bring-to-front">${messages.menus.bringToFront}</li>
<li data-action="send-to-back">${messages.menus.sendToBack}</li>
<li class="k-separator"></li>
<li data-action="delete-drawing">${messages.menus.delete}</li>
</ul>`;
kendo.spreadsheet.ContextMenu = kendo.ui.ContextMenu;
let FormulaInputStaticList = kendo.ui.StaticList.extend({
data: function(d) {
return this.dataSource.data(d);
},
itemClick: function(handler) {
this.bind("change", function(ev) {
handler(this.value()[0]);
});
}
});
class FormulaInputRefArgs {
constructor({ list, popup }) {
this.current = {
list,
popup
};
this.clone = function clone() {
return this;
};
}
}
class NameBoxRefArgs {
constructor({ nameEditor, container }) {
let combo = this.initializeComboBox(container, nameEditor);
this.current = { value: (val) => {
if (val === undefined) {
const item = combo.value();
return item ? item.name || item : item;
} else combo.value(val || "");
} };
this.nameEditor = nameEditor;
this.clone = function clone() {
return this;
};
}
initializeComboBox(container) {
let that = this;
let dataSource = new kendo.data.DataSource({ transport: {
read: function(options) {
let data = that.nameEditor()?.readData() || [];
options.success(data);
},
cache: false
} });
let combo = $(container).kendoComboBox({
clearButton: false,
dataTextField: "name",
dataValueField: "name",
template: ({ name }) => `${kendo.htmlEncode(name)}<a role='button' class='k-button-delete' href='\\#'>${kendo.ui.icon("x")}</a>`,
dataSource,
autoBind: false,
ignoreCase: true,
change: that.onChange.bind(that),
noDataTemplate: () => "<div></div>",
open: function() {
dataSource.read();
}
}).data("kendoComboBox");
combo.input.on("keydown", that, that.onKeyDown.bind(this));
combo.popup.element.addClass("k-spreadsheet-names-popup").on("mousemove", function(ev) {
ev.stopPropagation();
}).on("click", ".k-button-delete", function(ev) {
ev.preventDefault();
ev.stopPropagation();
let item = $(ev.target).closest(".k-list-item");
item = combo.dataItem(item);
that.onDelete(item.name);
});
return combo;
}
onChange(event) {
const editor = this.nameEditor();
if (editor && event.sender.value()) editor.trigger("select", { name: event.sender.value() });
}
onDelete(name) {
this.nameEditor()?.trigger("delete", { name });
}
onKeyDown(event) {
const editor = this.nameEditor();
if (editor) {
if (event.key === "Enter") {
const name = event.target.value;
editor.trigger("enter", { value: name });
} else if (event.key === "Escape") editor.trigger("cancel");
}
}
}
let Spreadsheet = kendo.ui.Widget.extend({
_renderInnerContent: function(element) {
$(element).append(SPREADSHEET_CONTENT_HTML_TEMPLATE(this.options));
},
init: function(element, options) {
let that = this;
Widget.fn.init.call(this, element, options);
this.options.messages = $.extend(true, {
view: kendo.spreadsheet.messages.view,
tabs: kendo.spreadsheet.messages.view.tabs,
menus: kendo.spreadsheet.messages.menus,
workbook: { defaultSheetName: "Sheet" }
}, this.options.messages);
this.element.addClass(Spreadsheet.classNames.wrapper);
this.element.attr("role", "application");
this._renderInnerContent(this.element);
this.element.on("keydown.kendoSpreadsheet", that, function() {});
this._createFormulaInputs();
that.spreadsheetRef = this._initSpreadsheetWidget();
this._normalizeTooltipClasses();
this._normalizeViewStacking();
this._bindWorkbookEvents();
const activeSheet = this.activeSheet();
this._onUpdateTools({ range: activeSheet.range(activeSheet.activeCell()) });
this._resizeHandler = function() {
that.resize();
};
$(window).on("resize.kendoSpreadsheet", this._resizeHandler);
if (this._showWatermarkOverlay) this._showWatermarkOverlay(this.element[0]);
kendo.ui.Widget.fn.endInit.call(this);
},
_initSpreadsheetWidget: function() {
const that = this;
const options = removeEventsFromOptions(that.options, that.events);
let widgetOptions = $.extend({}, options, {
sheetsbar: that.options.sheetsbar != false ? that.options.sheetsbar : {},
formulaBarInputRef: new FormulaInputRefArgs({
list: this._formulaBarInputRefList,
popup: this._formulaBarInputRefPopup
}),
formulaCellInputRef: new FormulaInputRefArgs({
list: this._formulaCellInputRefList,
popup: this._formulaCellInputRefPopup
}),
nameBoxRef: new NameBoxRefArgs({
container: that.element.find(".k-spreadsheet-name-editor [ref-namebox-input]"),
nameEditor: function() {
return that.spreadsheetRef?.view.nameEditor;
}
}),
createFilterMenu: function(options) {
let element = $("<div></div>").appendTo(that.element);
return new kendo.spreadsheet.FilterMenu(element, options);
},
createTabStrip: function(options) {
if (that.options.toolbar) {
that._initHeader();
return {
focus: function() {
that.menu.wrapper.trigger("focus");
},
select: function(name) {
that.menu.element.find(`li[ref-tab-name="${name}"]`).click();
},
destroy: function() {
that.menu.destroy();
}
};
}
},
createSheetEditor: function(options) {
that.sheetsBar._createEditor();
},
createSheetBar: function(openDialogCallback) {
that._sheetsBar(openDialogCallback);
},
createContextMenus: function(options) {
that._dialogs = [];
that._initContextMenus();
},
createSheetDataSource: function(dataSource) {
return kendo.data.DataSource.create(dataSource);
},
getWorkbookCommand: function(commandName, commandOptions) {
return new kendo.spreadsheet[commandName](commandOptions);
},
getIconHTMLString: function(iconName) {
return $(kendo.ui.icon(iconName))[0];
},
update: function(e) {
that._onUpdateTools(e);
if (e.reason.sheetSelection && that.sheetsBar) that.sheetsBar.renderSheets(e.sender.sheets(), e.sender.sheetIndex(e.sheet));
},
message: (args) => {
let { sender, name, ref, range, ...dialogOptions } = args;
let opts = $.extend({}, {
pdfExport: that.options.pdf,
excelExport: that.options.excel
}, dialogOptions);
let dialog = kendo.spreadsheet.dialogs.create(args.name, opts);
const saveAsCallback = function(data, fileName, exportOptions) {
kendo.saveAs({
dataURI: data,
fileName,
...exportOptions
});
};
if (dialog) {
dialog.bind("action", function(args) {
if (args.command == "SaveAsCommand") {
let { sender, ...commandArgs } = args;
let fileName = args.options.name + args.options.extension;
if (args.options.extension === ".xlsx") return that.spreadsheetRef.saveAsExcel($.extend(commandArgs, {
fileName,
Workbook: kendo.ooxml.Workbook,
saveAs: saveAsCallback
}));
else if (this.options.extension === ".pdf") return that.spreadsheetRef.saveAsPDF($.extend(args.options.pdf, {
workbook: this.options.workbook,
fileName
}));
}
that.spreadsheetRef.executeCommand(args);
});
dialog.bind("deactivate", () => {
dialog.destroy();
that._dialogs.pop();
});
that._dialogs.push(dialog);
dialog.open(args.range, args);
args.dialog = dialog;
}
},
contextmenu: (e) => {
const { objectRef, targetType, showUnhide, showUnmerge, originalEvent, isComposite } = e;
const { topLeft, bottomRight } = e.sender.activeSheet().select();
this._cellContextMenu.close();
this._colHeaderContextMenu.close();
this._rowHeaderContextMenu.close();
this._drawingContextMenu.close();
let menu;
if (targetType == "columnheader") menu = this._colHeaderContextMenu;
else if (targetType == "rowheader") menu = this._rowHeaderContextMenu;
else if (targetType == "drawing") menu = this._drawingContextMenu;
else menu = this._cellContextMenu;
menu.element.find(COMPOSITE_UNAVAILABLE_ACTION_SELECTORS).toggle(!isComposite);
menu.element.find(UNHIDE_ACTION_SELECTORS).toggle(showUnhide);
menu.element.find("[data-action=unmerge]").toggle(showUnmerge);
setTimeout(function() {
menu.open(e.originalEvent.pageX, e.originalEvent.pageY);
});
},
locale: kendo.cultures.current.name,
intl: kendo.kendoCultureToIntl()
});
return new kendo.spreadsheet.commonEngine.SpreadsheetWidget(this.element[0], widgetOptions);
},
_normalizeTooltipClasses: function() {
this.element.find(".k-tooltip.k-widget").removeClass("k-widget");
},
_normalizeViewStacking: function() {
let fixedContainer = this.element.find(".k-spreadsheet-fixed-container")[0];
let scroller = this.element.find(".k-spreadsheet-scroller")[0];
if (!fixedContainer || !scroller || !window.getComputedStyle) return;
let fixedZIndex = parseInt(window.getComputedStyle(fixedContainer).zIndex, 10);
let scrollerZIndex = parseInt(window.getComputedStyle(scroller).zIndex, 10);
if (!isNaN(fixedZIndex) && !isNaN(scrollerZIndex) && scrollerZIndex >= fixedZIndex) scroller.style.zIndex = String(Math.max(fixedZIndex - 1, 0));
},
_createFormulaInputs: function() {
let formulaBarInputRefElement = this.element.find(".k-spreadsheet-action-bar .k-spreadsheet-formula-input");
let formulaBarInputRefListId = kendo.guid();
formulaBarInputRefElement.attr("aria-controls", formulaBarInputRefListId);
this._formulaBarInputRefList = new FormulaInputStaticList($(`<ul id="${formulaBarInputRefListId}" />`).addClass(FormulaInput.classNames.listWrapper).insertAfter(formulaBarInputRefElement), {
aria: {
role: "menu",
itemRole: "menuitem"
},
autoBind: false,
selectable: true,
dataTextField: "text",
dataValueField: "value",
template: ({ text, value }) => `${text || value}`
});
this._formulaBarInputRefList.element.on("mousedown", function(e) {
e.preventDefault();
});
this._formulaBarInputRefPopup = new kendo.ui.Popup(this._formulaBarInputRefList.element, {
anchor: this.element.find(".k-spreadsheet-formula-input:not(.k-spreadsheet-cell-editor)"),
open: function(ev) {
formulaBarInputRefElement.attr("aria-expanded", true);
},
close: function(ev) {
formulaBarInputRefElement.attr("aria-expanded", false);
}
});
let formulaCellInputRefElement = this.element.find(".k-spreadsheet-cell-editor");
let formulaCellInputRefListId = kendo.guid();
formulaCellInputRefElement.attr("aria-controls", formulaCellInputRefListId);
this._formulaCellInputRefList = new FormulaInputStaticList($(`<ul id="${formulaCellInputRefListId}" />`).addClass(FormulaInput.classNames.listWrapper).insertAfter(formulaCellInputRefElement), {
aria: {
role: "menu",
itemRole: "menuitem"
},
autoBind: false,
selectable: true,
dataValueField: "value",
dataTextField: "text",
template: ({ text, value }) => `${text || value}`
});
this._formulaCellInputRefList.element.on("mousedown", function(e) {
e.preventDefault();
});
this._formulaCellInputRefPopup = new kendo.ui.Popup(this._formulaCellInputRefList.element, {
anchor: this.element.find(DOT + commonEngine.View.classNames.cellEditor),
open: function(ev) {
formulaCellInputRefElement.attr("aria-expanded", true);
},
close: function(ev) {
formulaCellInputRefElement.attr("aria-expanded", false);
}
});
},
_initContextMenus: function() {
let that = this;
let contextMenuConfig = {
target: this.element,
animation: false,
showOn: "never"
};
this._cellContextMenu = new kendo.spreadsheet.ContextMenu($(CELL_CONTEXT_MENU(that.options)).appendTo(that.element), contextMenuConfig);
this._colHeaderContextMenu = new kendo.spreadsheet.ContextMenu($(COL_HEADER_CONTEXT_MENU(that.options)).appendTo(that.element), contextMenuConfig);
this._rowHeaderContextMenu = new kendo.spreadsheet.ContextMenu($(ROW_HEADER_CONTEXT_MENU(that.options)).appendTo(that.element), contextMenuConfig);
this._drawingContextMenu = new kendo.spreadsheet.ContextMenu($(DRAWING_CONTEXT_MENU(that.options)).appendTo(that.element), contextMenuConfig);
this._cellContextMenu.bind("select", this.onContextMenuSelect.bind(this));
this._rowHeaderContextMenu.bind("select", this.onContextMenuSelect.bind(this));
this._colHeaderContextMenu.bind("select", this.onContextMenuSelect.bind(this));
this._drawingContextMenu.bind("select", this.onContextMenuSelect.bind(this));
},
onContextMenuSelect: function(e) {
let that = this;
let action = $(e.item).data("action");
let command;
switch (action) {
case "cut":
command = {
command: "ToolbarCutCommand",
options: { workbook: this.spreadsheetRef.workbook }
};
break;
case "copy":
command = {
command: "ToolbarCopyCommand",
options: { workbook: this.spreadsheetRef.workbook }
};
break;
case "paste":
command = {
command: "ToolbarPasteCommand",
options: { workbook: this.spreadsheetRef.workbook }
};
break;
case "delete-drawing":
command = {
command: "DeleteDrawingCommand",
options: { drawing: this.spreadsheetRef._controller.navigator._sheet._activeDrawing }
};
break;
case "bring-to-front":
command = {
command: "BringToFrontCommand",
options: { drawing: this.spreadsheetRef._controller.navigator._sheet._activeDrawing }
};
break;
case "send-to-back":
command = {
command: "SendToBackCommand",
options: { drawing: this.spreadsheetRef._controller.navigator._sheet._activeDrawing }
};
break;
case "unmerge":
command = {
command: "MergeCellCommand",
options: { value: "unmerge" }
};
break;
case "merge":
this.spreadsheetRef.openDialog("merge");
break;
case "hide-row":
command = {
command: "HideLineCommand",
options: { axis: "row" }
};
break;
case "hide-column":
command = {
command: "HideLineCommand",
options: { axis: "column" }
};
break;
case "unhide-row":
command = {
command: "UnHideLineCommand",
options: { axis: "row" }
};
break;
case "unhide-column":
command = {
command: "UnHideLineCommand",
options: { axis: "column" }
};
break;
case "delete-row":
command = { command: "DeleteRowCommand" };
break;
case "delete-column":
command = { command: "DeleteColumnCommand" };
break;
}
if (command) that.spreadsheetRef.executeCommand(command);
},
_onUpdateTools: function(e) {
let reason = e.reason;
if (reason && (reason.overElement || reason.comment)) return;
this.toolbar?.refresh(e.range);
},
_getCopyRegex: function(sheetName) {
const st = `(${sheetName.replaceAll("(", "\\(").replaceAll(")", "\\)")})\\s?\\(`;
return new RegExp(st, "s");
},
_sheetsBar: function(openDialogCallback) {
let that = this;
if (that.options.sheetsbar) {
let sheetsbarOptions = $.extend(true, { openDialog: openDialogCallback }, that.options.sheetsbar);
that.sheetsBar = new SheetsBar(that.element[0].querySelector("[ref-sheets-bar]"), sheetsbarOptions);
that.sheetsBar.bind("select", function onSheetSelect(ev) {
if (ev.isAddButton) that.spreadsheetRef.view.sheetsbar.onAddSelect();
else that.spreadsheetRef.view.sheetsbar.onSheetSelect(ev.name);
});
that.sheetsBar.bind("reorder", function onSheetReorderEnd(ev) {
that.spreadsheetRef.view.sheetsbar.onSheetReorderEnd(ev);
});
that.sheetsBar.bind("rename", function onSheetRename(ev) {
that.spreadsheetRef.view.sheetsbar.onSheetRename(ev.name, ev.sheetIndex);
});
that.sheetsBar.bind("duplicate", function onSheetDuplicate(ev) {
let name = ev.name;
let sheetToCopy = that.sheetByName(name);
let sheetIndex = that.sheetIndex(sheetToCopy);
let copies = 0;
const regex = that._getCopyRegex(name);
that.sheets().forEach((sheet) => {
if (regex.test(sheet.name())) copies += 1;
});
const newName = `${name} (${copies + 1})`;
that.insertSheet({
data: {
...sheetToCopy.toJSON(),
name: newName
},
index: sheetIndex + 1
});
that.spreadsheetRef.view.sheetsbar.onSheetSelect(newName);
});
that.sheetsBar.bind("remove", function onSheetBarRemove(ev) {
that.spreadsheetRef.view.sheetsbar.onSheetRemove(ev.name);
});
that.sheetsBar.bind("hide", function onSheetBarHide(ev) {
let sheetName = ev.name;
let sheetToHide = that.sheetByName(sheetName);
let visibleSheets = that.sheets().filter((x) => x.state() === "visible");
let visibleSheetIndex = visibleSheets.findIndex((x) => x.name() === sheetName);
let nextVisibleSheet = visibleSheets[visibleSheetIndex + 1] || visibleSheets[visibleSheetIndex - 1];
sheetToHide._state("hidden");
that.spreadsheetRef.workbook._sheetsSearchCache = {};
that.spreadsheetRef.view.sheetsbar.onSheetSelect(nextVisibleSheet.name());
});
that.sheetsBar.bind("show", function onSheetBarShow(ev) {
let sheetName = ev.name;
that.sheetByName(sheetName)._state("visible");
that.spreadsheetRef.workbook._sheetsSearchCache = {};
that.spreadsheetRef.view.sheetsbar.onSheetSelect(ev.name);
});
}
},
_createToolBar: function(options, tabs, toolbarId) {
let that = this;
if (that.toolbar) {
that.toolbar.destroy();
that.toolbar.element.empty();
}
let activeToolbar = tabs[tabs.findIndex((item) => item.id === toolbarId)];
let tools = options[activeToolbar.id];
that._activeToolBar = activeToolbar.text;
that.toolbar = new kendo.spreadsheet.ToolBar(this.element.find("[ref-header-toolbar]"), {
tools: typeof tools === "boolean" ? undefined : tools,
overflow: $.isPlainObject(options.overflow) ? options.overflow : undefined,
toolbarName: activeToolbar.id,
fillMode: "flat",
action: function(args) {
if (args.command === "undo" || args.command === "redo") {
that.spreadsheetRef.workbook.undoRedoStack[args.command]();
return;
}
if (args.command == "OpenCommand") args.options.file = args.options.value;
else if (args.command === "BorderChangeCommand") {
args.options.border = args.options.border || args.options.value.type;
args.options.style = args.options.style || args.options.value.style || {
color: args.options.value.color,
size: 1
};
}
that.spreadsheetRef.executeCommand(args);
},
dialog: function(args) {
that.spreadsheetRef.openDialog(args.name, args.options);
}
});
that.toolbar.element.attr("aria-label", activeToolbar.text);
},
_initHeader: function() {
let that = this;
let messages = this.options.messages.tabs;
let options = $.extend(true, {
file: true,
home: true,
insert: true,
format: true,
data: true,
view: true
}, this.options.toolbar);
let tabs = [];
if (this.menu) {
this.menu.destroy();
this.menu.empty();
}
if (this.toolbar) {
this.toolbar.destroy();
this.toolbar.empty();
}
for (let name in options) if (options[name] === true || options[name] instanceof Array) tabs.push({
id: name,
text: messages[name],
content: "",
attr: { "ref-tab-name": name }
});
this.menu = new kendo.spreadsheet.Menu(this.element.find("[ref-header-menu]"), {
dataSource: tabs,
toolbarOptions: options,
select: function(e) {
let text = $(e.item).text();
if (that._activeToolBar !== text) {
$(e.item).addClass(K_ACTIVE).siblings("li").removeClass(K_ACTIVE);
that._createToolBar(options, tabs, tabs.find((item) => item.text === text).id);
const activeSheet = that.activeSheet();
that._onUpdateTools({ range: activeSheet.range(activeSheet.activeCell()) });
}
}
});
if (tabs.length) {
let defaultTab = tabs.find((item) => item.id === "home");
this.menu.element.find(`li[ref-tab-name="home"]`).addClass(K_ACTIVE);
that._createToolBar(options, tabs, defaultTab ? defaultTab.id : tabs[0].id);
}
},
executeCommand(options) {
return this.spreadsheetRef.executeCommand(options);
},
_resize: function() {
this.refresh({ layout: true });
},
_workbookRender: function(e) {
if (this.trigger("render", e)) e.preventDefault();
},
_workbookChanging: function(e) {
if (this.trigger("changing", e)) e.preventDefault();
},
_workbookChange: function(e) {
if (this.trigger("change", { range: e.range })) e.preventDefault();
},
_workbookCut: function(e) {
this.trigger("cut", e);
},
_workbookCopy: function(e) {
this.trigger("copy", e);
},
_workbookPaste: function(e) {
this.trigger("paste", e);
},
activeSheet: function(sheet) {
return this.spreadsheetRef.activeSheet(sheet);
},
moveSheetToIndex: function(sheet, index) {
return this.spreadsheetRef.moveSheetToIndex(sheet, index);
},
insertSheet: function(options) {
return this.spreadsheetRef.insertSheet(options);
},
sheets: function() {
return this.spreadsheetRef.sheets();
},
removeSheet: function(sheet) {
return this.spreadsheetRef.removeSheet(sheet);
},
sheetByName: function(sheetName) {
return this.spreadsheetRef.sheetByName(sheetName);
},
sheetIndex: function(sheet) {
return this.spreadsheetRef.sheetIndex(sheet);
},
sheetByIndex: function(index) {
return this.spreadsheetRef.sheetByIndex(index);
},
renameSheet: function(sheet, newSheetName) {
return this.spreadsheetRef.renameSheet(sheet, newSheetName);
},
refresh: function(reason) {
this.spreadsheetRef.refresh(reason);
return this;
},
openDialog: function(name, options) {
return this.spreadsheetRef.openDialog(name, options);
},
autoRefresh: function(value) {
if (value !== undefined) {
this._autoRefresh = value;
if (value === true) this.refresh();
return this;
}
return this._autoRefresh;
},
toJSON: function() {
return this.spreadsheetRef.toJSON();
},
fromJSON: function(json) {
this.spreadsheetRef.fromJSON(json);
},
saveJSON: function() {
return this.spreadsheetRef.saveJSON();
},
fromFile: function(blob, name) {
return this.spreadsheetRef.fromFile(blob, name);
},
saveAsPDF: function(options) {
this.spreadsheetRef.saveAsPDF($.extend({}, this.options.pdf, options, { workbook: this.spreadsheetRef._workbook }));
},
saveAsExcel: function(options) {
const exportOps = $.extend({}, this.options.excel, options, {
Workbook: kendo.ooxml.Workbook,
saveAs: function(data, fileName, exportOptions) {
kendo.saveAs({
dataURI: data,
fileName,
...exportOptions
});
}
});
this.spreadsheetRef.saveAsExcel(exportOps);
},
draw: function(options, callback) {
this.spreadsheetRef.draw(options, callback);
},
_workbookExcelExport: function(e) {
if (this.trigger("excelExport", e)) e.preventDefault();
},
_workbookExcelImport: function(e) {
const eventData = {
file: e.file,
sender: e.sender,
preventDefault: e.preventDefault,
isDefaultPrevented: e.isDefaultPrevented,
promise: convertSpreadsheetDeferredToJQueryDeferred(e.deferred),
_defaultPrevented: e._defaultPrevented
};
if (this.trigger("excelImport", eventData)) e.preventDefault();
else this._initProgress(e.deferred);
},
_initProgress: function(deferred) {
let loading = $("<div class='k-loading-mask' style='width: 100%; height: 100%; top: 0;'><div class='k-loading-color'></div></div>").appendTo(this.element);
let pb = $("<div class='k-loading-progress'>").appendTo(loading).kendoProgressBar({
type: "chunk",
chunkCount: 10,
min: 0,
max: 1,
value: 0
}).data("kendoProgressBar");
deferred.progress(function(e) {
pb.value(e.progress);
}).promise.finally(function() {
kendo.destroy(loading);
loading.remove();
});
},
_workbookPdfExport: function(e) {
if (this.trigger("pdfExport", e)) e.preventDefault();
},
_workbookInsertSheet: function(e) {
if (this.trigger("insertSheet", e)) e.preventDefault();
},
_workbookRemoveSheet: function(e) {
if (this.trigger("removeSheet", e)) e.preventDefault();
},
_workbookSelectSheet: function(e) {
if (this.trigger("selectSheet", e)) e.preventDefault();
},
_workbookRenameSheet: function(e) {
if (this.trigger("renameSheet", e)) e.preventDefault();
},
_workbookInsertRow: function(e) {
if (this.trigger("insertRow", e)) e.preventDefault();
},
_workbookInsertColumn: function(e) {
if (this.trigger("insertColumn", e)) e.preventDefault();
},
_workbookDeleteRow: function(e) {
if (this.trigger("deleteRow", e)) e.preventDefault();
},
_workbookDeleteColumn: function(e) {
if (this.trigger("deleteColumn", e)) e.preventDefault();
},
_workbookHideRow: function(e) {
if (this.trigger("hideRow", e)) e.preventDefault();
},
_workbookHideColumn: function(e) {
if (this.trigger("hideColumn", e)) e.preventDefault();
},
_workbookUnhideRow: function(e) {
if (this.trigger("unhideRow", e)) e.preventDefault();
},
_workbookUnhideColumn: function(e) {
if (this.trigger("unhideColumn", e)) e.preventDefault();
},
_workbookSelect: function(e) {
this.trigger("select", e);
},
_workbookChangeFormat: function(e) {
this.trigger("changeFormat", e);
},
_workbookDataBinding: function(e) {
if (this.trigger("dataBinding", e)) e.preventDefault();
},
_workbookDataBound: function(e) {
this.trigger("dataBound", e);
},
_workbookProgress: function(e) {
kendo.ui.progress(this.element, e.toggle);
},
_bindWorkbookEvents: function() {
this.spreadsheetRef.bind("render", this._workbookRender.bind(this));
this.spreadsheetRef.bind("cut", this._workbookCut.bind(this));
this.spreadsheetRef.bind("copy", this._workbookCopy.bind(this));
this.spreadsheetRef.bind("paste", this._workbookPaste.bind(this));
this.spreadsheetRef.bind("changing", this._workbookChanging.bind(this));
this.spreadsheetRef.bind("change", this._workbookChange.bind(this));
this.spreadsheetRef.bind("excelExport", this._workbookExcelExport.bind(this));
this.spreadsheetRef.bind("excelImport", this._workbookExcelImport.bind(this));
this.spreadsheetRef.bind("pdfExport", this._workbookPdfExport.bind(this));
this.spreadsheetRef.bind("insertSheet", this._workbookInsertSheet.bind(this));
this.spreadsheetRef.bind("removeSheet", this._workbookRemoveSheet.bind(this));
this.spreadsheetRef.bind("selectSheet", this._workbookSelectSheet.bind(this));
this.spreadsheetRef.bind("renameSheet", this._workbookRenameSheet.bind(this));
this.spreadsheetRef.bind("insertRow", this._workbookInsertRow.bind(this));
this.spreadsheetRef.bind("insertColumn", this._workbookInsertColumn.bind(this));
this.spreadsheetRef.bind("deleteRow", this._workbookDeleteRow.bind(this));
this.spreadsheetRef.bind("deleteColumn", this._workbookDeleteColumn.bind(this));
this.spreadsheetRef.bind("hideRow", this._workbookHideRow.bind(this));
this.spreadsheetRef.bind("hideColumn", this._workbookHideColumn.bind(this));
this.spreadsheetRef.bind("unhideRow", this._workbookUnhideRow.bind(this));
this.spreadsheetRef.bind("unhideColumn", this._workbookUnhideColumn.bind(this));
this.spreadsheetRef.bind("select", this._workbookSelect.bind(this));
this.spreadsheetRef.bind("changeFormat", this._workbookChangeFormat.bind(this));
this.spreadsheetRef.bind("dataBinding", this._workbookDataBinding.bind(this));
this.spreadsheetRef.bind("dataBound", this._workbookDataBound.bind(this));
this.spreadsheetRef.bind("progress", this._workbookProgress.bind(this));
},
destroy: function() {
kendo.ui.Widget.fn.destroy.call(this);
this._formulaBarInputRefPopup?.destroy();
this._formulaCellInputRefPopup?.destroy();
this._formulaBarInputRefList?.destroy();
this._formulaCellInputRefList?.destroy();
this._formulaBarInputRefList = this._formulaCellInputRefList = null;
this._formulaBarInputRefPopup = this._formulaCellInputRefPopup = null;
if (this.menu) this.menu.destroy();
if (this.toolbar) this.toolbar.destroy();
if (this.sheetsBar) this.sheetsBar.destroy();
this._dialogs?.forEach(function(dialog) {
dialog?.destroy();
});
this.spreadsheetRef?.destroy();
this._cellContextMenu?.destroy();
this._rowHeaderContextMenu?.destroy();
this._colHeaderContextMenu?.destroy();
this._drawingContextMenu?.destroy();
this._cellContextMenu = this._rowHeaderContextMenu = this._colHeaderContextMenu = this._drawingContextMenu = null;
if (this._resizeHandler) $(window).off("resize.kendoSpreadsheet", this._resizeHandler);
kendo.destroy(this.element);
},
options: {
name: "Spreadsheet",
toolbar: true,
sheetsbar: true,
rows: 200,
columns: 50,
rowHeight: 30,
columnWidth: 64,
headerHeight: 30,
headerWidth: 32,
excel: {
proxyURL: "",
fileName: "Workbook.xlsx"
},
messages: {},
pdf: {
area: "workbook",
fileName: "Workbook.pdf",
proxyURL: "",
paperSize: "a4",
landscape: true,
margin: null,
title: null,
author: null,
subject: null,
keywords: null,
creator: "Kendo UI PDF Generator v." + kendo.version,
date: null
},
defaultCellStyle: {
fontFamily: "Arial",
fontSize: 12
},
useCultureDecimals: false
},
defineName: function(name, value, hidden) {
return this.spreadsheetRef.defineName(name, value, hidden);
},
undefineName: function(name) {
return this.spreadsheetRef.undefineName(name);
},
nameValue: function(name) {
return this.spreadsheetRef.nameValue(name);
},
forEachName: function(func) {
return this.spreadsheetRef.forEachName(func);
},
cellContextMenu: function() {
return this._cellContextMenu;
},
rowHeaderContextMenu: function() {
return this._rowHeaderContextMenu;
},
colHeaderContextMenu: function() {
return this._colHeaderContextMenu;
},
addImage: function(image) {
return this.spreadsheetRef.addImage(image);
},
cleanupImages: function() {
return this.spreadsheetRef.cleanupImages();
},
events: [
"cut",
"copy",
"paste",
"pdfExport",
"excelExport",
"excelImport",
"changing",
"change",
"render",
"removeSheet",
"selectSheet",
"renameSheet",
"insertRow",
"insertColumn",
"deleteRow",
"insertSheet",
"deleteColumn",
"hideRow",
"hideColumn",
"unhideRow",
"unhideColumn",
"select",
"changeFormat",
"dataBinding",
"dataBound",
"kendoKeydown"
]
});
kendo.ui.plugin(Spreadsheet);
$.extend(true, Spreadsheet, { classNames });
})(window.kendo);
var kendo_spreadsheet_default = kendo;
//#endregion
exports.__meta__ = __meta__;
exports.default = kendo_spreadsheet_default;