Jump to content
arnbrhm

How can I select an item in this drop down?

Recommended Posts

arnbrhm

I'm trying to filter results on a website by selecting a specific location (any one will do) from a drop down.  Note:  The website takes a couple seconds for the Javascript to fully load everything.  Until it is fully loaded, you won't see the drop down.

So far, I have been able to find the drop down object but haven't been able to interact with it.    I was hoping to use _IEFormElementOptionSelect but I can't find any forms to interact with using _IEFormElementGetCollection.    Any ideas are welcome.  Thanks!  Note:   AutoIt Version: 3.3.14.2

#include <IE.au3>
#include <MsgBoxConstants.au3>

Local $strMainURL = "http://bidfta.bidqt.com/BidFTA/#/Main"

Local $oIE = _IECreate($strMainURL)

MsgBox(0,"pause","Press ok when page is ready")

Local $oSelect = _IEGetObjByName($oIE, "LocationSelect")

MsgBox($MB_SYSTEMMODAL, "ExampleForm", _IEPropertyGet($oSelect, "innertext") & @CRLF)

_IEQuit($oIE)

 

5aa13e1e89f7b_SelectLocation.png.befe665e8008d6c0411284e9170d0272.png

Share this post


Link to post
Share on other sites
arnbrhm

Good news!   I am now able to select the item I want from the dropdown menu using _IE_FormElementOptionSelect. The bad news is I can't get the webpage to recognize that a change has been made so it doesn't update the page.   I've attempted to use _IEAction() with "focus" and "click" but I've had no luck yet.  It appears this drop down doesn't have the typical onchange() event so I'm not sure how to get it to update.   I'm open to any new ideas.  Below is my updated code.

 

#include <IE.au3>
#include <MsgBoxConstants.au3>

Local $strMainURL = "http://bidfta.bidqt.com/BidFTA/#/Main"

Local $oIE = _IECreate($strMainURL)

MsgBox(0,"pause","Press ok when page is ready")

Local $oSelect = _IEGetObjByName($oIE, "LocationSelect")

ControlSend("Main - Internet Explorer","","","e")

_IEFormElementOptionSelect($oSelect,"Amelia, OH",1,"byText")

_IEAction($oSelect, "focus")
_IEAction($oSelect,"click")

MsgBox(0,"Done","Done")

_IEQuit($oIE)

 

Share this post


Link to post
Share on other sites
Danp2

You'll need to trigger the attached jQuery change event. Here's one way to do it --

#include <IE.au3>
#include <MsgBoxConstants.au3>

Local $strMainURL = "http://bidfta.bidqt.com/BidFTA/#/Main"

Local $oIE = _IECreate($strMainURL)

MsgBox(0,"pause","Press ok when page is ready")

Local $oSelect = _IEGetObjByName($oIE, "LocationSelect")

;ControlSend("Main - Internet Explorer","","","e")

_IEFormElementOptionSelect($oSelect,"Amelia, OH",1,"byText")

Local $jQuery = _jQuerify($oIE)
$jQuery("[name='LocationSelect']").trigger('change')

MsgBox(0,"Done","Done")

_IEQuit($oIE)



; #FUNCTION# ====================================================================================================================
; Name ..........: _jQuerify
; Description ...:
; Syntax ........: _jQuerify(Byref $oIE)
; Parameters ....: $oIE                 - Object variable of an InternetExplorer.Application.
; Return values .: an object variable pointing to the jQuery library
; Author ........: Chimp
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _jQuerify(ByRef $oIE)

    Local $msie, $jsEval, $jQuery, $otherlib = False

    $msie = Execute('$oIE.document.documentMode')

    If ($msie = "") Or Number($msie) < 11 Then ; an IE version < 11
        ; create a reference to the javascript eval() function
        $oIE.document.parentWindow.setTimeout('window.eval = eval', 0)
        Do
            Sleep(250)
            $jsEval = Execute('$oIE.Document.parentwindow.eval')
        Until IsObj($jsEval)

    Else ; IE version > = 11
        ; create a reference to the javascript eval() function
        $oIE.document.parentWindow.setTimeout('document.head.eval = eval', 0)
        Do
            Sleep(250)
            $jsEval = Execute('$oIE.Document.head.eval')
        Until IsObj($jsEval)

    EndIf

    ; if jQuery is not already loaded then load it
    If $jsEval("typeof jQuery=='undefined'") Then

        ; check if the '$' (dollar) name is already in use by other library
        If $jsEval("typeof $=='function'") Then $otherlib = True

        Local $oScript = $oIE.document.createElement('script');
        $oScript.type = 'text/javascript'

        ; If you want to load jQuery from a disk file use the following statement
        ; where i.e. jquery-1.9.1.js is the file containing the jQuery source
        ; (or also use a string variable containing the whole jQuery listing)
