How should I address this custom menu error? - menu

This error occurs when using my custom menu designed to clear a range of cells from 7 sheets within the same document. The code is as follows:
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menubuttons = [{name: "Clear Dock 1", functionName: "clearRange1()"},
{name: "Clear Dock 2", functionName: "clearRange2()"},
{name: "Clear Dock 3", functionName: "clearRange3()"},
{name: "Clear Dock 4", functionName: "clearRange4()"},
{name: "Clear Dock 5", functionName: "clearRange5()"},
{name: "Clear Dock 6", functionName: "clearRange6()"},
{name: "Clear Dock 7", functionName: "clearRange7()"}
];
function clearRange1() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Dock 1');
sheet.getRange('b2:j49').clearContent();
}
function clearRange2() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Dock 2');
sheet.getRange('b2:j49').clearContent();
}
function clearRange3() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Dock 3');
sheet.getRange('b2:j49').clearContent();
}
function clearRange4() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Dock 4');
sheet.getRange('b2:j49').clearContent();
}
function clearRange5() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Dock 5');
sheet.getRange('b2:j49').clearContent();
}
function clearRange6() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Dock 6');
sheet.getRange('b2:j49').clearContent();
}
function clearRange7() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Dock 7');
sheet.getRange('b2:j49').clearContent();
}}
I am very new to coding and I am eager to learn as I am developing a shipping/receiving schedule for my workplace. My code may contain a lot of errors and thus any corrections would be awesome :).
The issue persists whenever I press the buttons on my custom menu, as it gives me the error: "Script function not found: clearRange1() For more information, see https://developers.google.com/apps-script/reference/base/menu#addItem(String,String)", consistently. Any help would be greatly appreciated.
Thank you,

firstly I don't know how you got a custom menu unless you've omitted your code for that.
Below details how you would need to format to get a custom menu.
Secondly your functions should be separate from all the other functions. So an onOpen() function will close } , then you'll start another function which is separate. See below for the example you can expand upon :)
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('Clear Dock 1', 'clearRange1')
.addItem('Clear Dock 2', 'clearRange2')
.addItem('Clear Dock 3', 'clearRange3')
.addItem('Clear Dock 4', 'clearRange4')
.addItem('Clear Dock 5', 'clearRange5')
.addItem('Clear Dock 6', 'clearRange6')
.addItem('Clear Dock 7', 'clearRange7')
.addToUi();
}
//you can put this outside your functions if you want it to work for all of them
var ss = SpreadsheetApp.getActive();
function clearRange1() {
var sheet = ss.getSheetByName('Sheet3');
sheet.getRange('B2:J49').clearContent();
}

Related

Header filtering - create Select field with down arrow

I am using Tabulator 5.x. I have a table with header filtering. The column in question is the last column "Transcribed". Is there a way to have the typical down arrow on the right side of the select box that shows the end user it is a drop down list similar to if you were using option in html? Rather than having to click on it filter field to see the choices.
I looked in documentation but do not see any examples using a down arrow. I also looked in the CSS, but did not anything if indeed it was there.
var table = new Tabulator("#transcription-table", {
height:"640px",
layout:"fitDataStretch",
ajaxURL:"get_transcriptions.php",
columns:[
{title:"ID", field:"id", headerSort:false, visible:false},
{title:"Song Title", field:"songtitle", width:350, sorter:"string", headerFilter:"input"},
{title:"Artist / Group", field:"artistgroup", widthGrow:1.5 ,sorter:"string", headerFilter:"input"},
{title:"Transcribed", field:"transcribed", widthGrow:1.2, sorter:"string", headerTooltip:"Transcribed into music notation", editor:"select", editorParams:{values:{"Yes":"Yes", "No":"No"}}, headerFilter:true, headerFilterParams:{values:{"Yes":"Yes", "No":"No", "":""}}},
]
});
Thank you.
You can create your own editor by extending editor module as
Tabulator.extendModule("edit", "editors", {
selectwithdrop: function (cell, onRendered, success, cancel, editorParams) {
var cellValue = cell.getValue().toUpperCase(),
input = document.createElement("select");
Object.keys(editorParams.values).forEach((key) => {
let option = document.createElement("option");
option.text = editorParams.values[key];
option.value = key;
input.add(option);
});
input.style.padding = "10px";
input.style.width = "100%";
input.style.boxSizing = "border-box";
input.style.border = "1px solid #4b4b4b";
input.style.borderRadius = "5px";
input.style.outline = "none";
input.value = cellValue;
// onRendered(function () {
// input.focus();
// input.style.height = "100%";
// });
function onChange(e) {
success(input.value);
}
//submit new value on blur or change
input.addEventListener("change", onChange);
// input.addEventListener("blur", onChange);
//submit new value on enter
return input;
},
});
Working Demo CodeSandBox

