Jump to content

Autoit and JavaScript passing information


Champak
 Share

Recommended Posts

I tried searching, but I can't search JavaScript.

I have a script with an embedded web page that has JavaScript in it(the JavaScript is programmed in my script itself). The JavaScript does all the fancy stuff with the web server. The problem is, I have a particular function that upon querying the site/Webserver too fast I have a msgbox ("alert" in JavaScript) pop up. I don't want the alert because that stops my app mid stride. I'd prefer the JavaScript pass the information instead of an alert back to the main app (autoit language) where I can put it in an array and deal with the issue after the function is finished.

So, how do I pass information from JavaScript to the app so I can put it in an array. Thanks.

Edited by Champak
Link to comment
Share on other sites

  • Moderators

Instead of the alert();, set an event, the use ObjEvent() in your code to capture it.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Different ways depending on what you can control yes/no in your tool

1. Make a html textbox with same front and backendcolor (and as such invisible but reachable with IUIAutomation or controlgettext functions)

1b. When not needed to be invisible make a textbox where you put the information you need

2. embed websocket in your javascript to connect to your autoit server tcp/ip listener in your AutoIT main part and make a simple communication pipe

3. objevent (but thats probably only for IE browser)

4. Make use of javascript to put something in the clipboard (but as far as i know you need flash for that)

5. ....

Link to comment
Share on other sites

  • Moderators

@junkew, he embedded it in his app, I have to assume he's using shell which is why ObjEvent was mentioned and probably the simplest way.

