I have written a Google Sheets add-on that uses a modal dialog as the interface. I was having trouble getting the success handler to run, so I created a skeleton interface for testing, and have the same issue.
Whenever the server-side function returns, the function specified in the success handler should run. Instead, it throws an error "Untaught TypeError: a is not a function". I am able to manually trigger the function specified for the handler via a button (added for demonstration purposes only. Code below:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function success(){
document.getElementById("waitMessage").innerHTML = "TEST";
}
function testFunc(){
google.script.run.withSuccessHandler("success").serverSideFunc();
}
</script>
</head>
<body>
<p>
Click the button to close the window
</p>
<form>
//Doesn't work
<input type="button" name="test" value="Server-side test" onclick="testFunc()">
//Works
<input type="button" name="test-client" value="Client-side test" onclick="success()">
</form>
<div id="waitMessage">
<p></p>
</div>
</body>
</html>
.gs script file below:
function serverSideFunc(){
Logger.log("");
}
As you can see, the script file is just a dummy function designed to trigger the success handler.
What's going on here? Have I missed something simple?
You are not having an error returned. You do not put quotes around the function name to run:
function testFunc(){
google.script.run.withSuccessHandler(success).serverSideFunc();
}
Related
I've spent 2 days trying to figure this out so any help is appreciated.
I was following this nice little video tutorial series
and I wanted to try something basic before getting any further: get an html button to show a javascript alert using google apps script and their HTML Service component, but for the life of me, I can't understand why the alert is not triggered.
Here's my code
Index.html
<!DOCTYPE html>
<html>
<head>
<script>
document.getElementById("btnSearch")
.addEventListener("click",showAlert);
function showAlert() {
alert("hello world");
}
</script>
</head>
<body>
<div>
<label>Enter code</label>
<input type="text" id="txtStudentID"/>
<button id="btnSearch">Search</button>
</div>
</body>
</html>
and my
code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('Index');
}
I also try it like google shows it here: but I still don't get the alert to trigger after the button is pressed:
<input type="button" value="Search"
onclick="google.script.run
.withSuccessHandler(showAlert)
.withUserObject(this)" />
it's like anything that starts with "document.getElementByID..." within the script tags will simply not work
What am I missing? is this something not longer supported with GAPS? is there a different/proper way to get this to work?
thank you in advance.
anything that starts with "document.getElementByID..." within the script tags will simply not work
Yes. Because at the time script tags are evaluated, there's no element with id btnSearch.
Solution(s):
Move the script to the bottom of DOM.
<div>
<label>Enter code</label>
<input type="text" id="txtStudentID" />
<button id="btnSearch">Search</button>
</div>
<script>
function showAlert() {
alert('hello world');
}
document.getElementById('btnSearch').addEventListener('click', showAlert);
</script>
Alternatively, As the previous answer states, use the load trigger; so that the script is evaluated after the DOM is loaded.
<script>
function showAlert() {
alert('hello world');
}
function load1() {
document.getElementById('btnSearch').addEventListener('click', showAlert);
}
window.addEventListener('load', load1);
</script>
Try putting addEvent into window.onload
I have a problem with an html page
here a simplified version of the page
<html>
<head>
<script type="text/javascript">
function maxLength()
{
console.log('maxLength');
}
</script>
</head>
<body>
<input type"text" onblur="maxLength()">
</body>
</html>
on onblur event I receive this error
Uncaught TypeError: maxLength is not a function
but if i call the function from console it works without errors and print 'maxLength'
Why?
The code there runs in the context of the input, which has defined maxLength.
Better developer tools would make it clearer:
maxLength is not a function at HTMLInputElement.onblur
Rename your function to something else or use a different way of attaching the event listener.
If you rename the function to something else it should work fine for you. The explanation is aptly given with Alex already. Example:
<html>
<head>
<script type="text/javascript">
function maximumLength()
{
console.log('maxLength');
}
</script>
</head>
<body>
<input type"text" onblur="maximumLength()">
</body>
</html>
What im trying to do, is to call my function from whenever someone clicks on my button. However, i know that it can be done with
<button onclick="myFuntion()>
But i want to skip that step, i dont want a function in my button, i've heard that its bad programming.
However, heres how my file looks.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javacript" src="javascript.js"> </script>
<title> Javascript </title>
<script>
function testFunction(){
document.getElementById("test").onclick = Hello;
}
function Hello(){
alert("Hello");
}
</script>
</head>
<body>
<button type="button" id="test" <!-- I know i can use onclick="testFunction()" here but i dont wanna !-->> Click me </button>
</body>
</html>
So how come it doesnt pop-up with the box "Hello" whenever i push the button, what have I done wrong?
You have to call your testFunction after the HTML body is loaded so that it actually creates he binding.
That is, at the end of the file, you'd do something like:
...
<script>
testFunction()
</script>
</body>
...
If you run that binding code in your head script the button element won't exist yet — that is why this have to be at the end.
JavaScript libraries such as jQuery make this more elegant by providing an ready hook, where one puts code to be called once the page is fully loaded, without having to resort to code on the bottom of the page.
Complete example with script at end (confusingly, Stack Snippets don't show it to you in the order they actually are in the snippet; even though it doesn't look like it, the script is at the end here):
// Scoping function to avoid creating unnecessary globals
(function() {
// The click handler
function Hello() {
alert("Hello");
}
// Hooking it up -- you *can* do it like you did:
//document.getElementById("test").onclick = Hello;
// ...but the modern way is to use addEventListener,
// which allows for more than one handler:
document.getElementById("test").addEventListener(
"click", Hello, false
);
})();
<button type="button" id="test">Click me</button>
window.onload=testFunction;
function testFunction(){
document.getElementById("test").onclick = Hello;
}
function Hello(){
alert("Hello");
}
Just run the line in your testFunction always. As seen here:
https://jsfiddle.net/arugco4b/
I have one file (CCPageContainer.swt) that contain number of frames, and each frame call file.
(swt - siebel template file)
this is part of the code with a specific frame:
<HTML dir="swe:dir">
<head>
<title><swe:this property="Title"/></title>
<swe:include file="CCStylesChoice.swt"/>
</head>
<swe:switch>
<swe:frameset htmlAttr="rows='30,30,27,18,42,*,15' border='0' frameborder='No'">
<swe:frame htmlAttr="marginheight='0' marginwidth='0' noresize scrolling='No'">
<swe:include file="CCFrameGoToView.swt"/>
</swe:frame>
</swe:frameset>
</swe:switch>
</HTML>
in the CCFrameGoToView.swt file that has been called I'm trying to call to alert function:
<HTML dir="swe:dir">
<body>
<script language="JScript">
function alert_test()
{
try
{
alert("test");
}
catch (err)
{
//document.write("oops.. an error has occurred");
}
}
</script>
<form name="myForm">
<table>
<tr>
<td>ALERT: <input type="Button" value="alert5" onClick="alert_test();"><br></td>
</tr>
</table>
</form>
<swe:scripts/>
</body>
</html>
the problem is that the alert message doesn't work when I'm pushing the button.
If I’m running only CCFrameGoToView.swt the alert button is working, and i see the message after i push.
but when I'm trying to run it from CCPageContainer.swt, nothing happened when i'm pushing the alert button.
I've also tried window.parent, window.top etc.
please your help. Thanks.
Try hanging your custom function off the top window so the click handler will be able to find its way to it:
top.alert_test = function alert_test()
{
// blah blah blah
}
then:
onClick="top.alert_test();"
As an aside, it feels strange to be directly injecting code into a Siebel Web Template file, so maybe if you tell us a little more about what you're trying to accomplish, we might be able to help you think about a better way to accomplish it.
I'm a beginner trying my first program to add external jscript file in scr attribute of script tag, followed all steps as I searched but it's not working the way it should. Can someone please help me with this?
I have one aspx form, and one button onclick calling internal javascript function.
I also have one button onclick calling external .js file function.
This is my aspx code
<head runat="server">
<script type="text/javascript" language="javascript" src="ExternalJScript.js">
function Myfunction()
{
document.getElementById("htmlbutton").innerHTML = "This is Button from Javascript function";
alert("Hi Function Called from Javascript");
}
</script>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<button type="button" id="htmlbutton" onclick="Myfunction()">This is html button</button><br />
<button type="button" id="Button1" onclick="ExternalJSFileFunction()" value="Call File">HI</button>
</div>
</form>
And this is my .js code
ExternalJSFileFunction()
{
alert("I m from external file");
}
There should not be code in between the script tags of an external script. Try changing it to:
<head runat="server">
<script type="text/javascript" language="javascript" src="ExternalJScript.js"></script>
<script type="text/javascript">
function Myfunction()
{
document.getElementById("htmlbutton").innerHTML = "This is Button from Javascript function";
alert("Hi Function Called from Javascript");
}
</script>
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<button type="button" id="htmlbutton" onclick="Myfunction()">This is html button</button><br />
<button type="button" id="Button1" onclick="ExternalJSFileFunction()" value="Call File">HI</button>
</div>
</form>
Also, the Language attribute is deprecated and is not needed
Edit
It's because the function you are trying to call isn't actually a function because the function keyword is not used. Change the external file so that it is:
function ExternalJSFileFunction()
{
alert("I m from external file");
}
Then it will work
Additionally, there are some other tips as well:
If you're using the HTML5 doctype, you can also get rid of the type attribute on <script> elements too
Also have your opening curly braces on the same line as the function or conditional, so do:
function ExternalJSFileFunction() {
but not:
function ExternalJSFileFunction()
{
You should almost always add your scripts to the end of the page, just before the closing </body> tag for performance
Using the onclick attribute is also not the recommended way of attaching event handlers, you should use the proper addEventListener() method instead. If you need to support <= IE8 you'll need to use IE's older event API. Using a JS library. like jQuery, can really help out with this kind of stuff.
The function in your external JavaScript file is not defined properly.
It should look like this (I added the function keyword).
function ExternalJSFileFunction()
{
alert("I m from external file");
}
You also need to make the changes that danwellman suggested in his answer.