Android Question Simulate button press on web page

sconlon

Active Member
Licensed User
My app aims to make a golf booking via a booking page on my golf club website. I have so far programmed the log in and loaded the required booking page (into a webview) which has rows of time slots for 4 players. The html source for each row is something like:

B4X:
<tr>
<td class="t_h" align="center">16:30</td>
<td class=t_s align=center>18<span title="Start">S</span></td>
<td class="t_s">MENS SEMI OPEN 13 HOLES FOURBALL</td>
<td class="R6">Competition</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td class="teeCell"  >
<form method="POST" action="members_booking.php?operation=member_booking_form" onSubmit="return ValidateMemberBookNow(this)">
<input name="double_click" type="hidden">
<input name="course_id" type="hidden" value="3">
<input name="d_date"    type="hidden" value="2019-03-06">
<input name="TeeTime"   type="hidden" value="16:30:00">
<input name="SubmitButton" type="submit" value="Book Now">
</form>
</td>
</tr>
<tr>
When the user clicks on the Book Now button a further page is loaded in which he selected the player names. Should I be able to use WebViewExtras1.executeJavascript with a suitable javascript (which I'm not very familiar with) to simulate pressing the Book Now button or is there some other way of doing this?

Thanks.
 

sorex

Expert
Licensed User
I never used the webextras lib but I believe you can inject javascript in the webview with it.

The form doesn't have an ID so you have to rely on being the first, second, whatever form on the page.

You can then use

B4X:
document.forms[0].submit()
if it is the first one in the source.

you might need to set that double_click hidden value to something before it will work tho as it seems to be some automatic booking flood 'protection'
 

sconlon

Active Member
Licensed User
Thanks for the reply. It was the fact that the form did not have a name (unlike the one for login) that made me wonder if there was some other way of ding this. Depending on which time slot you want to book the form may not be the first one. Perhaps I could loop through all the forms to get the desired time slot and then use its index in the submit.
 

sconlon

Active Member
Licensed User
So when I get the form index, eg 11, and try

B4X:
    Dim js As StringBuilder
    js.Initialize
    js.Append("document.forms[11].double_click.value = '1';")
    js.Append("document.forms[11].course_id.value='3';")
    js.Append("document.forms[11].d_date.value='2019-03-06';")
    js.Append("document.forms[11].Teetime.value='15:00';")
    js.Append("document.forms.[11].submit()")
    WebViewExtras1.executeJavascript(WebView1, js)
I get an error :
"Uncaught SyntaxError: Unexpected token [ in https://www.xxxgolf.com/server27/me...ber_day&amp;course_id=3&amp;d_date=2019-03-06 (Line: 1)"

I did try it without setting a value for double_click and got the same error.
 

sorex

Expert
Licensed User
your javascript is wrong.

you either use getElementById if your items have an id (which is not the case) or you use document.forms[11]['double_click'].value=1
 

sconlon

Active Member
Licensed User
So I've changed the code to:
B4X:
    js.Append("document.forms[11]['double_click'].value = 1;")
    js.Append("document.forms[11]['course_id'].value=3;")
    js.Append("document.forms[11]['d_date'].value=2019-03-06;")
    js.Append("document.forms[11]['TeeTime'].value=15:00;")
    js.Append("document.forms[11].submit()")
    WebViewExtras1.executeJavascript(WebView1, js)
It gives the same error.
"Uncaught SyntaxError: Unexpected token : in https://www.xxxgolf.com/server27/me...tion=member_day&course_id=3&d_date=2019-03-06 (Line: 1)"

Note that when I do this manually on the website the url that is loaded when I click the Book Now button is
"https://www.xxxgolf.com/server27/members_booking.php?operation=member_booking_form"
which is not the one reported in the error above.
 

sconlon

Active Member
Licensed User
Not sure since it is a 3rd party website but presumably checks if the logged in member is authorised to make the booking.
 

sconlon

Active Member
Licensed User
This is the function code:

B4X:
function ValidateMemberBookNow(form)
   {
       if (form.SubmitButton.value == "Confirm Booking") {
       form.SubmitButton.disabled = true;
       form.SubmitButton.value = 'Wait...';
    }

   if (form.double_click.value == "Yes")
      {
      alert("Warning: You have clicked the 'Booking' button twice.\nThis will send two requests to the server and result in a slower response.\nFor optimum performance, please press all buttons in the booking system only once.");
      return false;
      }

   form.double_click.value = "Yes";
   return true;
   }
 

Brandsum

Well-Known Member
Licensed User
The title of this thread is the answer!!

Triggering form submission from JavaScript will ignore the onSubmit function. So you have to simulate a submit button click instead of submitting the form directly.
B4X:
Dim js As StringBuilder
    js.Initialize
    js.Append("document.forms[11].double_click.value = '1';")
    js.Append("document.forms[11].course_id.value='3';")
    js.Append("document.forms[11].d_date.value='2019-03-06';")
    js.Append("document.forms[11].Teetime.value='15:00';")
    js.Append("document.forms.[11].SubmitButton.click()")
    WebViewExtras1.executeJavascript(WebView1, js)
 

sorex

Expert
Licensed User
there's no rocket science happening in the function called by the onsubmit so it should work the submit() way aswell if implemented correctly.
(for example his time & date lack quotes which will brake the JS code already)

it's better to parse pages and use your own display & post methods instead of using this webview hackering imho.
 

sconlon

Active Member
Licensed User
it's better to parse pages and use your own display & post methods instead of using this webview hackering imho.
I really wouldn't know how to do that so thought the existing form submission approach would be easier. A simple example of your suggestion would help!
 

sorex

Expert
Licensed User
the ideas is to drop the webview and read in the website page and then parse the data with regex filters or other methods.
then you build up the post data and send it back to the server.

if you plan an IOS release you can forget about the way you do it now as it won't pass the review team.

for now I guess you better stick to what you already have.

if you can wrap up the project and PM a link to it I'll have a look at where it goes wrong.
 

sconlon

Active Member
Licensed User
I'm away from PC until Monday but will get back to it then. Thanks for all the help guys.
 
Top