As far as your input type, not a bad idea, but would make more sense to just make it hidden with an "id" (unless your automation tool doesn't recognize that, but then again, if it's a shell embedded page, doesn't make sense to use non-standard methods).

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Thanks.

1/ I tried the text input, the info window isn't seeing it hidden or visible.

2/ I tried the copy to clipboard idea and they are not working, unless I'm coding them incorrectly

"           clipboardData.setData('Blah Blah', s);" & @CRLF & _

and tried

"               Copied = 'Blah blah';" & @CRLF & _
    "               Copied.execCommand('Copy');" & @CRLF & _

3/ I looked at the _IEInsertEventScript but it only has standard events like clicking. I need something to happen automatically with no interaction. I searched for a way to insert something that would automatically register and pass the information but couldn't find it.

4/ The websocket thing I don't even know where to begin with that. It's been at least 10 years since I've touched javascript and html before this.

 

What now?

Link to comment
Share on other sites

I don't know if I really understand your need...

My idea is to use an input (hidden type), set its value with Javascript, and retrieve its value with AutoIt... Not really clean, but it seems to work.

#Include <IE.au3>

Local $oIE = _IECreateEmbedded()

$hGUI = GUICreate("GUI", 800, 600)
GUICtrlCreateObj($oIE, 10, 40, 600, 360)

GUISetState()
_LoadPage($oIE)

$oDialog = _IEGetObjById($oIE, 'autoitDialog')


While 1
    $msg = GUIGetMsg()
    If $msg = -3 Then Exit
    
    If $oDialog.value <> "" Then
        MsgBox(0, "AutoIt MsgBox", "Message from browser : " & @CRLF & @CRLF & $oDialog.value)
        $oDialog.value = ''
    EndIf
    Sleep(10)
WEnd





Func _LoadPage($_oIE)

    _IENavigate($_oIE, "about:blank")
    
    Local $sHTML = ""
    $sHTML &= "<HTML>" & @CRLF
    $sHTML &= "<HEAD>" & @CRLF
    $sHTML &= "<SCRIPT LANGUAGE='JAVASCRIPT'>" & @CRLF
    $sHTML &= "function _alert(){" & @CRLF
    $sHTML &= "   document.getElementById('autoitDialog').value = document.getElementById('message').value" & @CRLF
    $sHTML &= "}" & @CRLF
    $sHTML &= "</SCRIPT>" & @CRLF
    $sHTML &= "</HEAD>" & @CRLF
    $sHTML &= "<BODY>" & @CRLF
    $sHTML &= "<input type='text' id='message' value='Text of the alert message...'>" & @CRLF
    $sHTML &= "<input type='button' onclick='_alert()' value='Click me !'>" & @CRLF
    $sHTML &= "<input type='hidden' id='autoitDialog'>" & @CRLF
    $sHTML &= "</BODY>" & @CRLF
    $sHTML &= "</HTML>"
    _IEDocWriteHTML($_oIE, $sHTML)
EndFunc
Link to comment
Share on other sites

  • Moderators
 

Thanks.

3/ I looked at the _IEInsertEventScript but it only has standard events like clicking. I need something to happen automatically with no interaction. I searched for a way to insert something that would automatically register and pass the information but couldn't find it.

 

100% sure I didn't imply using _IEInsertEventScript, ObjEvent tracks events happening in the DOM.  It's a callback option.

Then you can check within your au3 event handler code if it's what you're looking for.

Jguinch's code selection is something I've tried before and has worked for me, part of what else I was suggesting.

Since it seems you have access to the javascript code (based on how you worded your first post), this would be a very easy suggestion.  Just do a loop or a check when you want to see if there is a value in it.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

1. start AutoITserver code

2. open the html page

You should see the messagebox from the autoitserver as soon as html starts. So you could do this relatively easy

#include <MsgBoxConstants.au3>

; I am the server, start me first! (Start in second the TCPConnect example script).

Example()

Func Example()
    TCPStartup() ; Start the TCP service.

    ; Register OnAutoItExit to be called when the script is closed.
    OnAutoItExitRegister("OnAutoItExit")

    ; Assign Local variables the loopback IP Address and the Port.
    Local $sIPAddress = "127.0.0.1" ; This IP Address only works for testing on your own computer.
    Local $iPort = 65432 ; Port used for the connection.

    ; Bind to the IP Address and Port specified with a maximum of 100 pending connexions
    ;(Take a look at the example of this function for further details).
    Local $iListenSocket = TCPListen($sIPAddress, $iPort, 100)
    Local $iError = 0

    ; If an error occurred display the error code and return False.
    If @error Then
        ; Someone is probably already listening on this IP Address and Port (script already running?).
        $iError = @error
        MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Could not listen, Error code: " & $iError)
        Return False
    EndIf

    ; Assign Local variable to be used by Listening and Client sockets.
    Local $iSocket = 0
    Do ; Wait for someone to connect (Unlimited).
        ; Accept incomming connexions if present (Socket to close when finished; one socket per client).
        $iSocket = TCPAccept($iListenSocket)

        ; If an error occurred display the error code and return False.
        If @error Then
            $iError = @error
            MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "Could not accept the incoming connection, Error code: " & $iError)
            Return False
        EndIf
    Until $iSocket <> -1 ;if different from -1 a client is connected.

    ; Close the Listening socket to allow afterward binds.
    TCPCloseSocket($iListenSocket)

    MsgBox($MB_SYSTEMMODAL, "", "Client Connected.")

    ; Close the socket.
    TCPCloseSocket($iSocket)
EndFunc   ;==>Example

Func OnAutoItExit()
    TCPShutdown() ; Close the TCP service.
EndFunc   ;==>OnAutoItExit

save as websockettest.html

<!DOCTYPE html>  <meta charset="utf-8" />  <title>WebSocket Test</title>  <script language="javascript" type="text/javascript">  var wsUri = "ws://127.0.0.1:65432/"; var output;  function init() { output = document.getElementById("output"); testWebSocket(); }  function testWebSocket() { websocket = new WebSocket(wsUri); websocket.onopen = function(evt) { onOpen(evt) }; websocket.onclose = function(evt) { onClose(evt) }; websocket.onmessage = function(evt) { onMessage(evt) }; websocket.onerror = function(evt) { onError(evt) }; }  function onOpen(evt) { writeToScreen("CONNECTED"); doSend("WebSocket rocks"); }  function onClose(evt) { writeToScreen("DISCONNECTED"); }  function onMessage(evt) { writeToScreen('<span style="color: blue;">RESPONSE: ' + evt.data+'</span>'); websocket.close(); }  function onError(evt) { writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data); }  function doSend(message) { writeToScreen("SENT: " + message);  websocket.send(message); }  function writeToScreen(message) { var pre = document.createElement("p"); pre.style.wordWrap = "break-word"; pre.innerHTML = message; output.appendChild(pre); }  window.addEventListener("load", init, false);  </script>  <h2>WebSocket Test</h2>  <div id="output"></div>
Link to comment
Share on other sites