;~ $oScript.TextContent = FileRead(@ScriptDir & "\jquery-1.9.1.js") ; <--- from a file

        ; If you want to download jQuery from the web use this statement
        $oScript.src = 'https://code.jquery.com/jquery-latest.min.js' ; <--- from an url


        $oIE.document.getElementsByTagName('head').item(0).appendChild($oScript)
        Do
            Sleep(250)
        Until $jsEval("typeof jQuery == 'function'")
    EndIf

    Do
        Sleep(250)
        $jQuery = $jsEval("jQuery")
    Until IsObj($jQuery)

    If $otherlib Then $jsEval('jQuery.noConflict();')

    Return $jQuery
EndFunc   ;==>_jQuerify

 

  • Like 1

Share this post


Link to post
Share on other sites
arnbrhm

Danp2,

Your solution worked perfectly.  Thank you so much for your help.  I could not have done this without you.

Share this post


Link to post
Share on other sites
TheGreatMomo

I re-wrote my script to streamline it and make it easier to read can you assist with the last steps of pulling specific span values from a page.

My Script 2.0 =)  : 

#include <IE.au3>
#include <msgboxconstants.au3>
#include <array.au3>
#include <string.au3>
;~ ====================================================================================
;~ ~~~~~~~~~~~~~ToDO: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~ 1. Create a script to navigate to Timecard site [x]
;~ 2. find a way to isolate the frame [x]
;~ 3. find a way to isolate the current week link button ex 2018-05-13 [x]
;~ 4. click the New task button on the next page [x]
;~ 5. Select Break/Fix from the next page and click submit [x]
;~ 6. Get the variables for Sun - Sat Sum Variables at the bottom of the page [] <---- I am Stuck cannot associate specific string output to each day of the week
;~ 7. Create a logic script that makes var = 8 - sum of daily hrs []
;~ 8. Find a way to set the value for the New task line with the results of Var from step 7 []
;~ 9. Create GUI with check boxes that let you reconcile the hours for each day checkd with results

;~ ==============
Global $otime = _IECreate ("https://WebsiteURL.com")
_IELoadWait($otime)
$txt = ""
Global $oFrameobj = _IEFrameGetObjByName($otime, "gsft_main")  ; IFrame where timecard table is located

Local $oLinks = _IETagNameGetCollection($oFrameobj, "a")  ;Click to get into IFrame without invoking Cross site protections
For $oLink In $oLinks
    If $oLink.ClassName  = "linked formlink" Then
        _IEAction($oLink, "click")
         ExitLoop
    EndIf
Next
_IELoadWait($oFrameobj, 3000)

Local $oFrameobj = _IEFrameGetObjByName($otime, "gsft_main") ;This Line allows me to select the correct frame and get collection for the correct obj ID
;~ _IEbodywriteHTML($oFrameobj, "Hello iFrame!!")
_IEloadwait($oFrameobj)
Local $oTd = _IETagNameGetCollection($oFrameobj, "span") ; searches iframe for all TD objects - I was able to locate my object in both Span and TD

;~ For $spanValues In $oSpan
;~ If IsObj ($spanValues) Then
;~  If $spanValues.outerhtml Then
;~      $oAV = _StringBetween($Values.outerhtml, ">", "<")
;~      ConsoleWrite ($aTableData & @crlf & @extended) ; you can also try $spanValues.outerhtml
;~  EndIf
;~ EndIf
;~ Next

;~ ConsoleWrite ("===END SPAN Objects===" & @crlf)


;~ ================== _IEQuerySelectAll is AWESOME!  Set $oDoc to point to IFrame DocObj===========
If Not @error Then
    $oDoc = _IEDocGetObj($oFrameobj)
