Find Next in Google Apps - google-apps-script

We have a bunch of documents we would like to convert to Google Docs. In MSWord we have a macro where our users hit a key command and it will automatically find a string of characters (%%%) and then select them. So we can quickly go in and replace all occurrences of them with the correct data.
I am unable to find anything in Google Docs or scripts that can do that.
TL;DR
I need to write a script that will find and select text so we can quickly write over it. Any help or thoughts?

This function works in conjunction with a sidebar to find and select text.
function findTextAndSelect(s){
var doc=DocumentApp.getActiveDocument();
var body=doc.getBody();
var rgel=body.findText(s);
if(rgel){
var rgbldr=doc.newRange();
rgbldr.addElement(rgel.getElement(),rgel.getStartOffset(),rgel.getEndOffsetInclusive());
var rg=rgbldr.build();
if(rg.getRangeElements().length>0){
doc.setSelection(rgbldr.build());
return 'found';
}
else{
return 'Not Found';
}
}else{
return 'Not Found';
}
}
**This is the sidebar code. **
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
$('#txt1').val('');
});
function findAndSelect(){
$('#status').html('');
var txt=$('#txt1').val();
google.script.run
.withSuccessHandler(function(hl){
$('#status').html('<strong>Status:</strong>' + hl);
})
.findTextAndSelect(txt);
}
console.log("My code");
</script>
</head>
<body>
<br />Text:<br /><textarea id="txt1" rows="6" cols="35"></textarea>
<br /><input type="button" id="btn3" value="Find Text and Select" onClick="findAndSelect();" />
<div id="status"></div>
</body>
</html>
You need to add the code to load the sidebar and possibly put it into the menu.

Related

Uploading An Image With Google Apps Script To A GSheet - Passing Values To And From HTML Service Modal Dialog

