Commit 5b365708 authored by Mikolaï Krol's avatar Mikolaï Krol Committed by Mikolaï Krol

erp5_jexcel_editor: jexcel editor

added merging cells, more features in toolbar, horizontal scrollbar, searchbar in toolbar
parent 1266c706
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Folder" module="OFS.Folder"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>erp5_jexcel_editor</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>ERP5 Jexcel Editor</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
url_list = [
"renderjs.js",
"rsvp.js",
"jexcel.gadget.html",
"jexcel.gadget.js",
"fonts.ttf",
"icons.css",
"jexcel/jexcel.js",
"jexcel/jexcel.css",
"jexcel/jexcel.theme.css",
"jexcel/jexcel.webcomponent.js",
"jsuites/jsuites.js",
"jsuites/jsuites.css",
]
return url_list
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebSection_getJexcelEditorPrecacheManifestList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>fonts.ttf</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>font/ttf</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(fonts.ttf) format('truetype');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
}
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>icons.css</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/css</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Jexcel</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="jio.js"></script>
<script src="jexcel/jexcel.js"></script>
<script src="jsuites/jsuites.js"></script>
<link rel="stylesheet" href="jexcel/jexcel.css" type="text/css" />
<link rel="stylesheet" href="jsuites/jsuites.css" type="text/css" />
<link rel="stylesheet" href="icons.css" type="text/css" />
<script src="jexcel.gadget.js"></script>
</head>
<body>
<div class="spreadsheet"></div>
</body>
</html>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>jexcel.gadget.html</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/*jslint nomen: true, indent: 2 */
/*global window, rJS, RSVP, jexcel*/
(function (window, rJS, jexcel) {
"use strict";
rJS(window)
.setState({saveConfig: false})
.declareAcquiredMethod("notifyChange", "notifyChange")
.declareJob("deferNotifyChange", function () {
// Ensure error will be correctly handled
return this.notifyChange();
})
.declareMethod("render", function (options) {
var gadget = this;
return gadget.changeState(options);
})
.declareMethod('getContent', function () {
var gadget = this, form_data = {};
if (this.state.editable || true) {
form_data[this.state.key] = JSON.stringify(gadget.table.getConfig());
this.state.value = form_data[this.state.key];
}
return form_data;
})
.onStateChange(function (modification_dict) {
var template = {
minDimensions: [52, 300],
defaultColWidth: 100,
allowExport: true,
columnSorting: true,
columnDrag: true,
columnResize: true,
rowResize: true,
rowDrag: true,
editable: true,
allowInsertRow: true,
allowManualInsertRow: true,
allowInsertColumn: true,
allowManualInsertColumn: true,
allowDeleteRow: true,
allowRenameColumn: true,
allowComments: true,
selectionCopy: true,
search: true,
fullscreen: true,
//lazyLoading: true,
//loadingSpin: true,
//tableOverflow: true,
autoIncrement: true,
parseFormulas: true
},
gadget = this, tmp = Object.assign({}, template), table;
gadget.deferNotifyChangeBinded = gadget.deferNotifyChange.bind(gadget);
if (modification_dict.hasOwnProperty('value')) {
gadget.state.value = gadget.state.value === "" ? gadget.state.value : JSON.parse(gadget.state.value);
Object.assign(tmp, template);
Object.assign(tmp, gadget.state.value);
table = jexcel(gadget.element.querySelector(".spreadsheet"), Object.assign(tmp, {
onevent: function (ev) {
var exluded_events = ["onload", "onfocus", "onblur", "onselection"];
if (!exluded_events.includes(ev)) {
if ((ev === "onchangestyle" && gadget.state.saveConfig) || ev !== "onchangestyle") {
gadget.deferNotifyChangeBinded();
} else {
gadget.state.saveConfig = true;
}
}
},
toolbar: [
//undo
{
type: 'i',
content: 'undo',
onclick: function () {
table.undo();
}
},
//redo
{
type: 'i',
content: 'redo',
onclick: function () {
table.redo();
}
},
//merge cells
{
type: 'i',
content: 'table_chart',
onclick: function () {
var cell = gadget.element.querySelector("td.highlight-selected");
var x = Number(cell.dataset.x);
var selected = table.getJson(true);
var colspan = Object.keys(selected[0]).length;
var rowspan = selected.length;
var letter = "";
if (x <= 25) {
letter += String.fromCharCode(97 + x).toUpperCase();
}
else {
letter += String.fromCharCode(97 + Math.trunc(x / 25) - 1).toUpperCase();
letter += String.fromCharCode(97 + (x % 26)).toUpperCase();
}
var coor = letter + (Number(cell.dataset.y) + 1).toString();
table.setMerge(coor, colspan, rowspan);
}
},
//unmerge cell
{
type: 'i',
content: 'close',
onclick: function () {
var cell = gadget.element.querySelector("td.highlight-selected");
var x = Number(cell.dataset.x);
var letter = "";
if (x <= 25) {
letter += String.fromCharCode(97 + x).toUpperCase();
}
else {
letter += String.fromCharCode(97 + Math.trunc(x / 25) - 1).toUpperCase();
letter += String.fromCharCode(97 + (x % 26)).toUpperCase();
}
var coor = letter + (Number(cell.dataset.y) + 1).toString();
table.removeMerge(coor);
}
},
//destroy all merged cells
{
type: 'i',
content: 'cancel',
onclick: function () {
table.destroyMerged();
}
},
//font style
{
type: 'select',
k: 'font-family',
v: ['Arial', 'Comic Sans MS', 'Verdana', 'Calibri', 'Tahoma', 'Helvetica', 'DejaVu Sans', 'Times New Roman', 'Georgia', 'Antiqua']
},
//font size
{
type: 'select',
k: 'font-size',
v: ['9px', '10px', '11px', '12px', '13px', '14px', '15px', '16px', '17px', '18px', '19px', '20px', '22px', '24px', '26px', '28px', '30px']
},
//text align left
{
type: 'i',
content: 'format_align_left',
k: 'text-align',
v: 'left'
},
//text align center
{
type: 'i',
content: 'format_align_center',
k: 'text-align',
v: 'center'
},
//text align right
{
type: 'i',
content: 'format_align_right',
k: 'text-align',
v: 'right'
},
//text align justify
{
type: 'i',
content: 'format_align_justify',
k: 'text-align',
v: 'justify'
},
//vertical align top
{
type: 'i',
content: 'vertical_align_top',
k: 'vertical-align',
v: 'top'
},
//vertical align middle
{
type: 'i',
content: 'vertical_align_center',
k: 'vertical-align',
v: 'middle'
},
//vertical align bottom
{
type: 'i',
content: 'vertical_align_bottom',
k: 'vertical-align',
v: 'bottom'
},
//style bold
{
type: 'i',
content: 'format_bold',
k: 'font-weight',
v: 'bold'
},
//style underlined
{
type: 'i',
content: 'format_underlined',
k: 'text-decoration',
v: 'underline'
},
//style italic
{
type: 'i',
content: 'format_italic',
k: 'font-style',
v: 'italic'
},
//text color
{
type: 'color',
content: 'format_color_text',
k: 'color'
},
//background color
{
type: 'color',
content: 'format_color_fill',
k: 'background-color'
}
]
}));
gadget.table = table;
var filter = gadget.element.querySelector(".jexcel_filter");
gadget.element.querySelector(".jexcel_toolbar").appendChild(filter);
}
});
}(window, rJS, jexcel));
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>jexcel.gadget.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/javascript</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Folder" module="OFS.Folder"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>jexcel</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>jexcel.css</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/css</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>jexcel.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/x-javascript</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
:root {
--jexcel_header_color: #888;
--jexcel_header_color_highlighted: #444;
--jexcel_header_background: #313131;
--jexcel_header_background_highlighted: #777;
--jexcel_content_color: #777;
--jexcel_content_color_highlighted: #333;
--jexcel_content_background: #3e3e3e;
--jexcel_content_background_highlighted: #777;
--jexcel_menu_background: #7e7e7e;
--jexcel_menu_background_highlighted: #ebebeb;
--jexcel_menu_color: #ddd;
--jexcel_menu_color_highlighted: #222;
--jexcel_border_color: #5f5f5f;
--jexcel_border_color_highlighted: #999;
--active_color: #eee;
--active-color: var(--active_color);
}
.jexcel {
border-bottom: 1px solid var(--jexcel_border_color);
border-right: 1px solid var(--jexcel_border_color);
}
.jexcel > tbody > tr > td,
.jexcel > thead > tr > td {
border-top: 1px solid var(--jexcel_border_color);
border-left: 1px solid var(--jexcel_border_color);
background-color: var(--jexcel_content_background);
color: var(--jexcel_content_color);
}
.jexcel > tbody > tr > td:first-child,
.jexcel > thead > tr > td {
background-color: var(--jexcel_header_background);
color: var(--jexcel_header_color);
}
.jexcel > thead > tr > td.selected,
.jexcel > tbody > tr.selected > td:first-child {
background-color: var(--jexcel_header_background_highlighted);
color: var(--jexcel_header_color_highlighted);
}
.jexcel > tbody > tr > td.jexcel_cursor a {
color: var(--active-color);
}
.jexcel_pagination > div > div {
color: var(--jexcel_header_color);
background: var(--jexcel_header_background);
border: 1px solid var(--jexcel_border_color);
}
.jexcel_page,
.jexcel_container input,
.jexcel_container select {
color: var(--jexcel_header_color);
background: var(--jexcel_header_background);
border: 1px solid var(--jexcel_border_color);
}
.jexcel_contextmenu {
border: 1px solid var(--jexcel_border_color);
background: var(--jexcel_menu_background);
color: var(--jexcel_menu_color);
box-shadow: var(--jexcel_menu_box_shadow);
-webkit-box-shadow: var(--jexcel_menu_box_shadow);
-moz-box-shadow: var(--jexcel_menu_box_shadow);
}
.jexcel_contextmenu > div a {
color: var(--jexcel_menu_color);
}
.jexcel_contextmenu > div:not(.contextmenu-line):hover a {
color: var(--jexcel_menu_color_highlighted);
}
.jexcel_contextmenu > div:not(.contextmenu-line):hover {
background: var(--jexcel_menu_background_highlighted);
}
.jexcel_dropdown .jdropdown-container,
.jexcel_dropdown .jdropdown-content {
background-color: var(--jexcel_content_background);
color: var(--jexcel_content_color);
}
.jexcel_dropdown .jdropdown-item {
color: var(--jexcel_content_color);
}
.jexcel_dropdown .jdropdown-item:hover,
.jexcel_dropdown .jdropdown-selected,
.jexcel_dropdown .jdropdown-cursor {
background-color: var(--jexcel_content_background_highlighted);
color: var(--jexcel_content_color_highlighted);
}
.jexcel .jcalendar-content {
background-color: var(--jexcel_header_background);
color: var(--jexcel_header_color);
}
.jexcel .jcalendar-content > table {
background-color: var(--jexcel_content_background);
color: var(--jexcel_content_color);
}
.jexcel .jcalendar-weekday {
background-color: var(--jexcel_content_background_highlighted);
color: var(--jexcel_content_color_highlighted);
}
.jexcel .jcalendar-sunday {
color: var(--jexcel_header_color);
}
.jexcel .jcalendar-selected {
background-color: var(--jexcel_content_background_highlighted);
color: var(--jexcel_content_color_highlighted);
}
.jexcel_toolbar i.jexcel_toolbar_item {
color: var(--jexcel_content_color);
}
.jexcel_toolbar i.jexcel_toolbar_item:hover {
background: var(--jexcel_content_background_highlighted);
color: var(--jexcel_content_color_highlighted);
}
.jexcel_toolbar {
background: var(--jexcel_header_background);
}
.jexcel_content::-webkit-scrollbar-track {
background: var(--jexcel_background_head);
}
.jexcel_content::-webkit-scrollbar-thumb {
background: var(--jexcel_background_head_highlighted);
}
.jexcel_border_main {
border: 1px solid #000;
border-color: var(--jexcel_border_color_highlighted);
}
.jexcel .highlight {
background-color: var(--jexcel_content_background_highlighted);
}
.jexcel .highlight-bottom {
border-bottom: 1px solid var(--jexcel_border_color_highlighted);
}
.jexcel .highlight-right {
border-right: 1px solid var(--jexcel_border_color_highlighted);
}
.jexcel .highlight-left {
border-left: 1px solid var(--jexcel_border_color_highlighted);
}
.jexcel .highlight-top {
border-top: 1px solid var(--jexcel_border_color_highlighted);
}
.jexcel .copying-top {
border-top-color: var(--jexcel_border_color_highlighted);
}
.jexcel .copying-right {
border-right-color: var(--jexcel_border_color_highlighted);
}
.jexcel .copying-left {
border-left-color: var(--jexcel_border_color_highlighted);
}
.jexcel .copying-bottom {
border-bottom-color: var(--jexcel_border_color_highlighted);
}
.jexcel_border_main, .jexcel .highlight-top.highlight-left, .jexcel .highlight-top, .jexcel .highlight-left {
-webkit-box-shadow: unset;
box-shadow: unset;
}
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>jexcel.theme.css</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/css</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
class Jexcel extends HTMLElement {
constructor() {
super();
}
init(o) {
// Shadow root
const shadowRoot = this.attachShadow({mode: 'open'});
// Style
const cssJexcel = document.createElement('link');
cssJexcel.rel = 'stylesheet';
cssJexcel.type = 'text/css'
cssJexcel.href = 'jexcel.css';
shadowRoot.appendChild(cssJexcel);
const cssJsuites = document.createElement('link');
cssJsuites.rel = 'stylesheet';
cssJsuites.type = 'text/css'
cssJsuites.href = 'jsuites.css';
shadowRoot.appendChild(cssJsuites);
// Jexcel container
var container = document.createElement('div');
shadowRoot.appendChild(container);
// Garantee all elements are rendered
setTimeout(function() {
// Parse JSON
var config = JSON.parse(o.innerHTML);
// Root
config.root = shadowRoot;
// Reset container
o.innerHTML = '';
// Create jexcel element
jexcel(container, config);
}, 0);
}
connectedCallback() {
this.init(this);
}
disconnectedCallback() {
}
attributeChangedCallback() {
}
}
window.customElements.define('jexcel-spreadsheet', Jexcel);
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>jexcel.webcomponent.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/javascript</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Folder" module="OFS.Folder"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>jsuites</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>jsuites.css</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/css</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="File" module="OFS.Image"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>__name__</string> </key>
<value> <string>jsuites.js</string> </value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>application/x-javascript</string> </value>
</item>
<item>
<key> <string>precondition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
Spreadsheet editor with Jexcel library.
\ No newline at end of file
erp5_jexcel_editor
\ No newline at end of file
erp5_jexcel_editor
\ No newline at end of file
001
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment