I tried to use handsontable and want to add custom items to context menu.
There are many tutorials to implement custom menus, but it ignores the default items.
So I added keys of all items, but some of them don't work.
My setting is like follows.
var basicSettings = {
minRows: 1,
minCols: 1,
rowHeaders: false,
colHeaders: false,
hiddenColumns: true,
contextMenu: {
items: {
row_above: {},
row_below: {},
"hsep1": "---------",
col_left: {},
col_right: {},
"hsep2": "---------",
remove_row: {},
remove_col: {},
"hsep3": "---------",
undo: {},
redo: {},
"hsep4": "---------",
make_read_only: {},
"hsep5": "---------",
alignment: {},
"hsep6": "---------",
copy: {},
cut: {},
"paste": {
name: 'Paste',
callback: function (key, option) {
this.copyPaste.triggerPaste();
}
},
"hsep7": "---------",
mergeCells: {
name: "Merge"
},
"hsep8": "---------",
// Custom menu item to set color of cells
set_color: {
key: "color",
name: "Color",
"submenu": {
"items": [
{
key: "color:1",
"name": "Black",
callback: function(key, options) {
for (var i = options[0].start.row; i <= options[0].end.row; i ++){
for (var j = options[0].start.col; j <= options[0].end.col; j ++){
this.getCell(i, j).className = "color-black";
}
}
}
}, {
key: "color:2",
"name": "White",
callback: function(key, options) {
for (var i = options[0].start.row; i <= options[0].end.row; i ++){
for (var j = options[0].start.col; j <= options[0].end.col; j ++){
$(this.getCell(i, j)).removeClass("color-*").addClass("color-white");
}
}
this.render();
}
}, {
key: "color:3",
"name": "Red",
callback: function(key, options) {
for (var i = options[0].start.row; i <= options[0].end.row; i ++){
for (var j = options[0].start.col; j <= options[0].end.col; j ++){
this.getCell(i, j).style.backgroundColor = "red";
}
}
this.render();
}
}
]
}
}
}
},
manualRowResize: true,
manualColumnResize: true,
contextMenuCopyPaste: {
swfPath: '/bower_components/zeroclipboard/dist/ZeroClipboard.swf'
},
copyPaste: true,
mergeCells: true,
search: true,
stretchH: 'all',
autoColumnSize: {useHeaders: true},
autoRowSize: {syncLimit: 300},
width: 1000,
height: window.innerHeight - 100,
licenseKey: "xxxxx-xxxxx-xxxxx-xxxxx-xxxxx"
};
Menu looks like this.
Is there any way to add custom item with all the default menu items? If so, I don't need answers to Question 3 and Question 4.
The most important part that let me ask this question is custom menu, that is "set_color". After clicking "Black" or "Red", it turns into that color, but after I change value of a cell, it turns back. How can I prevent the cells from turning their background color back?
I want additional custom item besides all feature enabled. But I can't find proper key for "Merge" item. The current "Merge" function works so strangely. How to make the function works correctly?
I tried https://github.com/handsontable/handsontable/issues/2853 to implement paste functionality, but I see this error.
Uncaught TypeError: Cannot read property 'triggerPaste' of undefined
Please help me with those handsontable usage. Thanks in advance.
Is there any way to add custom item with all the default menu items? If so, I don't need answers to Question 3 and Question 4.
Handsontable
with contextMenu
set to a true
. Example:
let
example3 = document.getElementById('example3'),
settings3,
hot3;
settings3 = {
data: [...],
rowHeaders: true,
colHeaders: true,
contextMenu: true // set to `true`..
};
hot3 = new Handsontable(example3, settings3);
contextMenu
setting like this:
let cm = hot3.getPlugin('ContextMenu');
hot3.updateSettings({
contextMenu: {
// Clone the pre-defined items and add your custom items.
items: Object.assign({}, cm.itemsFactory.predefinedItems, {
'hsep1': '---------',
'set_color': {
key: 'color',
name: 'Color',
submenu: {
items: [{
key: 'color:red',
name: 'Red',
callback: setCellColor
}, {
key: 'color:blue',
name: 'Blue',
callback: setCellColor
}]
}
}
})
}
});
The most important part that let me ask this question is custom menu, that is "set_color". After clicking "Black" or "Red", it turns into that color, but after I change value of a cell, it turns back. How can I prevent the cells from turning their background color back?
I'm not sure how to prevent that; however, here's one way to restore the color (or any other custom/meta data..) of the appropriate cells.
// This is my callback for the 'set_color' context menu items.
// Sample `key`: 'color:red'
function setCellColor(key, opt) {
let color = key.substring(6);
for (let i = opt[0].start.row; i <= opt[0].end.row; i++) {
for (let j = opt[0].start.col; j <= opt[0].end.col; j++) {
this.getCell(i, j).style.color = color;
this.setCellMeta(i, j, 'color', color); // Save the color
}
}
}
// Listen to the `beforeRenderer` event, and restore the cell's color
// before the "renderer" starting rendering the cell
Handsontable.hooks.add('beforeRenderer', function(td, r, c, p, pv, cp){
if (cp.color) {
td.style.color = cp.color;
}
}, hot3);
Try the full example here: http://jsfiddle.net/y9j3m29c/1/, which is based on https://docs.handsontable.com/3.0.0/demo-context-menu.html#page-custom
SheetClip()
:
<script src="https://unpkg.com/sheetclip"></script>
let clipboardCache = '';
const sheetclip = new SheetClip();
settings3 = {
...
afterCopy: function(changes){
clipboardCache = sheetclip.stringify(changes);
},
afterCut: function(changes){
clipboardCache = sheetclip.stringify(changes);
},
afterPaste: function(changes){
clipboardCache = sheetclip.stringify(changes);
}
};
let cm = hot3.getPlugin('ContextMenu');
hot3.updateSettings({
contextMenu: {
// Clone the pre-defined items and add your custom items.
items: Object.assign({}, cm.itemsFactory.predefinedItems, {
...
'paste': {
name: 'Paste',
disabled: function(){
return clipboardCache.length === 0;
},
callback: function(){
var plugin = this.getPlugin('copyPaste');
this.listen();
plugin.paste(clipboardCache);
}
}
})
}
});
More details on https://docs.handsontable.com/3.0.0/demo-copy-paste.html#paste-in-context-menu and demo on http://jsfiddle.net/y9j3m29c/2/ — or http://jsfiddle.net/y9j3m29c/4/ which comes with a "Clear clipboard" functionality.