Apps script: Show loader on button click - javascript

I am trying to show a loader in the google sheets sidebar on the button click either on the complete page or at least on the button so that users submitting the form should not press again until the earlier form is submitted. I have added loader through js/jquery. Although they work fine but they are too quick to be even shown to users. I can add some delays but again I don't know how much time will the script take to complete. Therefore it may be good to run it from the apps script/server-side.
Html page:
<form >
<div class="inputbox">
<label for="name"><strong>Client Business Name</strong></label>
<input type="text" placeholder="Client Business Name" name="name" required>
</div>
<div class="inputbox">
<label for="description"><strong>Client Description</strong></label>
<input type="text" placeholder="Client Description" name="description" required>
</div>
<div class="inputbox">
<label for="domain"><strong>Domain</strong></label>
<input type="url" placeholder="www.example.com" name="domain">
</div>
<div class="inputbox">
<label for="homepage"><strong>Home Page</strong></label>
<input type="url" placeholder="www.example.com/home" name="homepage" >
</div>
<div class="inputbox">
<label for="kpi"><strong>Link Goal Per month</strong></label>
<input type="url" placeholder="www.example.com/home/blog" name="kpi" >
</div>
<button id="btn" onclick="addvalues" >Add</button>
</form>
JS:
<script>
function addvalues() {
document.getElementById("btn").innerHTML = "Adding.."
document.getElementById("btn").setAttribute('disabled', 'disabled')
google.script.run.clientAdd()
}
</script>
Apps Script:
function clientAdd(form) {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName('Clients');
sheet.getRange(sheet.getLastRow() + 1, 2).setValue(form.name);
sheet.getRange(sheet.getLastRow(), 3).setValue(form.domain);
sheet.getRange(sheet.getLastRow(), 4).setValue(form.homepage);
sheet.getRange(sheet.getLastRow(), 5).setValue(form.description);
sheet.getRange(sheet.getLastRow(), 6).setValue(form.kpi);
}

Modification points:
addvalues of <button id="btn" onclick="addvalues" >Add</button> should be addvalues();
In your situation I thought that withSuccessHandler might be suitable.
When these points are reflected to your script, it becomes as follows.
Modified script:
HTML
From:
<button id="btn" onclick="addvalues" >Add</button>
To:
<button id="btn" onclick="addvalues();return false;" >Add</button>
Javascript
From:
function addvalues() {
document.getElementById("btn").innerHTML = "Adding.."
document.getElementById("btn").setAttribute('disabled', 'disabled')
google.script.run.clientAdd()
}
To:
function addvalues() {
const button = document.getElementById("btn");
button.innerHTML = "Adding..";
button.setAttribute('disabled', 'disabled');
google.script.run.withSuccessHandler(_ => {
// Please set the loading animation here.
// In this sample modification, when the button is clicked, the button is disabled, when Google Apps Script is finished, the button is enabled.
button.removeAttribute('disabled');
button.innerHTML = "Add";
}).clientAdd();
}
When the above modifications are reflected in your script, as a simple sample, when the button is clicked, the text of the button is changed from Add to Adding.. and the button is disabled, when Google Apps Script is finished, the button is enabled and the text of the button is changed from Adding.. to Add.
Please modify the script in withSuccessHandler to your loader.
Note:
I'm not sure about your whole script. So I proposed a simple modification from your showing script.
Reference:
withSuccessHandler(function)

Related

Vanilla JS/HTML/CSS - I open a modal popup - an input field should receive an autofocus

