0

I have a button (in HTML) that both calls for a function LoginInfoInput(...) and redirect to a page (href="..."), that is:

<a onclick="LoginInfoInput('<?!= userID; ?>')" href="<?= ScriptApp.getService().getUrl(); ?>?v=form&userID=<?!= userID; ?>" class="waves-effect waves-light btn-large">Log In</a>,

where LoginInfoInput(...) is a javascript function that will trigger my google apps script (GS) function. The triggered GS function will then insert data into my spreadsheet. Meanwhile, the redirected URL will pass though my doGet() function. To determine the outcome, it gets data from my spreadsheet. My problem is that the spreadsheet is not always updated in time before redirecting the page takes action.

My attempt to solve the problem has been to wait/pause with a while-loop. However, when the while-loop is active during which the data becomes available in a spreadsheet (at least visually) does not work, i.e., the interesting data is not accessible. Note, I have also during the while-loop added the option to update the variable that stores the spreadsheet data (calling SpreadsheetApp.openByUrl(url)), however, without any improvement.

Update

My LoginInfoInput() (in JavaScript) is as follows:

function LoginInfoInput(userID){
  var userLO = document.getElementById("id_loginLO").value;
  var userPassword = document.getElementById("id_password").value;

  google.script.run.LoginAdd(userLO, userPassword, userID); 
}

Solution

My solution was a combination of the answer provided by @IMTheNachoMan see below and my discovery that the added data in GS to Spreadsheet can be delayed if not forcing the data to be updated. To force an update, one call SpreadsheetApp.flush(); link after inserting the data in Spreadsheet, in the GS function. From my understanding, the data needs to be in my Spreadsheet before I change my (GS)-based page as it will try to access the Spreadsheet at the time my (GS)-based page is called rather than when I call for my Spreadsheet when the data is available (by waiting/using while-loop).

WFTsai
  • 95
  • 1
  • 9
  • Thank you for replying. I apologize for the inconvenience and my poor English skill. I could understand that my answer was not suitable for your actual situation. So I have to delete my answer because I don't want to confuse other users. I deeply apologize for my poor skill. – Tanaike Jan 06 '20 at 22:20
  • Hi @Tanaike, no problem. Still, I do think you made a valuable suggestion. Hopefully, if I got everything correct, I will be able to post a solution soon. Probably, not as I initially anticipated, but that will fix the redirecting page problem. At that time (or before), you might be able to give some suggestions that you, yourself, can proudly present. All in all, I did appreciate your answer :). – WFTsai Jan 06 '20 at 22:43
  • Thank you for replying. I couldn't correctly understand about your goal because of my poor English skill. I thought that I have to apologize for this. On the other hand, from your question, I could study. I would like to study more and more. Thank you, too. When your issue was resolved, I'm glad. – Tanaike Jan 06 '20 at 22:47

1 Answers1

1

Replace your <a... with this:

<a onclick="return LoginInfoInput(this, '<?!= userID; ?>');" href="<?= ScriptApp.getService().getUrl(); ?>?v=form&userID=<?!= userID; ?>" class="waves-effect waves-light btn-large">Log In</a>

Replace your function with this:

function LoginInfoInput(a, userID)
{
    if(a.className == "done")
    {
        return true;
    }
    else
    {
        google.script.run.withSuccessHandler(function(){
            a.className = "done";
            a.click();
        }).LoginAdd();
    }
}

When the user clicks the link, className is not done so it calls your GAS function and returns false so the href is not opened. When the GAS function is done, it sets the className and then sets the clicks the link again. This time it returns true so the href would get run.

Does that make sense?

Note, you can also use withUserObject to pass the URL from a around.

Reference: https://developers.google.com/apps-script/guides/html/reference/run

IMTheNachoMan
  • 5,343
  • 5
  • 40
  • 89
  • Hi @IMTheNachoMan, I think I understand what you are trying to say but from my understanding, Google Apps Script will not allow the use of ```window.location.href```. In other words, I get the following message: "*Refused to display 'https://script.google.com/macros/s/...' in a frame because it set 'X-Frame-Options' to 'sameorigin'.*" – WFTsai Jan 09 '20 at 13:34
  • Oh. Doh. Let me keep trying. – IMTheNachoMan Jan 09 '20 at 17:23
  • Hi @IMTheNachoMan, I think you solved my problem. I just need to be sure that I can change the first ```href``` as currently at some attempts I think that the ```href```-action is faster than the ```onclick```-action. In its current state, it behaves as it did initially but now I think the code should allow for modifications (priorities). – WFTsai Jan 09 '20 at 22:36
  • You shouldn’t need to. The JavaScript onclick runs first. If it returns false it won’t execute the href. I am pretty sure. – IMTheNachoMan Jan 09 '20 at 23:42
  • Hi @IMTheNachoMan, Considering that the button both has a ```href```-action and an ```onclick```-action, where each of those can be activated separate without an additional click, my understanding is that the js-```click```-action allows for a click with modifications of ``````. If I misunderstand, I would like to know why in some instances the action of ```href``` takes place before the ```onclick```-action? – WFTsai Jan 10 '20 at 14:07
  • 1
    My understanding is that `onclick` goes first and as long as it doesn't return false it processes the `href`. In your case the `onclick` runs async so it kicks of a second 'thread' and then returns which then executes the `href`. – IMTheNachoMan Jan 10 '20 at 15:24
  • Thanks @IMTheNachoMan, I think you are right about that ```onclick``` and ```href``` runs async. Given that my code is run as expected, I have accepted your answer with some modifications accounting for the async process. My modifications are placed under **Solution** in my question, that is, in case you would like to know the end result of your contribution. :) – WFTsai Jan 10 '20 at 18:39
  • See this answer: https://stackoverflow.com/a/1346047/3383907. When an `a` element has an `onclick` and `href` attribute, when a user clicks on said `a` element, the browser will first process the `onclick` event. If, and only if, the `onclick` event **does not** return `false` then the browser will process the `href` element. In my code, when the user clicks the `a`, the `onclick` function returns `false` so the `href` is not processed. – IMTheNachoMan Jan 10 '20 at 18:46
  • Oh, in that case, I think your first answer was correct. I did change my **Solution** as I now strongly believe the problem after your first answer lies in that I did not force the data update in GAS. – WFTsai Jan 10 '20 at 19:35