How keep the Status keep appearing on JavaScript function to HTML - javascript

This is a continuation of previous question I made in this forum.
I made some changes in the code by adding else condition. What I'm trying to work out is to show the current status as the page loads. the current code shows the status only if the button get clicked.
How can I get the current status appear as the page loads and the status get updated when button get clicked.
CODE.GS
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('Index');
}
function checkStatus(notify) {
var employee = "John Peter";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var mainSheet = ss.getSheetByName("MAIN");
var data = mainSheet.getDataRange().getValues();
for (var j = 0; j < data.length; j++){
var row = data[j];
var mainSheet2 = row[4];
var mainSheet3 = row[0];
var status = (mainSheet2 =="IN" && mainSheet3 == employee) ;
if (status == true){
var notify = employee +" You Are In"
return notify;
}
else{
var status = (mainSheet2 =="OUT" && mainSheet3 == employee) ;
if (status == true){
var notify2 = employee +" You Are Out"
return notify2;
}
}
}
}
Index.html
<body>
<div>
<button onclick="onStatus()">Check Status</button>
<font color='Green' id="status" onbeforeprint="onStatus" ></font>
</div>
<script>
function onStatus() {
google.script.run.withSuccessHandler(updateStatus) // Send the backend result to updateStatus()
.checkStatus(); // Call the backend function
}
function updateStatus(notify) {
document.getElementById('status').innerHTML= notify;
}
</script>
</body>

You can invoke this function at page load like below. Add this script at then end, just before your body tag ends.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
// The code in this function runs when the page is loaded.
$(function() {
google.script.run.withSuccessHandler(updateStatus)
.checkStatus();
});
</script>

Related

How to Show Table from google speadsheet after login (Google Web App)

Everybody . I'm doing some mini web-app but I'm new in programming
,I followed tutorial from "Learn Google Spreadsheets" on Youtube but get a little bit confuse
My App is very simple
1.User login Page (Check Usercode and Pass from firebase) --- DONE!
2.Get data (get Usercode and find data row from spreadsheet) --- DONE!
3.Pass Object to Table --- Need help
var ss= SpreadsheetApp.openById('1l2Q7C5qBF7EsDInlHi1Bv76jeRJwWjixKteBkc8i3ik');
var PayrollSheet = ss.getSheetByName("ข้อมูลล่าสุด") ;
var Route = {} ;
Route.path = function(route,callback){
Route[route] = callback ;
}
function doGet(e) {
Route.path("Login",LoadLogin) ;
Route.path("Table",LoadTable) ;
if(Route[e.parameters.v]){
return Route[e.parameters.v]() ;
}else {
return render("Login") ;
}
}
function LoadLogin(){
return HtmlService.createTemplateFromFile('Login').evaluate() ;
}
function LoadTable(Usercode){
var TargetRow = GetRow(Usercode) ;
var Data = PayrollSheet.getRange(TargetRow,1,1,18).getValues().flat();
var Round = PayrollSheet.getRange(1,2,1,2).getValues().flat();
return render("Table",{array:Data,round:Round}) ;
}
function render(file,argsObject){
var tmp = HtmlService.createTemplateFromFile(file);
if(argsObject){
var keys = Object.keys(argsObject) ;
keys.forEach(function(key){
tmp[key] = argsObject[key] ;
});
} // END IF
return tmp.evaluate() ;
}
Javascript in html file
<script>
function LoginUser() {
var usercodeIn = document.getElementById("Usercode").value;
var passwordIn = document.getElementById("Password").value;
google.script.run.withSuccessHandler(function(User){
if(User != 'FALSE') // Found User
{
document.getElementById("errorMessage").innerHTML = "welcome " + User ;
google.script.run.LoadTable(usercodeIn) ;
}
else if(User == 'FALSE') //Not Found User
{
document.getElementById("errorMessage").innerHTML = "Wrong Password!";
}
}).checkLogin(usercodeIn,passwordIn);
}
</script>
After Login successful I try to run Loadtable(usercode) to render Table.html with data base on usercode but It only login and show success prompt , but not render Table.html
This is sound pretty easy, but I really don't know what to do ,So please help Thank you
Provided there are no Date objects in argsObject you could simply do tmp.argsObject = argsObject.
Code.gs
function render(file,argsObject){
var tmp = HtmlService.createTemplateFromFile(file);
if(argsObject){
tmp.argsObject = argsObject.
}
return tmp.evaluate() ;
}
Then in your templeted HTML.
<table>
<? for (let i = 0; i < argsObject.array.length; i++) { ?>
<tr><td><?= argsObject.array[i] ?></td></tr>
<? } ?>
</table>
Reference
Templated HTML

List file names during run time from App script HTML

I have created an app script to get list of all files available in Gdrive. While executing I m unable to pass the file names which are generated during the execution to tag.
My goal is to list the file names which are generated to be populated in HTML
Code.gs
var gSheetName;
var sheet = SpreadsheetApp.openById('1XyZ2m_knnyM7cLN-DtLcHyLX0pKOt5uASCcV8');
var sheets= sheet.getSheetByName('FileList');
var Fname, CountofFiles;
var sessionuser = Session.getActiveUser().getEmail();
function doGet(e) {
return HtmlService.createTemplateFromFile('params').evaluate();
}
function Start() {
try {
gSheetName=sheet.getId();
listFolders(DriveApp.getRootFolder());
return Fname;
}
catch(error) { return error.toString();}
}
function listFolders(folder) {
var folder = folder || DriveApp.getRootFolder();
var files = folder.getFiles();
var data;
while ( files.hasNext() ) {
var file1 = files.next();
var file1 = file1.getId();
var file=DriveApp.getFileById(file1);
var value = Math.floor((file.getLastUpdated()-file.getDateCreated())/(24*3600*1000));
var value1;
var emailid = Session.getActiveUser().getEmail();
Fname = file.getName(); //I want to list this file name in HTML one by one
fileList(Fname);
data = [
file.getName(),
file.getDateCreated(),
file.getLastUpdated(),
folder.getName(),
folder.getId(),
file.getSize()
];
sheets.appendRow(data);
data=[];
}
var subfolders = folder.getFolders();
while (subfolders.hasNext()) {
listFolders(subfolders.next());
}
}
function fileList(fileName) {
var Fname1 = Fname;
return Fname1;
}
params.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<form id="myForm">
<a class="waves-effect waves-light btn-large" onclick="google.script.run.withSuccessHandler(execute).Start();Showhide();">
<i class="material-icons left">cloud</i> Execute
</a>
</form>
<div id="output" style="display:none">
<p>Please wait while we are extracting records...</p>
<img src="https://media.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif">
</div>
<div id="Flist"></div>
<script>
function execute(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('Flist').innerHTML = execute();
document.getElementById('output').innerHTML = 'Completed';
}
function Showhide() {
var x = document.getElementById("output");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
I Need to display list of files which are generated by "Fname = file.getName();" this is where the file names are stored to the variable Fname. Is there a way i can populate these file names in HTML. I tried logging the records which is giving me the names in log but unfortunately i m unable to list in HTML tag. Please help me to solve this.
When you use google.script.run.withSuccessHandler(function) and the server function returns a value, the API passes the value to the new function as a parameter.
Which means when you call google.script.run.withSuccessHandler(execute).Start(), the return value of your Start() will be passed as an argument in your execute().
I noticed that you are trying to call your execute() to get your Flist here:
function execute(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('Flist').innerHTML = execute();
document.getElementById('output').innerHTML = 'Completed';
}
Sample Code Modification:
(code.gs - modified part only)
var Fname = [], CountofFiles;
function Start() {
try {
gSheetName=sheet.getId();
//Clear sheet
sheets.clear();
listFolders(DriveApp.getRootFolder());
return Fname;
}
catch(error) { return error.toString();}
}
function listFolders(folder) {
var folder = folder || DriveApp.getRootFolder();
var files = folder.getFiles();
var data;
while ( files.hasNext() ) {
var file1 = files.next();
var file1 = file1.getId();
var file=DriveApp.getFileById(file1);
var value = Math.floor((file.getLastUpdated()-file.getDateCreated())/(24*3600*1000));
var value1;
var emailid = Session.getActiveUser().getEmail();
//var fileFname = file.getName(); //I want to list this file name in HTML one by one
//fileList(file.getName());
Fname.push(file.getName());
data = [
file.getName(),
file.getDateCreated(),
file.getLastUpdated(),
folder.getName(),
folder.getId(),
file.getSize()
];
sheets.appendRow(data);
data=[];
}
var subfolders = folder.getFolders();
while (subfolders.hasNext()) {
listFolders(subfolders.next());
}
}
(params.html - modified part only)
function execute(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('Flist').innerHTML = status;
document.getElementById('output').innerHTML = 'Completed';
}
Changes done:
Clear FileList sheet every time you click Execute in your html page
I changed Fname to an array and push all file names found.
The array of file names returned by Start() will be passed as argument in your execute(status) hence you can access that in your status variable.
Output:

UPDATED: redirect url pass parameter from another page

I'm would like to do a 2 step process without the user knowing. Right now when the user click on the link from another page.
URL redirect to run some JavaScript function that updates the database.
Then pass the variable to view a document.
User clicks on this link from another page
Here is some of code in the JavaScript file:
<script type="text/javascript">
window.onload = function(){
var auditObject ="";
var audit_rec = {};
var redirLink = "";
if(document.URL.indexOf('?1w') > -1 {
redirLink = "https://www.wikipedia.org/";
auditObject = redirLink;
audit_rec.action = "OPEN";
audit_rec.object = auditObject;
audit_rec.object_type = "WINDOW";
audit_rec.status = "Y";
window.open(redirLink);
} else {
audit_rec.target = /MyServlet;
audit_rec.action = "OPEN";
audit_rec.object = TESTSITE;
audit_rec.object_type = "WINDOW";
audit_rec.status = "Y";
}
function audit(audit_rec) {
var strObject = audit_rec.object;
strObject = strObject.toLowerCase();
var strCategory = "";
if (strObject.indexOf("wiki") > -1) {
strCategory = "Wiki";
} else if strObject.indexOf("test") > -1) {
strCategory = "TEST Home Page";
}
//Send jQuery AJAX request to audit the user event.
$.post(audit_rec.target, {
ACTION_DATE : String(Date.now()),
DOMAIN : "TESTSITE",
ACTION : audit_rec.action,
OBJECT : audit_rec.object,
OBJECT_TYPE : audit_rec.object_type,
STATUS : audit_rec.status
});
}
//TEST initial page load.
audit(audit_rec);
}
</script>
Can someone help? Thanks
You could give your link a class or ID such as
<a id="doclink" href="http://website.com/docviewer.html?docId=ABC%2Fguide%3A%2F%2F'||i.guide||'">'||i.docno||'</a>
then use javascript to intercept it and run your ajax script to update the database. Here's how you'd do it in jQuery:
$('#doclink').click(function(e) {
var linkToFollow = $(this).attr('href');
e.preventDefault();
yourAjaxFunction(parameters, function() {
location.href = linkToFollow;
});
});
where the function containing the redirect is a callback function after your ajax script completes. This stops the link from being followed until you've run your ajax script.
if your question is to hide the parameters Here is the Answer
you just use input type as hidden the code like this
'||i.docno||'

Javascript 'onbeforeunload()' not working with a function call

I have this script below which is used in a survey. The problem I have is, onbeforeunload() works when I don't call a function inside it. If I make any function call(save_survey() or fetch_demographics()) inside it, the browser or the tab closes without any prompt.
<script type="text/javascript">
$(document).ready(function() {
$('#select_message').hide();
startTime = new Date().getTime();
});
loc = 0;
block_size = {{ block_size }};
sid = {{ sid }};
survey = {{ survey|tojson }};
survey_choices = '';
startTime = 0;
demographics_content = {};
function save_survey(sf)
{
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
var surveydat = '';
if(sf==1)
{ //Success
surveydat = 'sid='+sid+'&dem='+JSON.stringify(demographics_content)+'&loc='+loc+'&t='+t+'&survey_choice='+JSON.stringify(survey_choices);
}
if(sf==0)
{ //Fail
surveydat = 'sid='+sid+'&dem='+json_encode(demographics_content)+'&loc='+loc+'&t='+t+'&survey_choice='+json_encode(survey_choices);
}
//Survey Save Call
$.ajax({
type: 'POST',
url: '/save_surveyresponse/'+sf,
data: surveydat,
beforeSend:function(){
// this is where we append a loading image
$('#survey_holder').html('<div class="loading"><img src="/static/img/loading.gif" alt="Loading..." /></div>');
},
success:function(data){
// successful request; do something with the data
$('#ajax-panel').empty();
$('#survey_holder').html('Success');
alert("Dev Alert: All surveys are over! Saving data now...");
window.location.replace('http://localhost:5000/surveys/thankyou');
},
error:function(){
// failed request; give feedback to user
$('#survey_holder').html('<p class="error"><strong>Oops!</strong> Try that again in a few moments.</p>');
}
});
}
function verify_captcha()
{
// alert($('#g-recaptcha-response').html());
}
function block_by_block()
{
var div_content ='<table border="0" cellspacing="10" class="table-condensed"><tr>';
var ii=0;
var block = survey[loc];
var temp_array = block.split("::");
if(loc>=1)
{
var radio_val = $('input[name=block_child'+(loc-1)+']:checked', '#listform').val();
//console.log(radio_val);
if(radio_val!=undefined)
survey_choices += radio_val +'\t';
else
{
alert("Please select one of the choices");
loc--;
return false;
}
}
for(ii=0;ii<block_size;ii++)
{
//Chop the strings and change the div content
div_content+="<td>" + temp_array[ii]+"</td>";
div_content+="<td>" + ' <label class="btn btn-default"><input type="radio" id = "block_child'+loc+'" name="block_child'+loc+'" value="'+temp_array[ii]+'"></label></td>';
div_content+="</tr><tr>";
}
div_content+='<tr><td><input type="button" class="btn" value="Next" onClick="survey_handle()"></td><td>';
div_content+='<input type="button" class="btn" value="Quit" onClick="quit_survey()"></td></tr>';
div_content+="</table></br>";
$("#survey_holder").html(div_content);
//return Success;
}
function updateProgress()
{
var progress = (loc/survey.length)*100;
$('.progress-bar').css('width', progress+'%').attr('aria-valuenow', progress);
$("#active-bar").html(Math.ceil(progress));
}
function survey_handle()
{
if(loc==0)
{
verify_captcha();
$("#message").hide();
//Save the participant data and start showing survey
fetch_demographics();
block_by_block();
updateProgress();
$('#select_message').show();
}
else if(loc<survey.length)
{
block_by_block();
updateProgress();
}
else if(loc == survey.length)
{
//Save your data and show final page
$('#select_message').hide();
survey_choices += $('input[name=block_child'+(loc-1)+']:checked', '#listform').val()+'\t';
//alert(survey_choices);
//Great way to call AJAX
save_survey(1);
}
loc++;
return false;
}
</script>
<script type="text/javascript">
window.onbeforeunload = function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
//fetch_demographics();
save_survey(0);
return "You have spent "+Math.ceil(t)+ " minute/s on the survey!";
//!!delete last inserted element if not quit
}
</script>
I have checked whether those functions have any problem but they work fine when I call them from different part of the code. Later, I thought it might be because of unreachable function scope but its not the case. I have tried moving the onbeforeunload() at the end of script and the problem still persists. Wondering why this is happening, can anyone enlighten me?
I identified where the problem was. I am using json_encode instead of JSON.stringify and hence it is crashing(which I found and changed already in sf=1 case). That tip with debugger is invaluable. Also, its working fine even without async: false.
Thank you again #AdrianoRepetti!

Injection of contenscript into a page not working?

I injected contentscript into a page by :
//this is in background.js
chrome.tabs.executeScript(null, {"file": "contentscript.js"});
Then to check if it inserted well or not I modified an element on the page, but no changes made.
Did I inject it properly?
Here are my files :
background.js:
//injecting contentscript here
     chrome.tabs.executeScript(null, {"file": "contentscript.js"});
//receiving end
var title;
chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
if(message.method == 'setTitle')
title = message.title;
else if(message.method == 'getTitle')
sendResponse(title);
});
contentscript.js:
<script>
var table = document.getElementsByClassName("collapse")[0];
var marks = new Array();
for(var i=0;i<8;i++)
marks[i] = table.children[0].children[i+1].children[5].innerHTML;
var total=0;
for(var i=0;i<8;i++)
total += Number(marks[i]);
//code to send the data to background.js
var fromDOM = total;
chrome.runtime.sendMessage({method:'setTitle',title:fromDOM});
</script>
popup.js:
var total= 0,percentage = 0;
chrome.runtime.sendMessage({method:'getTitle'}, function(response){
$('.total').text(response);
percentage = total/7.25;
$('.percentage').text(percentage);
});
Why is this not working? Any changes or errors?
This is how my popup.html is looking :

Categories

Resources