I have a modal in my project that popsup on button click:
<div class="modal modal-visually-hidden">
<h3 class="modal__header">Оставить отзыв</h3>
<button name="Close the window" class="modal__close-button">x</button>
<div class="modal__form-container">
<form id="modal__form" action="#">
<label for="modal__form--name">Пожалуйста, заполните поле</label>
<input id="modal__form--name" type="text" placeholder="Имя" required> <!--this is the field needed to autofocus on modal open event-->
<input id="modal__form--qualities" type="text" placeholder="Достоинства">
<input id="modal__form--drawbacks" type="text" placeholder="Недостатки">
<input id="modal__form--submit" class="global-hover" type="submit" value="оставить отзыв">
</form>
</div>
Here is the button to pop the modal up:
<div class="feedback__button-container">
<button name="Leave a feedback" id="feedback__button" class="feedback__button">оставить отзыв</button>
</div>
I use the following JS to show the popup:
const activatePopupButton = document.querySelector('#feedback__button');
const commentPopup = document.querySelector('.modal');
const closePopupButton = document.querySelector('.modal__close-button');
const nameInputField = document.querySelector('#modal__form--name'); /* I select the field for further autofocus */
closePopupButton.addEventListener('click', function() {
commentPopup.classList.add('modal-visually-hidden');
document.querySelector('body').style.overflow = 'visible';
});
activatePopupButton.addEventListener('click', function() {
commentPopup.classList.remove('modal-visually-hidden');
nameInputField.autofocus = true; /*this line should autofocus the field in question*/
console.log(nameInputField.autofocus);
document.querySelector('body').style.overflow = 'hidden';
});
Modal is hidden with a class '.modal-visually-hidden' that is styled as display:none;
When the button is pressed the popup shows up and the first field suppose to get in focus with the line nameInputField.autofocus = true;
But it just won't. What am I doing wrong?
The autofocus attribute focuses the input on page load. You cannot set it after the DOM has loaded. Instead, try this:
nameInputField.focus();

Create HTML text in an HTML form and open up the text in a Javascript alert box

I'm new to coding and need to create HTML text in an HTML form on a page and open up the text in a Javascript alert box. I've tried various code to no success. Here is what I've come up with so far which does not create a pop up alert box:
Here is the HTML and the JS:
Function myfunction1()
{
Let myfun1 = document.getElementById('sec1-input').value;
Alert(myfun1);
}
<div class="form-group">
<label for="sec1-input"><strong>Enter Alert Text: </strong></label>
<input type="text" class="form-control" id="sec1-input">
</div>
<button id="sec1-btn1" type="button" class="btn btn-primary">Alert Me!</button>
I'm not sure what do you want, but I'll show you how to make an alert window exactly as you're asking.
First of all you must consider several mistakes that you are making. JavaScript does not recognize the word Function because it is capitalized. The function keyword must be lowercase.
Here I leave you a referring link with JavaScript reserved words: https://www.w3schools.com/js/js_reserved.asp
On the other hand, I see that you are not using the form tag, which leads to two problems: technical and semantic. Here I leave you another link with reference to forms: https://www.w3schools.com/html/html_forms.asp
Finally, to achieve what you want you need to work with events, especially with the click event. Here I will leave you a reference link and the solution you want:
let button = document.querySelector('#sec1-btn1');
button.addEventListener('click', function(e) {
let val = document.querySelector('#sec1-input').value;
alert(val);
});
<form>
<div class="form-group">
<label for="sec1-input"><strong>Enter Alert Text: </strong></label>
<input type="text" class="form-control" id="sec1-input" />
</div>
<button id="sec1-btn1" type="button" class="btn btn-primary">
Alert Me!
</button>
</form>
You have not called the function anywhere. For it to work you need to use a listener.
<div class="form-group">
<label for="sec1-input"><strong>Enter Alert Text: </strong></label>
<input type="text" class="form-control" id="sec1-input">
</div>
<button onclick="myfunction1()" id="sec1-btn1" type="button" class="btn btn-primary">Alert Me!</button>
<script>
function myfunction1() {
let myfun1 = document.getElementById('sec1-input').value;
alert(myfun1)
}
</script>
I added the onClick listener to button and now it works.
javaScript is case sensitive
function myfunction1()
{
let myfun1 = document.getElementById('sec1-input').value;
alert(myfun1);
}
<div class="form-group">
<label for="sec1-label"><strong>Enter Alert Text: </strong></label>
<input type="text" class="form-control" id="sec1-input">
</div>
<button id="sec1-btn1" type="button" onClick="myfunction1()" class="btn btn-primary">Alert Me!</button>
also IDs of elements should not be the same , to assign same selector , use class and you also need to give your function to your element's event listener
You should not start javascript functions like alert with capital letters.
Put this piece of code instead of your button:
<button id="sec1-btn1" type="button" class="btn btn-primary" onclick="myfunction1()">Alert Me!</button>

