Adding edittable version 2023-01-14 (66785d9).
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
51b386fcf7
commit
778f9ac0bf
101 changed files with 56770 additions and 0 deletions
210
plugins/55/edittable/script/contextmenu.js
Normal file
210
plugins/55/edittable/script/contextmenu.js
Normal file
|
@ -0,0 +1,210 @@
|
|||
/* global LANG */
|
||||
|
||||
window.edittable = window.edittable || {};
|
||||
|
||||
(function (edittable) {
|
||||
'use strict';
|
||||
/**
|
||||
* create an iterable array of selected cells from the selection object
|
||||
*
|
||||
* @param {object} selection the selection object
|
||||
*
|
||||
* @returns {Array} an array of the rows/columns of the cells in the selection
|
||||
*/
|
||||
edittable.cellArray = function (selection) {
|
||||
var selectionArray = [];
|
||||
for (var currentRow = selection.start.row; currentRow <= selection.end.row; currentRow += 1) {
|
||||
for (var currentCol = selection.start.col; currentCol <= selection.end.col; currentCol += 1) {
|
||||
selectionArray.push({row: currentRow, col: currentCol});
|
||||
}
|
||||
}
|
||||
return selectionArray;
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines our own contextMenu with custom callbacks
|
||||
*
|
||||
* @param {function} getData get the current data array
|
||||
* @param {function} getMeta get the current meta array
|
||||
* @returns {object} the context menu object
|
||||
*/
|
||||
edittable.getEditTableContextMenu = function (getData, getMeta) {
|
||||
return {
|
||||
items: {
|
||||
toggle_header: {
|
||||
name: LANG.plugins.edittable.toggle_header,
|
||||
callback: function (key, selection) {
|
||||
var meta = getMeta();
|
||||
jQuery.each(edittable.cellArray(selection), function (index, cell) {
|
||||
var col = cell.col;
|
||||
var row = cell.row;
|
||||
|
||||
if (meta[row][col].tag && meta[row][col].tag === 'th') {
|
||||
meta[row][col].tag = 'td';
|
||||
} else {
|
||||
meta[row][col].tag = 'th';
|
||||
}
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
},
|
||||
align_left: {
|
||||
name: LANG.plugins.edittable.align_left,
|
||||
callback: function (key, selection) {
|
||||
var meta = getMeta();
|
||||
jQuery.each(edittable.cellArray(selection), function (index, cell) {
|
||||
var col = cell.col;
|
||||
var row = cell.row;
|
||||
meta[row][col].align = 'left';
|
||||
});
|
||||
this.render();
|
||||
},
|
||||
disabled: function () {
|
||||
var meta = getMeta();
|
||||
var selection = this.getSelected();
|
||||
var row = selection[0];
|
||||
var col = selection[1];
|
||||
return (!meta[row][col].align || meta[row][col].align === 'left');
|
||||
}
|
||||
},
|
||||
align_center: {
|
||||
name: LANG.plugins.edittable.align_center,
|
||||
callback: function (key, selection) {
|
||||
var meta = getMeta();
|
||||
jQuery.each(edittable.cellArray(selection), function (index, cell) {
|
||||
var col = cell.col;
|
||||
var row = cell.row;
|
||||
meta[row][col].align = 'center';
|
||||
});
|
||||
this.render();
|
||||
},
|
||||
disabled: function () {
|
||||
var meta = getMeta();
|
||||
var selection = this.getSelected();
|
||||
var row = selection[0];
|
||||
var col = selection[1];
|
||||
return (meta[row][col].align && meta[row][col].align === 'center');
|
||||
}
|
||||
},
|
||||
align_right: {
|
||||
name: LANG.plugins.edittable.align_right,
|
||||
callback: function (key, selection) {
|
||||
var meta = getMeta();
|
||||
jQuery.each(edittable.cellArray(selection), function (index, cell) {
|
||||
var col = cell.col;
|
||||
var row = cell.row;
|
||||
meta[row][col].align = 'right';
|
||||
});
|
||||
this.render();
|
||||
},
|
||||
disabled: function () {
|
||||
var meta = getMeta();
|
||||
var selection = this.getSelected();
|
||||
var row = selection[0];
|
||||
var col = selection[1];
|
||||
return (meta[row][col].align && meta[row][col].align === 'right');
|
||||
}
|
||||
},
|
||||
hsep1: '---------',
|
||||
row_above: {
|
||||
name: LANG.plugins.edittable.row_above
|
||||
},
|
||||
remove_row: {
|
||||
name: LANG.plugins.edittable.remove_row,
|
||||
/**
|
||||
* The same as the default action, but with confirmation
|
||||
*
|
||||
* @param {string} key key of the menu item
|
||||
* @param {object} selection the selection object
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
callback: function (key, selection) {
|
||||
if (window.confirm(LANG.plugins.edittable.confirmdeleterow)) {
|
||||
var amount = selection.end.row - selection.start.row + 1;
|
||||
this.alter('remove_row', selection.start.row, amount);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* do not show when this is the last row
|
||||
*
|
||||
* @return {boolean} true if the entry is to be disabled, false otherwise
|
||||
*/
|
||||
disabled: function () {
|
||||
var rowsInTable = this.countRows();
|
||||
var firstSelectedRow = this.getSelected()[0];
|
||||
var lastSelectedRow = this.getSelected()[2]; // fix magic number with destructuring once we drop IE11
|
||||
var allRowsSelected = firstSelectedRow === 0 && lastSelectedRow === rowsInTable - 1;
|
||||
return (rowsInTable <= 1 || allRowsSelected);
|
||||
}
|
||||
},
|
||||
row_below: {
|
||||
name: LANG.plugins.edittable.row_below
|
||||
},
|
||||
hsep2: '---------',
|
||||
col_left: {
|
||||
name: LANG.plugins.edittable.col_left
|
||||
},
|
||||
remove_col: {
|
||||
name: LANG.plugins.edittable.remove_col,
|
||||
/**
|
||||
* The same as the default action, but with confirmation
|
||||
*
|
||||
* @param {string} key key of the menu item
|
||||
* @param {object} selection the selection object
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
callback: function (key, selection) {
|
||||
if (window.confirm(LANG.plugins.edittable.confirmdeletecol)) {
|
||||
var amount = selection.end.col - selection.start.col + 1;
|
||||
this.alter('remove_col', selection.start.col, amount);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* do not show when this is the last row
|
||||
*
|
||||
* @return {boolean} true if the entry is to be disabled, false otherwise
|
||||
*/
|
||||
disabled: function () {
|
||||
var colsInTable = this.countCols();
|
||||
var firstSelectedColumn = this.getSelected()[1];
|
||||
var lastSelectedColumn = this.getSelected()[3]; // fix magic number with destructuring once we drop IE11
|
||||
var allColsSelected = firstSelectedColumn === 0 && lastSelectedColumn === colsInTable - 1;
|
||||
return (colsInTable <= 1 || allColsSelected);
|
||||
}
|
||||
},
|
||||
col_right: {
|
||||
name: LANG.plugins.edittable.col_right
|
||||
},
|
||||
hsep3: '---------',
|
||||
mergeCells: {
|
||||
name: function () {
|
||||
var sel = this.getSelected();
|
||||
var info = this.mergeCells.mergedCellInfoCollection.getInfo(sel[0], sel[1]);
|
||||
if (info) {
|
||||
return '<div class="unmerge">' + LANG.plugins.edittable.unmerge_cells + '</div>';
|
||||
} else {
|
||||
return '<div class="merge">' + LANG.plugins.edittable.merge_cells + '</div>';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* disable if only one cell is selected
|
||||
*
|
||||
* @return {boolean} true if the entry is to be disabled, false otherwise
|
||||
*/
|
||||
disabled: function () {
|
||||
var selection = this.getSelected();
|
||||
var startRow = selection[0];
|
||||
var startCol = selection[1];
|
||||
var endRow = selection[2];
|
||||
var endCol = selection[3];
|
||||
return startRow === endRow && startCol === endCol;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}(window.edittable));
|
25
plugins/55/edittable/script/editbutton.js
Normal file
25
plugins/55/edittable/script/editbutton.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
* Adjust the top margin and make buttons visible
|
||||
*/
|
||||
jQuery(function () {
|
||||
'use strict';
|
||||
var $editbutton = jQuery('.dokuwiki div.editbutton_table');
|
||||
if (!$editbutton.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// unhide the buttons - we have JavaScript
|
||||
$editbutton.show();
|
||||
|
||||
// determine the bottom margin of the table above and remove it from our button
|
||||
var margin = 0;
|
||||
var $tablediv = $editbutton.prev('div.table');
|
||||
if (!$tablediv.length) {
|
||||
return;
|
||||
}
|
||||
margin += parseFloat($tablediv.css('margin-bottom'));
|
||||
margin += parseFloat($tablediv.find('table').css('margin-bottom'));
|
||||
margin += 1; // for the border
|
||||
|
||||
$editbutton.css('margin-top', margin * -1);
|
||||
});
|
585
plugins/55/edittable/script/editor.js
Normal file
585
plugins/55/edittable/script/editor.js
Normal file
|
@ -0,0 +1,585 @@
|
|||
/* global initToolbar */
|
||||
|
||||
window.edittable = window.edittable || {};
|
||||
window.edittable_plugins = window.edittable_plugins || {};
|
||||
|
||||
(function (edittable, edittable_plugins) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {Array} movingRowIndexes the indices of the rows to be moved
|
||||
* @param {int} target the row where the rows will be inserted
|
||||
* @param {Array} dmarray the data or meta array
|
||||
*
|
||||
* @return {Array} the new data or meta array
|
||||
*/
|
||||
edittable.moveRow = function moveRow(movingRowIndexes, target, dmarray) {
|
||||
var startIndex = movingRowIndexes[0];
|
||||
var endIndex = movingRowIndexes[movingRowIndexes.length - 1];
|
||||
var moveForward = target < startIndex;
|
||||
|
||||
var first = dmarray.slice(0, Math.min(startIndex, target));
|
||||
var moving = dmarray.slice(startIndex, endIndex + 1);
|
||||
var between;
|
||||
if (moveForward) {
|
||||
between = dmarray.slice(target, startIndex);
|
||||
} else {
|
||||
between = dmarray.slice(endIndex + 1, target);
|
||||
}
|
||||
var last = dmarray.slice(Math.max(endIndex + 1, target));
|
||||
if (moveForward) {
|
||||
return [].concat(first, moving, between, last);
|
||||
}
|
||||
return [].concat(first, between, moving, last);
|
||||
};
|
||||
|
||||
edittable.addRowToMeta = function (index, amount, metaArray) {
|
||||
var i;
|
||||
var cols = 1; // minimal number of cells
|
||||
if (metaArray[0]) {
|
||||
cols = metaArray[0].length;
|
||||
}
|
||||
|
||||
// insert into meta array
|
||||
for (i = 0; i < amount; i += 1) {
|
||||
var newrow = Array.apply(null, new Array(cols)).map(function initializeRowMeta() {
|
||||
return { rowspan: 1, colspan: 1 };
|
||||
});
|
||||
metaArray.splice(index, 0, newrow);
|
||||
}
|
||||
|
||||
return metaArray;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array} movingColIndexes the indices of the columns to be moved
|
||||
* @param {int} target the column where the columns will be inserted
|
||||
* @param {Array} dmarray the data or meta array
|
||||
*
|
||||
* @return {Array} the new data or meta array
|
||||
*/
|
||||
edittable.moveCol = function moveCol(movingColIndexes, target, dmarray) {
|
||||
return dmarray.map(function (row) {
|
||||
return edittable.moveRow(movingColIndexes, target, row);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array} meta the meta array
|
||||
* @returns {Array} an array of the cells with a rowspan or colspan larger than 1
|
||||
*/
|
||||
edittable.getMerges = function (meta) {
|
||||
var merges = [];
|
||||
for (var row = 0; row < meta.length; row += 1) {
|
||||
for (var col = 0; col < meta[0].length; col += 1) {
|
||||
if (meta[row][col].hasOwnProperty('rowspan') && meta[row][col].rowspan > 1 ||
|
||||
meta[row][col].hasOwnProperty('colspan') && meta[row][col].colspan > 1) {
|
||||
var merge = {};
|
||||
merge.row = row;
|
||||
merge.col = col;
|
||||
merge.rowspan = meta[row][col].rowspan;
|
||||
merge.colspan = meta[row][col].colspan;
|
||||
merges.push(merge);
|
||||
}
|
||||
}
|
||||
}
|
||||
return merges;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array} merges an array of the cells that are part of a merge
|
||||
* @param {int} target the target column or row
|
||||
* @param {string} direction whether we're trying to move a col or row
|
||||
*
|
||||
* @return {bool} wether the target col/row is part of a merge
|
||||
*/
|
||||
edittable.isTargetInMerge = function isTargetInMerge(merges, target, direction) {
|
||||
return merges.some(function (merge) {
|
||||
return (merge[direction] < target && target < merge[direction] + merge[direction + 'span']);
|
||||
});
|
||||
};
|
||||
|
||||
edittable.loadEditor = function () {
|
||||
var $container = jQuery('#edittable__editor');
|
||||
if (!$container.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $form = jQuery('#dw__editform');
|
||||
var $datafield = $form.find('input[name=edittable_data]');
|
||||
var $metafield = $form.find('input[name=edittable_meta]');
|
||||
|
||||
var data = JSON.parse($datafield.val());
|
||||
var meta = JSON.parse($metafield.val());
|
||||
|
||||
/**
|
||||
* Get the current meta array
|
||||
*
|
||||
* @return {array} the current meta array as array of rows with arrays of columns with objects
|
||||
*/
|
||||
function getMeta() {return meta;}
|
||||
|
||||
/**
|
||||
* Get the current data array
|
||||
*
|
||||
* @return {array} the current data array as array of rows with arrays of columns with strings
|
||||
*/
|
||||
function getData() {return data;}
|
||||
|
||||
var merges = edittable.getMerges(meta);
|
||||
if (merges === []) {
|
||||
merges = true;
|
||||
}
|
||||
var lastselect = { row: 0, col: 0 };
|
||||
|
||||
var handsontable_config = {
|
||||
data: data,
|
||||
startRows: 5,
|
||||
startCols: 5,
|
||||
colHeaders: true,
|
||||
rowHeaders: true,
|
||||
manualColumnResize: true,
|
||||
outsideClickDeselects: false,
|
||||
contextMenu: edittable.getEditTableContextMenu(getData, getMeta),
|
||||
manualColumnMove: true,
|
||||
manualRowMove: true,
|
||||
mergeCells: merges,
|
||||
|
||||
|
||||
/**
|
||||
* Attach pointers to our raw data structures in the instance
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
afterLoadData: function () {
|
||||
var i;
|
||||
this.raw = {
|
||||
data: data,
|
||||
meta: meta,
|
||||
colinfo: [],
|
||||
rowinfo: []
|
||||
};
|
||||
for (i = 0; i < data.length; i += 1) {
|
||||
this.raw.rowinfo[i] = {};
|
||||
}
|
||||
for (i = 0; i < data[0].length; i += 1) {
|
||||
this.raw.colinfo[i] = {};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* initialize cell properties
|
||||
*
|
||||
* properties are stored in extra array
|
||||
*
|
||||
* @param {int} row the row of the desired column
|
||||
* @param {int} col the col of the desired column
|
||||
* @returns {Array} the respective cell from the meta array
|
||||
*/
|
||||
cells: function (row, col) {
|
||||
return meta[row][col];
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom cell renderer
|
||||
*
|
||||
* It handles all our custom meta attributes like alignments and rowspans
|
||||
*
|
||||
* @param {object} instance the handsontable instance
|
||||
* @param {HTMLTableCellElement} td the dom node of the cell
|
||||
* @param {int} row the row of the cell to be rendered
|
||||
* @param {int} col the column of the cell to be rendered
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
renderer: function (instance, td, row, col) {
|
||||
// for some reason, neither cellProperties nor instance.getCellMeta() give the right data
|
||||
var cellMeta = meta[row][col];
|
||||
var $td = jQuery(td);
|
||||
|
||||
if (cellMeta.colspan) {
|
||||
$td.attr('colspan', cellMeta.colspan);
|
||||
} else {
|
||||
$td.removeAttr('colspan');
|
||||
}
|
||||
|
||||
if (cellMeta.rowspan) {
|
||||
$td.attr('rowspan', cellMeta.rowspan);
|
||||
} else {
|
||||
$td.removeAttr('rowspan');
|
||||
}
|
||||
|
||||
if (cellMeta.hide) {
|
||||
$td.hide();
|
||||
} else {
|
||||
$td.show();
|
||||
}
|
||||
|
||||
if (cellMeta.align === 'right') {
|
||||
$td.addClass('right');
|
||||
$td.removeClass('center');
|
||||
} else if (cellMeta.align === 'center') {
|
||||
$td.addClass('center');
|
||||
$td.removeClass('right');
|
||||
} else {
|
||||
$td.removeClass('center');
|
||||
$td.removeClass('right');
|
||||
}
|
||||
|
||||
if (cellMeta.tag === 'th') {
|
||||
$td.addClass('header');
|
||||
} else {
|
||||
$td.removeClass('header');
|
||||
}
|
||||
|
||||
/* globals Handsontable */
|
||||
Handsontable.renderers.TextRenderer.apply(this, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialization after the Editor loaded
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
afterInit: function () {
|
||||
// select first cell
|
||||
this.selectCell(0, 0);
|
||||
|
||||
// we need an ID on the input field
|
||||
jQuery('textarea.handsontableInput').attr('id', 'handsontable__input');
|
||||
|
||||
// we're ready to intialize the toolbar now
|
||||
initToolbar('tool__bar', 'handsontable__input', window.toolbar, false);
|
||||
|
||||
// we wrap DokuWiki's pasteText() here to get notified when the toolbar inserted something into our editor
|
||||
var original_pasteText = window.pasteText;
|
||||
window.pasteText = function (selection, text, opts) {
|
||||
original_pasteText(selection, text, opts); // do what pasteText does
|
||||
// trigger resize
|
||||
jQuery('#handsontable__input').data('AutoResizer').check();
|
||||
};
|
||||
window.pasteText = original_pasteText;
|
||||
|
||||
/*
|
||||
This is a workaround to rerender the table. It serves two functions:
|
||||
1: On wide tables with linebreaks in columns with no pre-defined table widths (via the tablelayout plugin)
|
||||
reset the width of the table columns to what is needed by its no narrower content
|
||||
2: On table with some rows fixed at the top, ensure that the content of these rows stays at the top as well,
|
||||
not only the lefthand rownumbers
|
||||
Attaching this to the event 'afterRenderer' did not have the desired results, as it seemed not to work for
|
||||
usecase 1 at all and for usecase 2 only with a delay.
|
||||
*/
|
||||
var _this = this;
|
||||
this.addHookOnce('afterOnCellMouseOver', function () {
|
||||
_this.updateSettings({});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* This recalculates the col and row spans and makes sure all correct cells are hidden
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
beforeRender: function () {
|
||||
var row, r, c, col, i;
|
||||
|
||||
// reset row and column infos - we store spanning info there
|
||||
this.raw.rowinfo = [];
|
||||
this.raw.colinfo = [];
|
||||
for (i = 0; i < data.length; i += 1) {
|
||||
this.raw.rowinfo[i] = {};
|
||||
}
|
||||
for (i = 0; i < data[0].length; i += 1) {
|
||||
this.raw.colinfo[i] = {};
|
||||
}
|
||||
|
||||
// unhide all cells
|
||||
for (row = 0; row < data.length; row += 1) {
|
||||
for (col = 0; col < data[0].length; col += 1) {
|
||||
if (meta[row][col].hide) {
|
||||
meta[row][col].hide = false;
|
||||
data[row][col] = '';
|
||||
}
|
||||
// unset all row/colspans
|
||||
meta[row][col].colspan = 1;
|
||||
meta[row][col].rowspan = 1;
|
||||
|
||||
// make sure no data cell is undefined/null
|
||||
if (!data[row][col]) {
|
||||
data[row][col] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var merge = 0; merge < this.mergeCells.mergedCellInfoCollection.length; merge += 1) {
|
||||
row = this.mergeCells.mergedCellInfoCollection[merge].row;
|
||||
col = this.mergeCells.mergedCellInfoCollection[merge].col;
|
||||
var colspan = this.mergeCells.mergedCellInfoCollection[merge].colspan;
|
||||
var rowspan = this.mergeCells.mergedCellInfoCollection[merge].rowspan;
|
||||
meta[row][col].colspan = colspan;
|
||||
meta[row][col].rowspan = rowspan;
|
||||
|
||||
// hide the cells hidden by the row/colspan
|
||||
|
||||
for (r = row; r < row + rowspan; r += 1) {
|
||||
for (c = col; c < col + colspan; c += 1) {
|
||||
if (r === row && c === col) {
|
||||
continue;
|
||||
}
|
||||
meta[r][c].hide = true;
|
||||
meta[r][c].rowspan = 1;
|
||||
meta[r][c].colspan = 1;
|
||||
if (data[r][c] && data[r][c] !== ':::') {
|
||||
data[row][col] += ' ' + data[r][c];
|
||||
}
|
||||
if (r === row) {
|
||||
data[r][c] = '';
|
||||
} else {
|
||||
data[r][c] = ':::';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clone data object
|
||||
// Since we can't use real line breaks (\n) inside table cells, this object is used to store all cell values with DokuWiki's line breaks (\\) instead of actual ones.
|
||||
var dataLBFixed = jQuery.extend(true, {}, data);
|
||||
|
||||
// In dataLBFixed, replace all actual line breaks with DokuWiki line breaks
|
||||
// In data, replace all DokuWiki line breaks with actual ones so the editor displays line breaks properly
|
||||
for (row = 0; row < data.length; row += 1) {
|
||||
for (col = 0; col < data[0].length; col += 1) {
|
||||
dataLBFixed[row][col] = data[row][col].replace(/(\r\n|\n|\r)/g, '\\\\ ');
|
||||
data[row][col] = data[row][col].replace(/\\\\\s/g, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
// Store dataFixed and meta back in the form
|
||||
$datafield.val(JSON.stringify(dataLBFixed));
|
||||
$metafield.val(JSON.stringify(meta));
|
||||
},
|
||||
|
||||
/**
|
||||
* Disable key handling while the link wizard or any other dialog is visible
|
||||
*
|
||||
* @param {event} e the keydown event object
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
beforeKeyDown: function (e) {
|
||||
if (jQuery('.ui-dialog:visible').length) {
|
||||
e.stopImmediatePropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
|
||||
beforeColumnMove: function (movingCols, target) {
|
||||
var disallowMove = edittable.isTargetInMerge(this.mergeCells.mergedCellInfoCollection, target, 'col');
|
||||
if (disallowMove) {
|
||||
return false;
|
||||
}
|
||||
meta = edittable.moveCol(movingCols, target, meta);
|
||||
data = edittable.moveCol(movingCols, target, data);
|
||||
this.updateSettings({ mergeCells: edittable.getMerges(meta), data: data });
|
||||
return false;
|
||||
},
|
||||
|
||||
beforeRowMove: function (movingRows, target) {
|
||||
var disallowMove = edittable.isTargetInMerge(this.mergeCells.mergedCellInfoCollection, target, 'row');
|
||||
if (disallowMove) {
|
||||
return false;
|
||||
}
|
||||
meta = edittable.moveRow(movingRows, target, meta);
|
||||
data = edittable.moveRow(movingRows, target, data);
|
||||
this.updateSettings({ mergeCells: edittable.getMerges(meta), data: data });
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update meta data array when rows are added
|
||||
*
|
||||
* @param {int} index the index where the new rows are created
|
||||
* @param {int} amount the number of new rows that are created
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
afterCreateRow: function (index, amount) {
|
||||
meta = edittable.addRowToMeta(index, amount, meta);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set id for toolbar to current handsontable input textarea
|
||||
*
|
||||
* For some reason (bug?), handsontable creates a new div.handsontableInputHolder with a new textarea and
|
||||
* ignores the old one. For the toolbar to keep working we need make sure the currently used textarea has
|
||||
* also the id `handsontable__input`.
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
afterBeginEditing: function () {
|
||||
if (jQuery('textarea.handsontableInput').length > 1) {
|
||||
jQuery('textarea.handsontableInput:not(:last)').remove();
|
||||
jQuery('textarea.handsontableInput').attr('id', 'handsontable__input');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update meta data array when rows are removed
|
||||
*
|
||||
* @param {int} index the index where the rows are removed
|
||||
* @param {int} amount the number of rows that are removed
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
afterRemoveRow: function (index, amount) {
|
||||
meta.splice(index, amount);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update meta data array when columns are added
|
||||
*
|
||||
* @param {int} index the index where the new columns are created
|
||||
* @param {int} amount the number of new columns that are created
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
afterCreateCol: function (index, amount) {
|
||||
for (var row = 0; row < data.length; row += 1) {
|
||||
for (var i = 0; i < amount; i += 1) {
|
||||
meta[row].splice(index, 0, { rowspan: 1, colspan: 1 });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update meta data array when columns are removed
|
||||
*
|
||||
* @param {int} index the index where the columns are removed
|
||||
* @param {int} amount the number of columns that are removed
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
afterRemoveCol: function (index, amount) {
|
||||
for (var row = 0; row < data.length; row += 1) {
|
||||
meta[row].splice(index, amount);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Skip hidden cells for selection
|
||||
*
|
||||
* @param {int} r the row of the selected cell
|
||||
* @param {int} c the column of the selected cell
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
afterSelection: function (r, c) {
|
||||
if (meta[r][c].hide) {
|
||||
// user navigated into a hidden cell! we need to find the next selectable cell
|
||||
var x = 0;
|
||||
|
||||
var v = r - lastselect.row;
|
||||
if (v > 0) {
|
||||
v = 1;
|
||||
}
|
||||
if (v < 0) {
|
||||
v = -1;
|
||||
}
|
||||
|
||||
var h = c - lastselect.col;
|
||||
if (h > 0) {
|
||||
h = 1;
|
||||
}
|
||||
if (h < 0) {
|
||||
h = -1;
|
||||
}
|
||||
|
||||
if (v !== 0) {
|
||||
x = r;
|
||||
// user navigated vertically
|
||||
do {
|
||||
x += v;
|
||||
if (!meta[x][c].hide) {
|
||||
// cell is selectable, do it
|
||||
this.selectCell(x, c);
|
||||
return;
|
||||
}
|
||||
|
||||
} while (x > 0 && x < data.length);
|
||||
// found no suitable cell
|
||||
this.deselectCell();
|
||||
} else if (h !== 0) {
|
||||
x = c;
|
||||
// user navigated horizontally
|
||||
do {
|
||||
x += h;
|
||||
if (!meta[r][x].hide) {
|
||||
// cell is selectable, do it
|
||||
this.selectCell(r, x);
|
||||
return;
|
||||
}
|
||||
|
||||
} while (x > 0 && x < data[0].length);
|
||||
// found no suitable cell
|
||||
this.deselectCell();
|
||||
}
|
||||
} else {
|
||||
// remember this selection
|
||||
lastselect.row = r;
|
||||
lastselect.col = c;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array} pasteData An array of arrays which contains data to paste.
|
||||
* @param {Array} coords An array of objects with ranges of the visual indexes (startRow, startCol, endRow, endCol)
|
||||
* that correspond to the previously selected area.
|
||||
* @return {true} always allowing the pasting
|
||||
*/
|
||||
beforePaste: function (pasteData, coords) {
|
||||
var startRow = coords[0].startRow;
|
||||
var startCol = coords[0].startCol;
|
||||
var totalRows = this.countRows();
|
||||
var totalCols = this.countCols();
|
||||
|
||||
var missingRows = (startRow + pasteData.length) - totalRows;
|
||||
var missingCols = (startCol + pasteData[0].length) - totalCols;
|
||||
if (missingRows > 0) {
|
||||
this.alter('insert_row', undefined, missingRows, 'paste');
|
||||
}
|
||||
if (missingCols > 0) {
|
||||
this.alter('insert_col', undefined, missingCols, 'paste');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
if (window.JSINFO.plugins.edittable['default columnwidth']) {
|
||||
handsontable_config.colWidths = window.JSINFO.plugins.edittable['default columnwidth'];
|
||||
}
|
||||
|
||||
|
||||
for (var plugin in edittable_plugins) {
|
||||
if (edittable_plugins.hasOwnProperty(plugin)) {
|
||||
if (typeof edittable_plugins[plugin].modifyHandsontableConfig === 'function') {
|
||||
edittable_plugins[plugin].modifyHandsontableConfig(handsontable_config, $form);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$container.handsontable(handsontable_config);
|
||||
|
||||
};
|
||||
|
||||
jQuery(document).ready(edittable.loadEditor);
|
||||
|
||||
}(window.edittable, window.edittable_plugins));
|
63
plugins/55/edittable/script/newtable.js
Normal file
63
plugins/55/edittable/script/newtable.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* exported addBtnActionNewTable */
|
||||
/**
|
||||
* Add button action for your toolbar button
|
||||
*
|
||||
* @param {jQuery} $btn Button element to add the action to
|
||||
* @param {Array} props Associative array of button properties
|
||||
* @param {string} edid ID of the editor textarea
|
||||
* @return {string} If button should be appended return the id for in aria-controls,
|
||||
* otherwise an empty string
|
||||
*/
|
||||
window.addBtnActionNewTable = function addBtnActionNewTable($btn, props, edid) {
|
||||
'use strict';
|
||||
|
||||
$btn.click(function () {
|
||||
var editform = jQuery('#dw__editform')[0];
|
||||
var ed = jQuery('#' + edid)[0];
|
||||
|
||||
/**
|
||||
* Add new textarea to the form
|
||||
*
|
||||
* @param {string} name the name attribute of the new field
|
||||
* @param {string} val the value attribute of the new field
|
||||
*
|
||||
* @return {void}
|
||||
*/
|
||||
function addField(name, val) {
|
||||
var pos_field = document.createElement('textarea');
|
||||
pos_field.name = 'edittable__new[' + name + ']';
|
||||
pos_field.value = val;
|
||||
pos_field.style.display = 'none';
|
||||
editform.appendChild(pos_field);
|
||||
}
|
||||
|
||||
var sel;
|
||||
if (window.DWgetSelection) {
|
||||
sel = window.DWgetSelection(ed);
|
||||
} else {
|
||||
sel = window.getSelection(ed);
|
||||
}
|
||||
addField('pre', ed.value.substr(0, sel.start));
|
||||
addField('text', ed.value.substr(sel.start, sel.end - sel.start));
|
||||
addField('suf', ed.value.substr(sel.end));
|
||||
|
||||
// adora belle requires a range, even though we handle ranging ourselve here
|
||||
var range = document.createElement('input');
|
||||
range.name = 'range';
|
||||
range.value = '0-0';
|
||||
range.type = 'hidden';
|
||||
editform.appendChild(range);
|
||||
|
||||
// Fake POST
|
||||
var editbutton = document.createElement('input');
|
||||
editbutton.name = 'do[edit]';
|
||||
editbutton.type = 'submit';
|
||||
editbutton.style.display = 'none';
|
||||
editform.appendChild(editbutton);
|
||||
// Prevent warning
|
||||
window.textChanged = false;
|
||||
editbutton.click();
|
||||
|
||||
});
|
||||
return 'click';
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue