【问题标题】:Which event to trigger, programmatically simulating user blur触发哪个事件,以编程方式模拟用户模糊
【发布时间】:2022-12-11 11:39:21
【问题描述】:

我正在使用带有执行 Javascript 流程的 Power Automate Desktop 来尝试自动执行 Quickbooks Online Payroll 表单中的一些用户输入。

在本机使用表单时,似乎在 blur 上触发了一个事件来验证数字输入等。

使用 JS 流程,更新输入值不会被表单识别,因为一旦我保存它,它就会将这些输入显示为空。

所以我想我需要触发 blur 事件来获取要保存的数据。这是我的 JS 脚本:

function ExecuteScript() { 
   var $payrollTableRows = $("table").first().find("tbody > tr.enabled");
   var $regHoursInput;
   var decRegHours;
   var $bonusInput;
   var employeeName;
   
   console.log('Power Automate: Rows Found: ' + $payrollTableRows.length);
   
   $payrollTableRows.each(function(){
   
        employeeName = $(this).find("td:eq(1)").find("a").text();
        
            $regHoursInput = $(this).find("input[wageitemid='HOURLY_PAY']");
            if($regHoursInput){
                    decRegHours = Number($regHoursInput .val());
                    
                    $bonusInput = $(this).find("input[wageitemid='BONUS']");
                    $bonusInput.focus();
    
                    if($bonusInput){
                        $bonusInput.val(decRegHours);
                        $bonusInput.trigger('blur');
                    } 
                } 
    });
}

这是在 QB Payroll 页面上的 focusblur 上执行的脚本。

为什么脚本启动的触发器不触发此代码?

更新 1:添加页面图像:

更新 2:贴出我用的PAD流程。还从this video 那里得到了很好的概述。以及如何使用 this article 的 Loop 和 Loop Index。

我的流程:

【问题讨论】:

  • 当您在浏览器控制台中运行它时会发生什么?
  • @CobyC - 没什么,它也不会触发代码

标签: javascript jquery automation power-automate-desktop


【解决方案1】:

要在不依赖 JavaScript 的情况下做类似的事情,您可以使用变量和循环。

用于此流程的 HTML:

<!DOCTYPE html>
<html lang="en">
<head>    
</head>
<body>
    <div class="table-responsive">
        <table class="table">
            <thead>
                <tr>
                    <th>Column A</th>
                    <th>Column B</th>
                    <th>Column C</th>
                    <th>Column D</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>A <input type="text" id="text-1-input" value="One"></td>
                    <td>B <input type="text" id="text-2-input" value="Two"></td>
                    <td>C <input type="text" id="text-3-input" value="Three"></td>
                    <td>D <input type="text" id="text-4-input" value="Four"onblur="txtOnblur();"></td>
                </tr>
                <tr>
                    <td><input type="text" id="text-5-input" ></td>
                    <td><input type="text" id="text-6-input" ></td>
                    <td><input type="text" id="text-7-input" ></td>
                    <td><input type="text" id="text-8-input" hidden></td>
                </tr>
                
            </tbody>
        </table>
    </div>    
    <script src="https://code.jquery.com/jquery-3.6.1.slim.min.js"></script>
    <script>
        function txtOnblur(){
            $("#text-8-input").show(true);
            $("#text-8-input").val('blur triggered!');
        }
    </script>
</body>
</html>

我使用了一些 JavaScript 来提取表格中的列数和行数,这可以通过流程功能“从网页中提取数据”来完成,但我发现 JavaScript 更快/更容易一些。

function ExecuteScript() {
var table = document.querySelector('body > div > table');
var colCount = table.children[0].children[0].children.length;
var rowCount = table.children[1].children.length;
return `${colCount} ${rowCount}`
}

声明第一个输入框的一个 UI 元素。您可以通过替换/更改选择器属性以使用变量来重用此元素。

在流程中分配将匹配特定控件的 HTML 选择器的值。

然后在任何你想更改/提取值的地方使用相同的元素(记住变量现在设置 UI 元素)

完整的流程代码(复制并粘贴到 PAD 以查看详细信息) 你这边会有错误,但你会看到流程。