;~  $oElements = _IEquerySelectorAll($oDoc, ".aggregate_value")
;~  If ISobj($oElements) Then
;~      MsgBox (0, "Agg value", $oElements)
;~  EndIf
    $oElements = _IEquerySelectorAll($oDoc, "span.aggregate_value")   ; Identify all Span elements with the aggregate_value for all incidents created  for each day of the week
    If IsObj($oElements) Then
        For $iElement_idx = 1 To $oElements.length
            ConsoleWrite($oElements.item($iElement_idx).innertext & @LF)  ;writes to console all timecard aggregave values in table example Sum 1.5 for monday column
        Next
    EndIf
    _IELoadWait($oFrameobj, 300)
    $oDoc = _IEDocGetObj($oFrameobj)
    $oDElements = _IEquerySelectorAll($oDoc, "span.aggregate_value")  ;Gets the full Span OuterHTML Object Details for each column <Span: Class= Aggregate_value =""</Span>
    If IsObj($oDElements) Then
        For $iElement_idx = 1 To $oDElements.length
            ConsoleWrite($oDElements.item($iElement_idx).OuterHTML & @LF)
            Local $oSums = String ($oDElements.item($iElement_idx).OuterHTML & @LF)
            Local $sMondayV= StringMid($oSums, 124,3)  ; Use stringinstr($oSums, "Monday",0,1,1,1) to get the 1st value  124= substring position start point, the next value is how many characters to extract after the starting point 3 characters for 0.1
            Local $sMonday = StringMid($oSums, 72, 6)
            Sleep( 500 )
            ConsoleWrite($sMondayV &@LF)
            If String ($sMonday) = "monday" Then
                Global $oMonSum = $sMonday  ; sets global variable for  "Monday" string value
;~              ConsoleWrite($oMonSum)
            EndIf
            If String ($sMondayV) = "0.4" Then ; creates a global variable for monday sum value
                Global $oMonSumV = $sMondayV
;~              ConsoleWrite($oMonSumV)
            EndIf
;~===================this is where I stuck! how do i associate the .04 value with the Monday span values, I want to have it read the span outerhtml:
;~ <span class="aggregate_value" aggregate_display="0.4" aggregate_field="monday" aggregate_value="0.40" aggregate_type="SUM">0.4</span>  Identify it is monday and identify the value and  use logic if string $spanMonday has both "monday" and value*
        Next
    EndIf
EndIf






Func _IEquerySelectorAll(ByRef $oDoc, $sQuery, $iItemIndex = Default)
    If Not IsObj($oDoc) Then
        ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IEStatus_InvalidDataType & " Invalid DataType" & @LF)
        Return SetError($_IEStatus_InvalidDataType, 1, 0)
    ElseIf Not __IEIsObjType($oDoc, "browserdom") Then
        ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IEStatus_InvalidObjectType & " Invalid ObjectType" & @LF)
        Return SetError($_IEStatus_InvalidObjectType, 2, 0)
    ElseIf Not IsNumber($iItemIndex) And $iItemIndex <> Default Then
        ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IEStatus_InvalidValue & " Invalid Index" & @LF)
        Return SetError($_IEStatus_InvalidValue, 3, 0)
    ElseIf $iItemIndex = Default Or $iItemIndex >= 0 Then
        Local $oTemp = Null
        If __IEIsObjType($oDoc, "documentcontainer") Then
            $oTemp = _IEDocGetObj($oDoc)
            ConsoleWriteError("--> _IEDocGetObj Error: " & @error & " Ext: " & @extended & @LF)
            If @error Then Return SetError(@error, @extended, 0)
        Else
            $oTemp = $oDoc
        EndIf
        Local $oClassColl = $oTemp.querySelectorAll($sQuery)
        If @error Then
            ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IESTATUS_GeneralError & " GeneralError1: " & @error & @LF)
            Return SetError($_IESTATUS_GeneralError, 3, 0)
        ElseIf (Not IsObj($oClassColl)) Or $oClassColl = Null Or $oClassColl.length = 0 Then
            ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IEStatus_NoMatch & " NoMatch" & @LF)
            Return SetError($_IEStatus_NoMatch, 0, 0) ; Could be caused by parameter 2, 3 or both
        Else
            If $iItemIndex = Default Then
                Return SetError($_IEStatus_Success, $oClassColl.length, $oClassColl)
            ElseIf $iItemIndex > $oClassColl.length Then
                ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IEStatus_InvalidValue & " Invalid Value" & @LF)
                Return SetError($_IEStatus_InvalidValue, $oClassColl.length, 0)
            Else
                $oItem = $oClassColl.Item($iItemIndex)
                If @error Then
                    ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IESTATUS_GeneralError & " GeneralError2: " & @error & @LF)
                    Return SetError($_IESTATUS_GeneralError, 3, 0)
                ElseIf (Not IsObj($oItem)) Or $oItem = Null Then
                    ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IEStatus_NoMatch & " NoMatch Index: " & $iItemIndex & @LF)
                    Return SetError($_IEStatus_NoMatch, 0, 0) ; Could be caused by parameter 2, 3 or both
                Else
                    Return SetError($_IEStatus_Success, 0, $oItem)
                EndIf
            EndIf
        EndIf
    Else
        ConsoleWriteError("--> _IEquerySelectorAll Error: " & $_IEStatus_InvalidValue & " Invalid Value: " & $iItemIndex & @LF)
        Return SetError($_IEStatus_InvalidValue, 3, 0)
    EndIf