Google Apps Scripts - HTML Service - "wait" for client-side form submission

I am creating a container-bound Google Apps Scripts that is bound to a Google Spreadsheet. In my GS code I am using Google HTML Service to display a dialogue box in Google Sheets (i.e. an HTML form).
The issue I am running into is that when I render the HTML form client-side, the GS server-side code continues to run. Instead, I would like to "pause" the server side code and have it wait until the user submits the form.
Is that possible to do?
Here's what I have so far:
Code.gs
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom')
.addItem('Generate Shipping Email', 'menuItem1')
.addToUi();
}
function menuItem1() {
var html = HtmlService.createHtmlOutputFromFile('index');
var ui = SpreadsheetApp.getUi()
ui.showModalDialog(html, 'Shipping Email Options'); // This line shows the modal in index.html
// Here is where I would like to "pause" until the HTML form is submitted by user clicking the button with id="button1id" ...
Logger.log("Line after showModalDialog"); // ... however, currently this code runs before the user clicks submit or cancel button in the html form
// Rest of code which should not run until user clicks submit or cancel button will go here
}
readyToSendEmail(shippingNeeded, notes) {
// Some non-relevant code goes here
}
index.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form class="form-horizontal">
<fieldset>
<!-- Form Name -->
<!-- Multiple Radios (inline) -->
<div class="form-group">
<label class="col-md-4 control-label" for="radios">Do you need expedited shipping?</label>
<div class="col-md-4">
<label class="radio-inline" for="radios-0">
<input type="radio" name="radios" id="shippingNeededYes" value="Yes" checked="checked">
Yes
</label>
<label class="radio-inline" for="radios-1">
<input type="radio" name="radios" id="shippingNeededNo" value="No">
No
</label>
</div>
</div>
<!-- Textarea -->
<div class="form-group">
<label class="col-md-4 control-label" for="textarea">Additional shipping notes:</label>
<div class="col-md-4">
<textarea class="form-control" id="textarea" name="textarea"></textarea>
</div>
</div>
<!-- Button (Double) -->
<div class="form-group">
<label class="col-md-4 control-label" for="button1id">Ready to send?</label>
<div class="col-md-8">
<button id="button1id" name="button1id" class="btn btn-primary" onclick="clickedSubmit()">Yes, send the email</button>
<button id="button2id" name="button2id" class="btn btn-default" onclick="google.script.host.close()">Cancel, do not send an email</button>
</div>
</div>
</fieldset>
</form>
<script>
function clickedSubmit() {
if(document.getElementById('shippingNeededYes').checked) {
var shippingNeeded = "Yes";
} else {
var shippingNeeded = "No";
}
var notes = document.getElementById('textarea');
google.script.run.readyToSendEmail(shippingNeeded, notes);
}
</script>
</body>
</html>
Any ideas, thoughts or suggestions are appreciated!
I guess you are bit confused how the js function works in app script.
//This function will run when the spreadsheet is loaded
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom')
.addItem('Generate Shipping Email', 'menuItem1')
.addToUi();
}
//This entire function will run when you click on the menu item in the spreadsheet.
function menuItem1() {
var html = HtmlService.createHtmlOutputFromFile('index');
var ui = SpreadsheetApp.getUi()
ui.showModalDialog(html, 'Shipping Email Options');
}
//This is where you need to write the logic...this function will be called when you click on the button
function readyToSendEmail(shippingNeeded, notes) {
}
Also, its better to add type="button" to both the button or else it can consider it as submit buttons.

Javascript does not write innerHTML of element but flashes result?