WebAutomation.LaunchEdge.AttachToEdgeByUrl TabUrl: $'''http://localhost/stackoverAnswer/''' AttachTimeout: 5 BrowserInstance=> Browser
WebAutomation.ExecuteJavascript BrowserInstance: Browser Javascript: $'''function ExecuteScript() {
var table = document.querySelector('body > div > table');
var colCount = table.children[0].children[0].children.length;
var rowCount = table.children[1].children.length;
return `${colCount} ${rowCount}`
}''' Result=> cols_rows
Text.SplitText.Split Text: cols_rows StandardDelimiter: Text.StandardDelimiter.Space DelimiterTimes: 1 Result=> ColsAndRows
Text.ToNumber Text: ColsAndRows[0] Number=> numCols
Text.ToNumber Text: ColsAndRows[1] Number=> numRows
LOOP colIdx FROM 1 TO numCols STEP 1
    SET inputBoxVariable TO $'''text-%colIdx%-input'''
    WebAutomation.GetDetailsOfElement BrowserInstance: Browser Control: appmask['Web Page 'http://localhost/stackoverAnswer/'']['Input text 'text-1-input''] AttributeName: $'''Own Text''' AttributeValue=> inputBoxValue
    IF colIdx = 4 THEN
        WebAutomation.Focus.Focus BrowserInstance: Browser Control: appmask['Web Page 'http://localhost/stackoverAnswer/'']['Input text 'text-1-input''] WaitForPageToLoadTimeout: 60
        MouseAndKeyboard.SendKeys.FocusAndSendKeys TextToSend: $'''{Tab}''' DelayBetweenKeystrokes: 10 SendTextAsHardwareKeys: False
    END
    SET inputBoxVariable TO $'''text-%colIdx + 4%-input'''
    IF inputBoxValue <> $'''Three''' THEN
        WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserInstance: Browser Control: appmask['Web Page 'http://localhost/stackoverAnswer/'']['Input text 'text-1-input''] Text: inputBoxValue Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: False WaitForPageToLoadTimeout: 60
    ELSE
        WebAutomation.PopulateTextField.PopulateTextFieldUsePhysicalKeyboard BrowserInstance: Browser Control: appmask['Web Page 'http://localhost/stackoverAnswer/'']['Input text 'text-1-input''] Text: $'''Skip this one''' Mode: WebAutomation.PopulateTextMode.Replace UnfocusAfterPopulate: False WaitForPageToLoadTimeout: 60
    END
END

它是如何运行的:

【讨论】:

    【解决方案2】:

    我没有 QB,但我将一个带有脚本的快速 html 页面放在一起。

    这是html

        <!DOCTYPE html>
    <html lang="en">
    <head>    
    </head>
    <body>
        <div class="table-responsive">
            <table class="table">
                <thead>
                    <tr>
                        <th>Column 1</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>Value <input type="text" id="text-1-input" onblur="txtOnblur();">1</td>
                    </tr>
                    <tr>
                        <td>Value <input type="text" id="text-2-input" hidden></td>
                    </tr>
                    
                </tbody>
            </table>
        </div>    
        <script src="https://code.jquery.com/jquery-3.6.1.slim.min.js"></script>
        <script>
            function txtOnblur(){
                $("#text-2-input").show(true);
                $("#text-2-input").val('blur triggered!');
            }
        </script>
    </body>
    </html>
    

    当我使用 Power automate 在页面上运行以下脚本时,它会触发文本框上的 onblur 事件

    function ExecuteScript() {
    var $txt = $("input[id='text-1-input']");
          $txt[0].onblur();
    }
    

    在行动中:

    当我尝试以与您类似的方式调用代码时,我只会获得链接到模糊事件。

    我假设它是在 QB 中使用的 jQuery。当谈到 PAD 时,我倾向于坚持使用原生 JavaScript,更多的输入,但更少的抽象。

    【讨论】:

    • 感谢您为解决此问题所做的努力。我将脚本转换为纯 js 但仍然有同样的问题。我觉得我需要更好地确定 QBO 代码如何绑定到听众......以更好地模仿呼叫,但我只是猜测。 JS不是我的强项。
    • 完全没有问题,使用 JS 有什么特别的原因吗?看看 this answer 如果它试图遍历文本框可能会有所帮助,它可能有助于找到解决方案。
    • 对于每一行,我需要读取一个文本框中的值,复制它,然后将其粘贴到同一行的另一个文本框中……然后对所有行重复。我也有一些基于员工姓名的行排除项,所以实际上我需要先读取名称单元格值,然后如果名称不是提供的几个之一,则执行复制/粘贴。不确定如何在 PAD 中使用本机流程来做到这一点,因此在 JS 中也是如此。这可能只需要流程步骤吗?
    • 应该是,你能在你的问题中添加一张图片来显示屏幕的样子吗?空白/屏蔽任何个人信息。如果有一种方法可以使用 html 选择器识别单元格,那么您应该能够在流程中完成所有操作。它将是循环的组合,获取元素的详细信息,填充文本字段,变量。 UI 元素由它们的 html 选择器映射,您可以用变量全部或部分替换这些元素,或多或少类似于我之前评论中链接中的答案。只需更改它的 html 选择器,就可以操纵 1 个 UI 元素来表示任何其他元素。
    • 我添加了一张图片。高级逻辑是:对于每个行,如果 Employee NOT Jane Doe,则将 Regular Hours 复制到 OT Hours。 (实际上它是一个名为 Bonus 的专栏,但它使图像更宽......假装图像中的 OT HRS 说 BONUS。你可以在问题中看到我原始 JQuery 代码中的选择器......在每一行,它们都是带有属性 wageitemit 的输入,它的值是将其标识为小时工资与奖金的区别。我需要哪种类型的函数?一个是抓取行,然后循环读取 HOURLY_PAY 输入并粘贴到 BONUS 输入.
    猜你喜欢
    • 1970-01-01
    • 2015-10-30
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多