EndFunc   ;==>_IEquerySelectorAll

; User's COM error function.
; After SetUp with ObjEvent("AutoIt.Error", ....) will be called if COM error occurs
Func _User_ErrFunc($oError)
    ; Do anything here.
    ConsoleWrite(@ScriptFullPath & " (" & $oError.scriptline & ") : ==> COM Error intercepted !" & @CRLF & _
            @TAB & "err.number is: " & @TAB & @TAB & "0x" & Hex($oError.number) & @CRLF & _
            @TAB & "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
            @TAB & "err.description is: " & @TAB & $oError.description & @CRLF & _
            @TAB & "err.source is: " & @TAB & @TAB & $oError.source & @CRLF & _
            @TAB & "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
            @TAB & "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
            @TAB & "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
            @TAB & "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
            @TAB & "err.retcode is: " & @TAB & "0x" & Hex($oError.retcode) & @CRLF & @CRLF)
EndFunc   ;==>_User_ErrFunc

SCITE OUTPUT:

>"C:\Program Files (x86)\AutoIt3\SciTE\..\AutoIt3.exe" "C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.au3" /run /prod /ErrorStdOut /in "C:\AutoIT\Projects\ServiceNow TimeKeeping\ServiceNow Aggregate Value Get.au3" /UserParams    
+>08:10:46 Starting AutoIt3Wrapper v.17.224.935.0 SciTE v.3.7.3.0   Keyboard:00000409  OS:WIN_10/  CPU:X64 OS:X64  Environment(Language:0409)  CodePage:0  utf8.auto.check:4
+>         SciTEDir => C:\Program Files (x86)\AutoIt3\SciTE   UserDir => C:\Users\FREES\AppData\Local\AutoIt v3\SciTE\AutoIt3Wrapper   SCITE_USERHOME => C:\Users\FREES\AppData\Local\AutoIt v3\SciTE 
>Running AU3Check (3.3.14.5)  from:C:\Program Files (x86)\AutoIt3  input:C:\Users\FREES\OneDrive\Desktop\coding\AutoIT\Projects\ServiceNow TimeKeeping\ServiceNow Aggregate Value Get.au3
+>08:10:46 AU3Check ended.rc:0
>Running:(3.3.14.5):C:\Program Files (x86)\AutoIt3\autoit3_x64.exe "C:\Users\FREES\OneDrive\Desktop\coding\AutoIT\Projects\ServiceNow TimeKeeping\ServiceNow Aggregate Value Get.au3"    
--> Press Ctrl+Alt+Break to Restart or Ctrl+Break to Stop


0.4
0.4
1.4
0
0
0
0
2.2

<span class="aggregate_value" aggregate_display="" aggregate_field="task" aggregate_value="" aggregate_type=""></span>

<span class="aggregate_value" aggregate_display="" aggregate_field="u_notes" aggregate_value="" aggregate_type=""></span>