Chrome extension for selected text which matches a specific form [duplicate]

I am trying to create entries on the Chrome context menu based on what is selected.
I found several questions about this on Stackoverflow, and for all of them the answer is: use a content script with a "mousedown" listener that looks at the current selection and creates the Context Menu.
I implemented this, but it does not always work. Sometimes all the log messages say that the context menu was modified as I wanted, but the context menu that appears is not updated.
Based on this I suspected it was a race condition: sometimes chrome starts rendering the context menu before the code ran completely.
I tried adding a eventListener to "contextmenu" and "mouseup". The later triggers when the user selects the text with the mouse, so it changes the contextmenu much before it appears (even seconds). Even with this technique, I still see the same error happening!
This happens very often in Chrome 22.0.1229.94 (Mac), occasionally in Chromium 20.0.1132.47 (linux) and it did not happen in 2 minutes trying on Windows (Chrome 22.0.1229.94).
What is happening exactly? How can I fix that? Is there any other workaround?
Here is a simplified version of my code (not so simple because I am keeping the log messages):
manifest.json:
{
"name": "Test",
"version": "0.1",
"permissions": ["contextMenus"],
"content_scripts": [{
"matches": ["http://*/*", "https://*/*"],
"js": ["content_script.js"]
}],
"background": {
"scripts": ["background.js"]
},
"manifest_version": 2
}
content_script.js
function loadContextMenu() {
var selection = window.getSelection().toString().trim();
chrome.extension.sendMessage({request: 'loadContextMenu', selection: selection}, function (response) {
console.log('sendMessage callback');
});
}
document.addEventListener('mousedown', function(event){
if (event.button == 2) {
loadContextMenu();
}
}, true);
background.js
function SelectionType(str) {
if (str.match("^[0-9]+$"))
return "number";
else if (str.match("^[a-z]+$"))
return "lowercase string";
else
return "other";
}
chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {
console.log("msg.request = " + msg.request);
if (msg.request == "loadContextMenu") {
var type = SelectionType(msg.selection);
console.log("selection = " + msg.selection + ", type = " + type);
if (type == "number" || type == "lowercase string") {
console.log("Creating context menu with title = " + type);
chrome.contextMenus.removeAll(function() {
console.log("contextMenus.removeAll callback");
chrome.contextMenus.create(
{"title": type,
"contexts": ["selection"],
"onclick": function(info, tab) {alert(1);}},
function() {
console.log("ContextMenu.create callback! Error? " + chrome.extension.lastError);});
});
} else {
console.log("Removing context menu")
chrome.contextMenus.removeAll(function() {
console.log("contextMenus.removeAll callback");
});
}
console.log("handling message 'loadContextMenu' done.");
}
sendResponse({});
});
The contextMenus API is used to define context menu entries. It does not need to be called right before a context menu is opened. So, instead of creating the entries on the contextmenu event, use the selectionchange event to continuously update the contextmenu entry.
I will show a simple example which just displays the selected text in the context menu entry, to show that the entries are synchronized well.
Use this content script:
document.addEventListener('selectionchange', function() {
var selection = window.getSelection().toString().trim();
chrome.runtime.sendMessage({
request: 'updateContextMenu',
selection: selection
});
});
At the background, we're going to create the contextmenu entry only once. After that, we update the contextmenu item (using the ID which we get from chrome.contextMenus.create).
When the selection is empty, we remove the context menu entry if needed.
// ID to manage the context menu entry
var cmid;
var cm_clickHandler = function(clickData, tab) {
alert('Selected ' + clickData.selectionText + ' in ' + tab.url);
};
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.request === 'updateContextMenu') {
var type = msg.selection;
if (type == '') {
// Remove the context menu entry
if (cmid != null) {
chrome.contextMenus.remove(cmid);
cmid = null; // Invalidate entry now to avoid race conditions
} // else: No contextmenu ID, so nothing to remove
} else { // Add/update context menu entry
var options = {
title: type,
contexts: ['selection'],
onclick: cm_clickHandler
};
if (cmid != null) {
chrome.contextMenus.update(cmid, options);
} else {
// Create new menu, and remember the ID
cmid = chrome.contextMenus.create(options);
}
}
}
});
To keep this example simple, I assumed that there's only one context menu entry. If you want to support more entries, create an array or hash to store the IDs.
Tips
Optimization - To reduce the number of chrome.contextMenus API calls, cache the relevant values of the parameters. Then, use a simple === comparison to check whether the contextMenu item need to be created/updated.
Debugging - All chrome.contextMenus methods are asynchronous. To debug your code, pass a callback function to the .create, .remove or .update methods.
MDN doc for menus.create(), 'title' param
You can use "%s" in the string. If you do this in a menu item, and some text is selected in the page when the menu is shown, then the selected text will be interpolated into the title.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus/create
Thus
browser.contextMenus.create({
id: 'menu-search',
title: "Search '%s'", // selected text as %s
contexts: ['selection'], // show only if selection exist
})

