General assistance in Google Apps scripting - google-apps-script

OK, I'm tired of searching for specific questions to help with a project, finding answers, changing my implementation which just adds more questions, realizing there's a better way to do things, etc. So allow me to ask for general assistance, I will then do my best to research how to do it and ask further questions if needed.
I'm writing a script to be used as a Gadget in a Google Site page
(I'm more than willing to share this if anyone wants to take a look
at it); right now I'm doing this just for me, but I want to write
this to be easily used by others.
This will list all user's Google Docs in a specified folder; when
selecting the document from the list, the contents will be displayed
for editing in another field.
The user will be able to define certain lines, starting wit a period,
to "mark" as chords that can be automatically transposed with the
push of a button; that is to say, the user clicks a button and all
A's go to A#, B to C, C to C# and so on, but only on the specified
"Chord" lines.
The user can then save this document back to the Google Docs for
printing if needed.
I've got the layout mostly. Some problems I'm coming across:
Doing a .find apparently finds all documents that have the given string in the name and
the contents. The fix would be to put the document IDs in a Hidden, but it doesn't seem
that a List returns the numbered item you clicked on, so how can I also get the ID
that's stored somewhere else?
I'd like the TextArea to be rich text for bolding and what-not; does
Google Apps have a text editor (it'd be awesome if I could just put
the Google Docs editor in a panel)? RichTextArea has been
deprecated, is there a replacement?
To do the transposing, I was planning on just putting every character
of the text area into an array, stepping through the array, when it
sees a "\n" followed by a "." to flip a var "on", then changing any
following characters, then if it sees another "\n" to turn the var
"off"; is there a better way to do this?
Or, is there way to add a script to a Google Document that would do
the transposing (I know you can do macros for spreadsheets, but there
doesn't really seem to be an equivalent for documents)? That way I can
just give out this macro and tell people to use on their existing document.

Since you asked, yes, separate questions would be appropriate, because the combination of questions is very specialized, while the individual problems might be more general, and of use to more people. But let me take a stab at it anyway...
[With the result of find()]... how can I also get the ID that's stored somewhere else?
DocsList.find() returns a list of File objects. Class File has a getId() method that returns the document ID you are used to seeing in Google Drive. To get the IDs of all your files:
var files = DocsList.getAllFiles();
for (var i in files) {
Logger.log(files[i].getId());
}
You should also look at DocsListDialog for creating a file picker that works on Google Drive.
RichTextArea has been deprecated, is there a replacement?
No, not in apps-script. You've just got TextArea. However, you may be able to embed a third-party rich text editor in your UI.
To do the transposing, ... is there a better way to do this?
Change the TextArea.value into an array of lines, then manipulate those, without needing to manage an on/off state. See How do I get information out of TextArea in Google App Script on the button click? and Javascript: Convert textarea into an array.
// aTextArea contains user's input. Probably a Johnny Cash song.
var inputText = e.parameter.aTextArea;
var inputLines = inputText.split('\n');
for (var i in inputLines) {
if (inputLines[i].charAt(0) == '.') {
// Transpose
}
}
// Put lines back together, if you wish
var outputText = inputLines.join('\n');
..is there way to add a script to a Google Document that would do the transposing...
Yes (capability extended to Docs and Forms since question was originally asked). No, Spreadsheets are the only document type that can be a container for scripts at this time.
Alternatively, you could employ a stand-alone script to operate directly on Docs! Perhaps with a script deployed as a Web App that lets users pick the target music to transpose from documents on their Google Drive, and that then writes a new copy of the document, transposed?

Related

Moving an item from one Google form to a new Google form using google apps script

When editing a Google form manually, you can usually click on an item, and on the side appears a menu, which includes the button "import questions". This button is very useful for me as it allows me to collect questions from past Google forms and import them to new Google forms.
But I'm looking through the Forms documentation, and I can't figure out how to do this via Google apps script programatically.
Here is the documentation:
https://developers.google.com/apps-script/reference/forms/form
The closest thing to what I want is the .moveItem() method, which moves an item from one spot in a form to another. But it only works within the same form. I want to know if I could do it across forms. And ideally, instead of moving the item, it would make a copy of the item in the new form.
I considered the .getItems() method, but there doesn't seem to be a general .addItem() method I could use on the new form. Would I have to go through the painstaking process of having to identify each item type, and specify how the details of each one should be copied to the new form, including things like point values of a question and whether or not the question is required?
I want to import from forms that have all kinds of content: video, images, multiple choice questions, grid questions, number scale questions, etc. I feel that if I have to specify the details of each item type, it would take too long, and I would be bound to miss something or run into an error that may be impossible to solve. Is there not an easier way?
And if specifying each item type is what I have to do to import everything properly, has someone else created that code already that I can re-use?
Issue:
In the current stage, unfortunately, it seems that Forms Service cannot copy all items. Ref1, Ref2 Ref3. And, unfortunately, moveItem can be used for the same Google Form as you say.
Workaround:
In your situation, as a workaround, how about copying the source Google Form? And, when there are some items you want to remove, you can remove them. I thought that this process can be achieved by Google Apps Script.
But, I'm not sure about your actual Google Form. So I'm not sure whether this is a suitable method.
Future:
Recently, Google Forms API was announced. Ref When this API got to be able to be used, your goal might be able to be achieved by retrieving the object from Google Form. Unfortunately, I'm still not sure about the detail of it.

AppsScript with Google Sheets: Conditionally load images based on user interaction/when a range is selected

We've got a google sheet with user editable text that will eventually be used within images. We have a web application that generates the images and serves them, so they can be embedded within the IMAGE function provided within Sheets.
This works fine and ends up being something like:
=IMAGE(CONCAT("PREVIEW_TOOL_URL", "?t=", ENCODEURL(previewText(D2))), 3) where 'previewText' is simply formatting the string to pass to the web tool.
However, to avoid overloading the server and generating a ton of requests every single time someone loads the sheet, I'd like to make it so images only load in some condition (i.e. a user presses a button or they highlight the text), is there some way of doing this?
Add a checkbox to E2:
=IF(E2,IMAGE(CONCAT("PREVIEW_TOOL_URL", "?t=", ENCODEURL(previewText(D2))), 3),"Check to preview")
You can also use Apps Script for this!
You will have to start by:
Go to Tools > Create a new script;
Use the following script:
function loadImages() {
let sheet = SpreadsheetApp.openById("SPREADSHEET_ID").getSheetByName("SHEET_NAME");
sheet.getRange("CELL_YOU_WANT_TO_PLACE_THE_FORMULA").setFormula("YOUR_FORMULA");
}
Do not forget to adjust this script such that it meets your needs accordingly.
Insert a new drawing into the sheet;
Attach a script to it by going to the three dots symbol on the drawing; when asked about the name, input loadImages which is the function which we had created previously.
Press the button on the sheet and that's it!
Reference
setFormula(formula).

FILE_UPLOAD item type in Google Apps Script (GAS) for Form Submission

I've seen FILE_UPLOAD item type in google forms regarding this topic.
My problem is related, but somewhat different--perhaps someone can recommend a workaround?
Situation: Using Google Forms as content submission and editing tool for certain kinds of "documents," with a specific form for each document.
Objective: copy an original form submission to create through GAS a NEW form submission with the same item responses.
This is based on a response in the original form submission indicating that a variant also needs to be created based on the original content.
Example: Another form entry is needed where the original content is translated to a different language (with first draft using google translate and then revised by native speaker using the Google form). In other cases, only portions of a long original submission need to be revised to create the variant document, where the revisions are made to the duplicated submission in the Google form.
Things are fine except where the form(s) have image upload options and I need to copy the FILE_UPLOAD content of the original form response back into the new scripted form submission. But it appears required to specify the item type (e.g., .asTextItem(), .asCheckBoxItem(), etc.). But there is no .asFileUploadItem() option (I tried using it), and therefore an error is thrown, preventing the copy of FILE_UPLOAD content into the corresponding question item of the form. I've tried using .asTextItem(), since the G-Drive address is just a text string (at least in the paired Google Sheet), but the Form won't accept that. It seems (at least in our case) that the original file location would work for all variant duplicates that retain the same image, so copying the content (the G-Drive location of the image) should be fine, if GAS allowed me to do that.
Is there any workaround provided by Google, now that it is a year later than the previous post I found (above)? Has anyone come up with a workable solution that might work for my case?
Thanks so much for any help!

How to embed a single Google Sheets cell's text content into a web page?

Background: I have a Google Sheet that automatically manages key organization event dates, but occasionally one has to be manually overridden. I have been duplicating those auto calc'd event dates using PHP on the organization's web page but that doesn't handle it when the event dates are manually changed back in the Sheets database.
Need Statement: I wish to grab the text content of the Google "DateCalc" Sheet, cell "A33" (which contains the corrected next Date) and embed it automatically in a web page sentence that states, "The next event is scheduled for ???." where "???" is whatever is needed for the HTML embed effort for the text content of cell A33.
All the embedding approaches I have tried using the publish to web feature of Sheets, just display a frame with the entire Sheets page content, and I have not been able to find a simple single text display approach, which is what I seek. All the solutions I have found so far are for much more complex situations. I believe I don't need any more code on the Sheet (source) end, just an appropriate "embed code snippet" at the destination end.
I can embed a complete sheet but haven't found a way to embed a simple text string in line with the surrounding text in the sentence.
This web script is the closest I have been able to come...
Our next meeting is on <object data="https://docs.google.com/spreadsheets/d/e/2PACX-1vQq6sXBel4SOW5U_XLnQ1xyyl4P-aK2v1R-5uofUvstMLV89_yCSqX3Lmsy4B7E21gojeG88efGFjZ0/pubhtml?gid=604484136&single=true&range=A29&chrome=false" type="text/html" width="171" height="15"></object>.
but, if the Code Snippet really ran (I changed the file ID to protect the innocent), you would see it doesn't produce an in-line text string but an isolated "block" with the text inside it, as shown below....
The text seems to be an image, not text, that is displaced above the text baseline and has a small gray blob following it that I just can't get rid of.
I'll assume that your server uses a combination of PHP and HTML, so one approach can be to use that PHP code to make a call to the Sheets API to retrieve the data. In the PHP Sheets API Quickstart you can find a example of how to set up a project to achieve a working connection between your server and the API. After you complete the tutorial, you can modify your script to include the following function so you can achieve your original request.
function getNextDate() {
$client = getClient();
$sheetsService = new Google_Service_Sheets($client);
$spreadsheetID = '{YOUR SPREADSHEET ID}';
$cellRange = 'DateCalc!A33';
$serverResponse = $sheetsService->spreadsheets_values->get($spreadsheetID, $cellRange);
$cellValue = $serverResponse->getValues();
if (empty($cellValue)) {
return "NO MEETINGS AHEAD!\n";
} else {
foreach ($cellValue as $value) {
return $value[0];
}
}
}
A totally different alternative is to use a webapp. You can use this tutorial to deploy a webapp that can be later embedded in your webpage to show the following meeting dates.
So there are two free alternatives to accomplish your objectives: using the Sheets API or a webapp; and in this anwser I provided a function for the API option. Please, don't hesitate to offer information for further clarifications or request for help.
Our next meeting is on
.
I built a free, open source, and easy to use service and badge generator called https://cellshield.info. It works out of the box for public Google spreadsheets. What you see above is a live Markdown output version of a badge that is synced from a spreadsheet with the value formatted as what was shown in your example with a formula of TODAY(). The Markdown just makes an image tag which I suppose you can do with anything else that can make an image tag as well.
If you want the yellow or any formatting to to go away, try this:
Our next meeting is on
.
This was done by adding &color=rgba%28255%2C255%2C255%2C0.0%29&style=flat-square to the arguments. The text doesn't match perfectly, it's servicable.
Anyway, I see you went with tabletop but if you or anyone else is just looking to do what you wanted to do, then my service should be sufficient.
For example, it is used for this Game Boy development contest to present the prize pool amount.
If a private spreadsheet solution is needed, one could fork my code, run it on Cloud Run in their Google Cloud Platform account and explicitly share the spreadsheet to the service account on their Google Cloud Platform instance.
Jacques-
Merci beaucoup !
It has been a challenging several days of non-stop effort but you put me on the right track.
Using less than 20 lines of JavaScript code, including one line for the free TableTop.js library call (see https://github.com/jsoma/tabletop#if-your-publish-to-web-url-doesnt-work) and inserting a string in the middle of my HTML sentence, yielded EXACTLY what I was seeking and the solution was INFINITELY SIMPLIER than virtually everything else I found that required multiple libraries, subscription fees, complex system calls, etc.
The hardest part was inserting the JavaScript code into WordPress which my web site is constructed with, as you can essentially only insert plain text into a WordPress page, but with the an added WordPress plugin (Insert Header and Footers) you can put code into a WordPress page.
Many thanks for getting me headed in the right direction, and having a great learning experience along the way. :-)

How do I insert a Horizontal line in a google document via Google Apps Script?

I wrote a script that takes some data from a google spreadsheet and writes it in several separate tables in a google document.
Since I need to physically cut these tables from the printed document, I'd like to add horizontal lines between them.
I guess I can insert an image of a line, via
var cutline = UrlFetchApp.fetch("SOME URL");
body.appendInlineImage(resp.getBlob());
where "SOME URL" is the url for the image.
Another way I can think of would be creating a one-column table and add my tables in its cells. The horizontal lines for the table would be my cutting guides.
However, from the user interface I a horizontal line can be easily added via "Insert>Horizontal Line". I was not able to do find a way to do that from Google Apps Script.
Is this unsupported?
Can someone confirm that and/or possibly suggest method that is less cumbersome than those I thought of?
EDIT: I have also found the HorizontalRule class, which I do not understand entirely. However I don't think it's what I'm looking for.
Another alternative could be an InlineDrawing. However, from this guide, I gather that an InlineDrawing can only be manipulated, but not added programmatically.
HorizontalRule should do the magic.
This code worked for me:
DocumentApp.getActiveDocument().getBody().appendHorizontalRule();
More info:
https://developers.google.com/apps-script/reference/document/horizontal-rule#copy()
DocumentApp.getActiveDocument()..getBody().insertHorizontalRule(0)