<span class="aggregate_value" aggregate_display="0.4" aggregate_field="sunday" aggregate_value="0.40" aggregate_type="SUM">0.4</span>
0.4 
<span class="aggregate_value" aggregate_display="0.4" aggregate_field="monday" aggregate_value="0.40" aggregate_type="SUM">0.4</span>
0.4
<span class="aggregate_value" aggregate_display="1.4" aggregate_field="tuesday" aggregate_value="1.40" aggregate_type="SUM">1.4</span>
>1.
<span class="aggregate_value" aggregate_display="0" aggregate_field="wednesday" aggregate_value="0.00" aggregate_type="SUM">0</span>
>0<
<span class="aggregate_value" aggregate_display="0" aggregate_field="thursday" aggregate_value="0.00" aggregate_type="SUM">0</span>
0</
<span class="aggregate_value" aggregate_display="0" aggregate_field="friday" aggregate_value="0.00" aggregate_type="SUM">0</span>
/sp
<span class="aggregate_value" aggregate_display="0" aggregate_field="saturday" aggregate_value="0.00" aggregate_type="SUM">0</span>
0</
<span class="aggregate_value" aggregate_display="2.2" aggregate_field="total" aggregate_value="2.20" aggregate_type="SUM">2.2</span>
.2<


+>08:11:02 AutoIt3.exe ended.rc:0
+>08:11:02 AutoIt3Wrapper Finished.
>Exit code: 0    Time: 17.03

I am really close to the finish line with this script, I am able to get the span parent node value# from "aggregate_value" and outerHTML child node value from "aggregate_field" but I can't seem to put the two things together. 


I just want to have it scan the span output  like: "<span class="aggregate_value" aggregate_display="0.4" aggregate_field="sunday" aggregate_value="0.40" aggregate_type="SUM">0.4</span> "and check that Monday and 0.4 are from the same line in my output. ... I can seem to wrap my head around it. I know its something simple like             

Local $oSums = String ($oDElements.item($iElement_idx).OuterHTML & @LF)  sets up the string Variable and then do a basic search within the string... If StringMid( $oSums, "string Position: 124", " 3 chars to extract") =  "0.4" AND If StringMid( $oSums, "string Position: 72", " 7 chars to extract") =  "monday" Then
    Local $VarMonday = "Var that = 0.4"
    Local $MonVarReconcile = ("8" - $VarMonday)
    
;~ Click new task button and enter $MonVarReconcile
    local $oNewBtn = _IEGetObjById($oFrameobj, "sysverb_new")
    _IEAction($oNewBtn, "click") ;Clicks New on Time_Card week view window to create a new task below.
    _IELoadWait($oFrameobj)
    Local $oTaskSel = _IEGetObjByName ($oFrameobj, "time_card.category") ; Narrowing down Objects from IE window by creating a Variable "$oTaskSel" to use when searching Objects inside iFrame Object "$oFrameobj" for properties of object named "time_card.category"
    ControlSend("Main - Internet Explorer","","","e")
    _IEFormElementOptionSelect($oTaskSel,"Break/Fix: Incident Standby",1,"byText") ; OBJECT Selection command for  "Break/Fix: Incident Standby"
    _IEAction($oTaskSel, "focus")
    _IEAction($oTaskSel, "click")
    Sleep(300)
    Local $oSubmitTask = _IEGetObjById ($oFrameobj, "sysverb_insert") ; OBJECT = "Submit" button bottom of Task Category Select page
    _IEAction($oSubmitTask, "click")   Not Ready to test this yet, still need to get a list of variables for  Sun-Sat sum values AND then ready to create new field to test.
    _IELoadwait($oFrameObj)
   Local $MonNewInput = _IEPropertyGet($oFrameObj, "monday_newinputbox.innerhtml")
   _IEPropertySet($MonNewInput, $MonVarReconcile)
                    

I dunno I hope you guys can help me out with this

Share this post


Link to post
Share on other sites
Danp2

I would recommend using the same jQuerify solution. The code would look something like this --

$sValue = $jQuery('.aggregate_value[aggregate_field="monday"]').innerText

This may not be the exact selector needed, but should hopefully get you going in the right direction.

Share this post


Link to post
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

×