Telegraf.js: leave WizardScene with a button

I would put a button after a message in a WizardScene with a "Cancel" Button. But i retrieve some error:
This is my wizard scene:
const superWizard = new WizardScene('super-wizard',
async ctx => {
ctx.wizard.state.data = {};
ctx.telegram.sendMessage(ctx.from.id, "Insert name", {
parse_mode: 'MarkdownV2',
reply_markup: cancelOrder()
})
return ctx.wizard.next();
},
ctx => {
ctx.wizard.state.data.name = ctx.message.text;
ctx.reply("here is your name: "+ctx.wizard.state.data.name);
return ctx.scene.leave();
}
);
const stage = new Stage([superWizard]);
bot.use(session());
bot.use(stage.middleware());
Here is my cancel order function:
function cancelOrder() {
const annullaBtn = Markup.inlineKeyboard([
Markup.callbackButton('CANCEL', `cancelOrder_btn`),
])
return annullaBtn;
}
and the button action:
bot.action("cancelOrder_btn", (ctx) => {
ctx.replyWithMarkdown(`Ordine *ANNULLATO* correttamente`)
return ctx.scene.leave('super-wizard');
});
The program writes correctly the text, and puts the button. But if i press "CANCEL" it gives error at:
ctx.wizard.state.data.name = ctx.message.text;
as "text is undefined" because i press cancel and i didn't write anything.
So how can i leave the scene without going forward, but if i write a text it goes forward in the wizardScene?
Thank you
Replace
ctx.message.text;
with
ctx.update.callback_query.data;
as there is no message returned by callback button

How to put selection text in chrome.contextMenus?

How can I add selection text in context.Menus?
I want to create a Chrome extension which will work similarly to the right-click search function in Google Chrome (i.e. right click on selected text -> "Search 'selection text')
I made a preview
I assume this is something with chrome.contextMenus.update but i don't know how to make it work
background.js:
chrome.runtime.onInstalled.addListener(function () {
var context = "selection";
var title = "Search";
var id = chrome.contextMenus.create({
"title": title,
"contexts": [context],
"id": "context" + context
});
});
// add click event
chrome.contextMenus.onClicked.addListener(onClickHandler);
// The onClicked callback function.
function onClickHandler(info, tab) {
var sText = info.selectionText;
var url = "https://www.google.com/search?source=hp&q=" + encodeURIComponent(sText);
window.open(url, '_blank');
};

Chrome Extension context menu, differentiate image and link event

In my chrome extension I'm adding two context items "Get link" and "Get Image". The main difference being when setting them both up they have the "context" of link and image respectively. But when right clicking on an image that is acting as a link you get the option of both:
when either of those are clicked the data that comes into the listener seems to be identical, I need to be able to differentiate the two to know if the context is that of an image or a link to handle them differently. Here is my code:
chrome.runtime.onInstalled.addListener(function() {
var context = "image";
var title = "Copy Image";
var id = chrome.contextMenus.create({"title": title, "contexts":[context],
"id": "context" + context});
});
chrome.runtime.onInstalled.addListener(function() {
var context = "link";
var title = "Copy link";
var id = chrome.contextMenus.create({"title": title, "contexts":[context],
"id": "context" + context});
});
chrome.contextMenus.onClicked.addListener(onClickHandler);
function onClickHandler(info, tab) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, {action: "imageAdded", subject: info.srcUrl}, function(response) {
});
If you want know which menu item was clicked, you can get the id value of the clicked context menu item in the menuItemId property of the object passed into the onClicked handler:
function onClickHandler(info, tab) {
console.log(info.menuItemId);
//...
}
Take a look at Parameter of onClicked callback, you could differentiate the image/link via mediaType
One of 'image', 'video', or 'audio' if the context menu was activated on one of these types of elements.

Resources