I'm trying to trigger a file upload off of a Google Sheet, taking the uploaded file, add it to a Google Drive folder, and then return the URL of the uploaded file and place it in a cell on the Sheet. I'm currently triggering the file upload by using a checkbox. Once you set the checkbox to TRUE, it'll pop up a dialog box with a file upload input field. This is triggered by an installed onEdit function. Also, info on the row in the sheet will be used to name the newly uploaded file. This info will be input manually on the sheet.
I get to the showModalDialog line, and the dialog box comes up just fine, but I can't figure out how to pass variables from the original function to the HTML service and then back again (with the file) to upload to Drive, set the name, and put the URL back on the sheet.
Here's the first function in Code.gs, receiving values from the onEdit function:
function addFile(ss,ui,row,total) { \\Triggered if edited cell is in column 25 & value is TRUE
Logger.log('add file function');
var name = ss.getRange(row,1).getDisplayValue();
var date = ss.getRange(row,3).getDisplayValue();
var filename = 'Row ' + row + ' - ' + name + ' - ' + date + ' - ' + total;
var htmlTemp = HtmlService.createTemplateFromFile('Index');
htmlTemp.fName = filename;
htmlTemp.position = row;
var html = htmlTemp.evaluate().setHeight(76).setWidth(415);
ui.showModalDialog(html, 'Upload');
Logger.log('end of add file function');
}
And here's what's in Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_center">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<form>
Please upload image below.<br /><br />
<input type="file" name="upload" id="file" accept="image/*,.pdf" />
<input type="button" value="Submit" class="action" onclick="formData(this.parentNode)" />
<input type="button" value="Close" onclick="google.script.host.close()" />
</form>
<script>
function formData(obj){
var newFileName = <? fName ?>;
var rowNum = <? position ?>;
google.script.run.withSuccessHandler(closeIt).upload(obj,newFileName,rowNum);
}
function closeIt(e){
console.log(e);
google.script.host.close();
};
</script>
</body>
</html>
And here's the return function on Code.gs:
function upload(obj,newFileName,rowNum) {
Logger.log('upload function');
var upFile = DriveApp.getFolderById('[folderid]').createFile(obj).setName(newFileName);
var fileUrl = upFile.getUrl();
Logger.log(fileUrl);
var urlCell = SpreadsheetApp.getSheetByName('sheet name').getRange(rowNum,26);
urlCell.setValue('=HYPERLINK("' + fileUrl + '","View image")');
}
Running this code, the dialog box comes up just fine, and I'm able to select a file for upload. However, clicking the Submit button does nothing, and the box stays up until I X it out or hit the Cancel button. The logs only get so far as 'end of add file function' and never gets to the upload function. Should the google.script.run.withSuccessHandler line close the dialog box, or is something else needed to confirm / get the file and close the box?
I've been searching online and have found a number of posts relating to this, but none seem to address this specific issue. This is also pretty much a frankenstein of code I've cobbled together from those posts, so it's possible there's just something that doesn't belong in there and if that is the case I do apologize. Any help would be appreciated; thanks!
[Edit: the submit button wasn't opening a separate tab because I was using <input type="button"> instead of <button>.]
According to the documentation [1] in the “Parameters and return values” part,
if you’re going to send the form object as a parameter “it must be the function’s only parameter”. So you should send the parameters inside the form, using inputs of types “hidden” or “text”, then, from code.gs you can retrieve the input data of the Form object.
Another thing stated in the documentation [1] in the “form” section, is that you need to disable the default submit action with preventFormSubmit function.
Another problem is that the correct way of printing the variables passed to the template are using <?= ?> instead of <? ?> which works to execute code but not to print variables. [2]
Your “addFile” function is all right. Below is the code i've tested on my environment and I was able to upload an image successfully and print the url in the sheet.
Index.html:
<!DOCTYPE html>
<html>
<head>
<base target="_center">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
</head>
<body>
<form id="myForm">
Please upload image below.<br /><br />
<input type="hidden" name="fname" id="fname" value="<?= fName ?>"/>
<input type="hidden" name="position" id="position" value="<?= position ?>"/>
<input type="file" name="file" id="file" accept="image/jpeg,.pdf" />
<input type="button" value="Submit" class="action" onclick="formData(this.parentNode)" />
<input type="button" value="Close" onclick="google.script.host.close()" />
</form>
<script>
//Disable the default submit action using “func1”
window.onload=func1;
function func1() {
document.getElementById('myForm').addEventListener('submit', function(event) {
event.preventDefault();
});
}
function formData(obj){
google.script.run.withSuccessHandler(closeIt).upload(obj);
}
function closeIt(e){
console.log(e);
google.script.host.close();
};
</script>
</body>
</html>
Code.gs (upload function):
function upload(obj) {
//Retrieve the input data of the Form object.
var newFileName = obj.fname;
var rowNum = obj.position;
var blob = obj.file;
var upFile = DriveApp.getFolderById('[folderid]').createFile(blob).setName(newFileName);
var fileUrl = upFile.getUrl();
var urlCell = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1').getRange(rowNum,5);
urlCell.setValue('=HYPERLINK("' + fileUrl + '","View image")');
}
[1] https://developers.google.com/apps-script/guides/html/communication
[2] https://developers.google.com/apps-script/guides/html/templates

How to get input information on web app like msg box using google script

I need output on web app which key information in input box. using html and java script I deployed as web app. once key the information I should get pop up msg on web app that information. Please help me out of this problem.
I have created HTML and javascript, using that data is getting capture in google spreadsheet but that information I should get on web app like pop up msg
Key information get in pop up msg in web app only
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h2>US P2P Standard Notes</h2>
<label>G-case #: </label><input type= "#" id="username">
<button id="btn">Pass</button> <form action="">
<p> </p>
</form>
<script>
document.getElementById("btn").addEventListener("click",doStuff);
function doStuff(){
var uname = document.getElementById("username").value;
google.script.run.userClicked(uname);
document.getElementById("username").value ="";
}
</script>
</body>
</html>
function doGet() {
return HtmlService.createHtmlOutputFromFile("page");
}
function userClicked(name){
var url = "docs.google.com/spreadsheets/d/…";
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Data");
ws.appendRow([name + "This is G-case#"]);
}
Try this:
I have it running as a dialog. I assume that you can take it from here and turn it into a Web App.
The html file was name aq4.html:
<html>
<head>
<base target="_top">
</head>
<body>
<h2>US P2P Standard Notes</h2>
<label>G-case #: </label><input type="text" id="username" />
<input type="button" id="btn" value="Pass" onClick="doStuff();" />
<script>
function doStuff(){
var uname=document.getElementById("username").value;
google.script.run
.withSuccessHandler(function(){
document.getElementById("username").value ="";
})
.userClicked(uname);
}
</script>
</body>
</html>
Since there was nothing in your form, I removed it. I also changed your button style to the input version. I added a withSuccessHandler to remove the entered text.
This is the google script:
function userClicked(name){
var ss=SpreadsheetApp.getActive();
var ws=ss.getSheetByName("Sheet1");
ws.appendRow([name + "This is G-case#"]);
return;
}
function showDialog() {
var userInterface=HtmlService.createHtmlOutputFromFile('aq4');
SpreadsheetApp.getUi().showModelessDialog(userInterface, "My Page")
}
Your saying something about a pop up but I haven't a clue as to what you're trying to say. Perhaps, you can elaborate on that a bit.
Oh and this is what the current dialog looks like:

How to add file upload to spreadsheet as custom menu option?

I want to make a spreadsheet CMS - that is to read/write data from firebase and vice versa. I reached a point where I need to upload files directly from the spreadsheet and not any other page.
I have added a custom menu with a htmlService to output a template where the user may click and upload a file and that file must get handled in google script, but the problem is that I'm getting only the fake path of a file "c:/fakepath/avatar.png" and not a blob.
my files in google script:
upload.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
</head>
<body>
<div>
<div id="progress" ></div>
<input type="file" name="upload" id="file">
<input type="submit" value="Submit" class="action" onclick="form_data()" >
<input type="button" value="Close" onclick="google.script.host.close()" />
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
function form_data(){
var values = [{
"file":$("#upload").val(),
}];
google.script.run.withSuccessHandler(closeIt).upload(values);
};
function closeIt(){
google.script.host.close()
};
</script>
</body>
</html>
test.gs
function upload(values){
//Display the values submitted from the dialog box in the Logger.
Logger.log(values); // here I'm getting file = c/fakepath/avatar.png while I
//need the file to send it as a post request or save it in google drive
};
I believe I should use FileReader but I have tried and failed:
var file,
reader = new FileReader();
// Upload the file to Google Drive
reader.onloadend = function(e) {
google.script.run
.upload(
e.target.result, file.name
);
};
function form_data(){
reader.readAsDataURL(file);
}
You want to upload a file using a dialog box on Google Docs to Google Drive.
If my understanding is correct, how about this modification? Please think of this as just one of several answers.
Modified script:
Google Apps Script:
function upload(obj) {
var file = DriveApp.createFile(obj.upload);
return {
fileId: file.getId(),
mimeType: file.getMimeType(),
fileName: file.getName(),
};
}
HTML:
Please replace <body>...</body> as follows. In this modification, jquery is not used.
<body>
<form> <!-- Modified -->
<div id="progress" ></div>
<input type="file" name="upload" id="file">
<input type="button" value="Submit" class="action" onclick="form_data(this.parentNode)" >
<input type="button" value="Close" onclick="google.script.host.close()" />
</form>
<script>
function form_data(obj){ // Modified
google.script.run.withSuccessHandler(closeIt).upload(obj);
};
function closeIt(e){ // Modified
console.log(e);
google.script.host.close();
};
</script>
</body>
Note:
When you uploaded a file, the file ID, mimeType and filename of the created file are returned. You can see them on the console.
In this method, because blob is used, the maximum file size is 50 MB. Please be careful this.
If I misunderstood your question and this was not the result you want, I apologize.

Google apps script get user input with no length limit

I want to take user input (HTML specifically) using either:
var ui = SpreadsheetApp.getUi();
var response = ui.prompt('Paste HTML below');
or
var input = Browser.inputBox('Paste HTML below', Browser.Buttons.OK_CANCEL);
These work fine for small inputs, however when copying over the entire HTML for a page of interest an error occurs (in each case). This error cannot be caught, it simply crashes the script.
Do you know why this is happening? I can't find anything in the docs that mention limits on input size.
Any experience doing this a different way?
Edit: as per a suggestion in the comments, I have tried another method (below). This also fails (with no error message) when passed large input.
First I set up Page.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
Paste Sitemap Content Below
<textarea id="user-input-box" rows="4" cols="50"></textarea>
<script>
function logToConsole() {
var userInput = document.getElementById("user-input-box").value;
google.script.run.doSomething(userInput);
}
</script>
<input type="button" value="Close" onclick="logToConsole();google.script.host.close();" />
</body>
</html>
Then in file Code.gs
function testDialog() {
var html = HtmlService.createHtmlOutputFromFile('Page')
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi()
.showModalDialog(html, 'My custom dialog');
}
function doSomething(userInput){
Logger.log(userInput);
}
I just ran into the same problem and couldn't log the error. In my case as is yours, you're calling your logToConsole() function and then directly after you're closing the dialog by using google.script.host.close();
google.script.host.close() is the problem. For some reason it can cancel the script execution - this typically happens when you're sending a lot of data back. The trick is to use a successHandler when you call your script which then calls google.script.host.close(). This way, the data transfer from the dialog finishes correctly and when you call withSuccessHandler(), that callback closes the dialog. Try this amendment to your code:
<script>
function logToConsole() {
var userInput = document.getElementById("user-input-box").value;
google.script.run.withSuccessHandler(closeDialog).doSomething(userInput);
}
function closeDialog() {
google.script.host.close();
}
</script>
<input type="button" value="Close" onclick="logToConsole()" />

Why the program not run correctly?

I am beginner to html and asp. I should write code of the program in Notepad. I want the program that when I click on the Random Button, generate a random number and when I click on the Check button, the program compare between my guess and random number. I write this code but when run the program, not show random number and not compare. Why?
<html>
<head>
<script>
var numOfGuess=new number(0);
var numRandom;
var num;
function RandomNum(){
numRandom=new number(math.floor(math.random()*100));
response.write(numRandom);
numOfGuess=0;
}
fucntion Guess(){
num=document.getElementById("guess");
var alert="";
if(num.value<numRand){
alert="grater than!";
numOfGuess++;
}
esle if (num.value>numRand){
alert="lower than!";]
numOfGuess++;
}
else{
alert="equal!";
numOfGuess++;
}
document.getElementById("message").innerHtml=alert;
}
</script>
</head>
<body>
<input type="text" id="guess">
<input type="submit" onClick='RandomNum()' value="Random">
<p id="message"></p>
<input type="submit" onClick='Guess()' value="Check">
</body>
</html>
Like AnthonyLeGovic said:
you need to be rigorous when programming
here is what you are looking for:
<html>
<head>
<title>test</title>
<script language="javascript">
var numRand = 0;
var numGuess = 0;
var numTry = 1;
function setRand(){
numRand = Math.floor((Math.random()*100)+1);
numTry = 0;
alert("done");
}
function guess(){
var msg = document.getElementById("message");
numGuess=Number(document.getElementById("guess").value);
if(numGuess>numRand){
msg.innerHTML = "lower than!";
}
else if(numGuess<numRand){
msg.innerHTML = "grater than!";
}
else {
msg.innerHTML = "equal! tried " + numTry +"times";
}
numTry++;
}
</script>
</head>
<body>
<input type="text" id="guess" />
<input type="button" onclick="setRand()" value="Random" />
<p id="message"></p>
<input type="button" onclick="guess()" value="Check" />
</body>
do not forget language="javascript" in your script tag else your script will not work!
You need to be rigorous when programming.
There are some syntax errors in your code like :
fucntion instead of function while declaring Guess function.
you declare numRandom as a global variable but you are using numRand then, unfortunately these two variables are not the same at all. Moreover numRand isn't declare (which is logic because it should be numRandom).
you are using innerHtml instead of innerHTML (case sensitive) in order to help the user to find the right number.
Maybe there are some more mistakes I've forgotten right there.