@junkew, thanks, but I want to try and work out the objevent because it seems neater and easier to navigate through.

@Smoke_N, you're right, I got turned around in everything trying to figure this out. This is what I've come up with.

This is how I set it up, I put the objevent at the top of the function calling the javascript.

Func GAS_CLICK_7()
    ObjEvent ( $gmap, "Gas_CLICK_7_Help", "NoPickUp" )
    FunctionCallingTheJavascriptpage()
EndFunc

Func Gas_CLICK_7_Help()
    MsgBox(0,0,0)
EndFunc

Then in the javascript I canceled out the alert and put the following in its place

"   evt = document.createEvent('EventNoPass');" & @CRLF & _;TOYE TEST
    "   evt.initEvent('NoPickUp',true,true);" & @CRLF & _;TOYE TEST
    "   evt.CustomData = 'BAR';" & @CRLF & _;TOYE TEST
    "   document.dispatchEvent(evt);" & @CRLF & _;TOYE TEST

Nothing is happening. If it helps I'm trying to work with the google map udf. Also note, after creating the event, just to test what's going on, if I leave the alert alone (not commenting it out) it no longer fires after the event creation.

Thanks.

Edited by Champak
Link to comment
Share on other sites

  • Moderators

The way you're utilizing ObjEvent is incorrect.

I covered something similar with someone a few weeks ago.

And helped them with an example in the next post after that.

Pay attention to the 2nd and 3rd parameters and compare to how you're utilizing it.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

OK, I fixed the parameters and moved where it's actually being called, but still nothing. 

ObjEvent ( $gmap, "_myevent_", "IDocumentEvent" )

and the function is now: _myevent_test()

and I also realized this was wrong:

"   evt = document.createEvent('EventNoPass');" & @CRLF & _

and changed it to

"   evt = document.createEvent('CustomEvent');" & @CRLF & _

 

But it's still not firing and I believe it has to do with the creation of the event, only because as I said before, if I leave the alert right after the creation and dispatch of the event the alert no longer fires. I even commented out everything creation process except:

" evt = document.createEvent('CustomEvent');" & @CRLF & _

and the alert still wont fire if it comes right under that, but once I comment that out the alert fires. So am I doing something wrong in this creation, or the coding? Or is that how this works in that it will cancel out the event which would be weird?

Link to comment
Share on other sites

Mmmh,

here the simple way:

in your html code set up a textfield like:

<textarea id="eventMsg" style="width: 200px;height:20px;font:8pt" title="Important events"></textarea>

In your html js.code put "eventMsg = document.getElementById('eventMsg');" into your startup-code. 

Replace your "alert" with something like: "eventMsg.value = 'myMsgToAutoIt'".

Now we want to catch this event/msg in AutoIt for the embedded object Internet explorer ($oIE).

So after $oIE.Navigate(....) and waitOnLoad (readyState = OK) call the following function.

func addHtmlListener()
  DIM $mapEvent = $oIe.document.all.eventMsg
 objEvent($mapEvent,"mapEvent_")
endfunc

 

After the basics are done, we have to set up the mapEvent_ function in AutoIt to catch every change of the property of the html-textfield:

func mapEvent_onPropertyChange()   ;(text in html-eventMsg field has changed)

 ;; get the msg string

 $mapEvent_strg = $mapEvent.value

 ..... do something with the msg you got .....

EndFunc

That's the simple solution and should work (like it works for my html page with Gmap API events).

SmOke_N's example show you much more possibilities.

Good luck, Reinhard

@SmOke_N

Thanks for the example.Saved it.
 

Link to comment
Share on other sites

Well, I just can't seem to get the event thing working. So I gave up on that and relented to do it the way I didn't. Junkew, I wasn't thinking straight with your original suggestion in making an invisible text box. I was trying to view the html text box with the info window the same way I would a GUI box not remembering obviously it wouldn't show up. So that's what I did, made a hidden element and placed the results in their on each loop, then used the _IE functions to retrieve needed information.

I don't know why I couldn't get the events to work, or how some of you got them to work when I've read that custom events are not possible with IE. Thank you all in your attempts to help.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...