In this simple program, the script does not write result id="result" just flashes the resultant value. Can anybody take a look and show why this behavior? What am I doing wrong?
function multiplication() {
var product,
no1 = document.getElementById('no1').value,
no2 = document.getElementById('no2').value;
product = no1 * no2;
document.getElementById("result").innerHTML = product;
}
function division() {
var divis,
no1 = document.getElementById('no1').value,
no2 = document.getElementById('no2').value;
divis = no1 / no2;
document.getElementById("result").innerHTML = divis;
}
<h2>Write a JavaScript program to calculate multiplication and division of two numbers ?</h2>
<h3>Sample Form</h3>
<form name="sample" method="POST">
1st Number:
<input type="text" id="no1" name="firstno" /> 2nd Number:
<input type="text" id="no2" name="secondno" />
<button id="mul" onclick="multiplication();">Multiply</button>
<button id="div" onclick="division();">Division</button>
</form>
<p id="result"></p>
The submit button is clicked
The JavaScript runs
The form is submitted
A new page is loaded
The new page doesn't have the DOM changes that were on the old page.
Either prevent the default behaviour of the submit button or bind your event handler to a different kind of control.
Your JS is working but when the user clicks a submit button the form is also submitted, because that's the default action.
Prevent the form from submitting.
<form onsubmit="event.preventDefault();" name="sample" method="POST">
<button type="button" id="mul" onclick="multiplication();">Multiply</button>
<button type="button" id="div" onclick="division();">Division</button>
This might help you.

Radio buttons checked changing submit text

My site structure consists on an index.php which is styled by a css file. It then includes the following php code in a separate file:
<?php include("globals.php"); ?>
<form action="<?php echo $website.$relative_string;?>" name="subscribe" onsubmit="javascript:return checkEmail(this);" method="post">
<div id="cell8" class="titlecell2"><h3>Email:</h3></div>
<div id="cell9" class="inputcell2">
<input type="text" class="inputfield2" name="email" value="Your Email..." id="email2" maxlength="255" onfocus="this.value='';">
</div>
<div id="cell10" class="textcell3">
<input name="group" type="hidden" id="group[]" value="<?php echo $group; ?>">
<input name="subscribe" id="sub" type="radio" value="true" checked>
</span>Subscribe </p>
</div>
<div id="cell11" class="buttoncell">
<button type="submit" name="Submit2" value="Join" id="submitButton2">
<span>OK</span>
</button>
</div>
<div id="cell8" class="textcell4">
<input type="radio" name="subscribe" id="unsub" value="false">
</span>Un-Subscribe </p>
</div>
</form>
It appears on screen with no problems in the correct layout as my css style sheet. What I would like this to do is when I select the "Subscribe" radio button the submit button text "OK" changes to "Join". When I click on the Unsubscribe button text "OK" or "Join" changes to "Leave".
I tried to make some code from research:
if(document.getElementById('sub').checked) {
document.write("<span>Join</span>"
}
else if(document.getElementById('unsub').checked) {
document.write("<span>Leave</span>)
}
I think this kind of worked in that it changed to Join (replacing the OK line, but obviously didn't update on clicking unsubscribe. I guess it would update on refreshing the page if my default wasn't join. I guess I need to do some form of onclick but then I have no idea how to adjust that span ok bit.
Please help?
Many thanks Chris
Here is a solution in plain JavaScript without jQuery. It avoids the unnecessary overhead.
This should work, but I haven't had a chance to test it:
var sub = document.getElementById('sub'); // Save element to a variable, so you don't have to look for it again
var unsub = document.getElementById('unsub');
var btn = document.getElementById('submitButton2');
sub.onchange = function() //When sub changes
{
if(sub.checked) //If it's checked
{
btn.innerHTML = "<span>Join</span>"; // Set button to Join
}
else // If not..
{
btn.innerHTML = "<span>OK</span>"; // Set button to OK
}
}
unsub.onchange = function() //When unsub changes
{
if(unsub.checked) //If it's checked
{
btn.innerHTML = "<span>Leave</span>"; // Set button to Leave
}
else // If not..
{
btn.innerHTML = "<span>OK</span>"; // Set button to OK
}
}
However, you should not do it like this.
You should combine the two radio buttons into a radio group.
In that case you will listen for radio group to change, get the value of the radio group, set button text according to the value.
if you label your <span>OK</span> to something like <span id="your_id">OK</span> then added a class to your radio button like this <input class="your_class" type="radio" name="subscribe" id="unsub" value="false"> them...
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script>
$("#your_class").change(function () {
if ($(this).is(':checked')) {
$("#your_id").text('Join');
}else {
$("#your_id").text('Leave');
}
});
</script>
This was all written in the browser so let me know if there are any problems.

Categories