使用javascript更改AngularJS输入文本值

时间:2022-08-22 08:53:44

I'm trying to run javascript in a browser extension to automate a process of filling in a form on a website and then clicking a button -- the extension code can be simulated by typing javascript:code into the address bar.

我正在尝试在浏览器扩展中运行javascript以自动完成在网站上填写表单然后单击按钮的过程 - 可以通过在地址栏中键入javascript:code来模拟扩展代码。

The website that I'm having problems with uses angularJS. I have the names of the input field ids and am using those to change the input field values. The fields fill up but when I click the button it says they are not filled, there are no values and they are all in error. Some validation is going on that does not "see" my changes unless I type in the values manually.

我遇到问题的网站使用angularJS。我有输入字段ID的名称,并使用它们来更改输入字段值。字段填满但是当我点击按钮时它表示它们没有填充,没有值,它们都是错误的。除非我手动输入值,否则会进行一些不会“看到”我的更改的验证。

Is there a simple way to change the value of the AngularJS input fields that have validation using just the id of the input field.

是否有一种简单的方法来更改仅使用输入字段的id进行验证的AngularJS输入字段的值。

Here is the code:

这是代码:

<input id="shippingAddr-first-name" type="text" class="first-name ng-pristine ng-valid" maxlength="16" data-ng-model="addressTypes[addressType].FirstName" focus-me="commonAddressTypeProps[addressType].focusOnFirstName" client-validation="onExit" data-required-on-exit="">

My attempts using document.getElementById("shippingAddr-first-name").value="Dave"; change the field but do not register correctly during the form submission. It does work however if I type it in manually. I've also tried click(),blur(),focus(), to simulate some things I might be doing manually but those do not work either.

我尝试使用document.getElementById(“shippingAddr-first-name”)。value =“Dave”;更改字段但在表单提交期间未正确注册。但是,如果我手动输入它,它确实有效。我也尝试过click(),blur(),focus()来模拟我可能手动做的一些事情,但那些也不起作用。

3 个解决方案

#1


5  

Trigger input event on element with ng-model attribute that is observable by AngularJS. Event input is the way from where Angular knows that some changes occurs and it must run $digest loop

使用AngularJS可观察的ng-model属性触发元素上的输入事件。事件输入是Angular知道发生某些更改并且必须运行$ digest循环的方式

Some source code:

一些源代码:

// if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
  // input event on backspace, delete or cut
  if ($sniffer.hasEvent('input')) {
    element.on('input', listener);
  } else {
    var timeout;

    var deferListener = function(ev, input, origValue) {
      if (!timeout) {
        timeout = $browser.defer(function() {
          timeout = null;
          if (!input || input.value !== origValue) {
            listener(ev);
          }
        });
      }
    };

    element.on('keydown', function(event) {
      var key = event.keyCode;

      // ignore
      //    command            modifiers                   arrows
      if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;

      deferListener(event, this, this.value);
    });

    // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
    if ($sniffer.hasEvent('paste')) {
      element.on('paste cut', deferListener);
    }
  }

Some working proof of concept:

一些工作概念证明:

angular.module('app', []).controller('app', function($scope) {
  $scope.user = {}
  $scope.handleSubmit = function(user) {
    alert('passed name ' + JSON.stringify(user))
  }
})

$(function() {
  $('#run').click(function() {
    fillElement($('[ng-model="user.name"]'), 'some user name')
    sendForm($('[ng-submit="handleSubmit(user)"]'));
  })

  function fillElement($el, text) {
    $el.val(text).trigger('input')
  }

  function sendForm($form) {
    $form.submit()
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div>
  <button id="run">Execute `input` event outside AngularJS</button>
</div>
<div ng-app="app">
  <div ng-controller="app">
    <form ng-submit="handleSubmit(user)">
      <input type="text" ng-model="user.name" />
      <input type="submit" id="submit" value="Submit" />
    </form>
  </div>
</div>

#2


3  

You should use the data binding of AngularJS, you put an ng-model on the input so you need to change that value to get/set the input value, in you controller you can do:

您应该使用AngularJS的数据绑定,在输入上放置一个ng-model,这样您就需要更改该值来获取/设置输入值,您可以在控制器中执行以下操作:

JSFiddle

的jsfiddle

.controller('myCtrl', function ($scope) {
    $scope.addressTypes = [];
    $scope.addressTypes['onetype'] = { FirstName: 'Dave'};
});

#3


2  

use angular.element

使用angular.element

angular.element(document.querySelector("#shippingAddr-first-name")).val("Dave");

#1


5  

Trigger input event on element with ng-model attribute that is observable by AngularJS. Event input is the way from where Angular knows that some changes occurs and it must run $digest loop

使用AngularJS可观察的ng-model属性触发元素上的输入事件。事件输入是Angular知道发生某些更改并且必须运行$ digest循环的方式

Some source code:

一些源代码:

// if the browser does support "input" event, we are fine - except on IE9 which doesn't fire the
  // input event on backspace, delete or cut
  if ($sniffer.hasEvent('input')) {
    element.on('input', listener);
  } else {
    var timeout;

    var deferListener = function(ev, input, origValue) {
      if (!timeout) {
        timeout = $browser.defer(function() {
          timeout = null;
          if (!input || input.value !== origValue) {
            listener(ev);
          }
        });
      }
    };

    element.on('keydown', function(event) {
      var key = event.keyCode;

      // ignore
      //    command            modifiers                   arrows
      if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;

      deferListener(event, this, this.value);
    });

    // if user modifies input value using context menu in IE, we need "paste" and "cut" events to catch it
    if ($sniffer.hasEvent('paste')) {
      element.on('paste cut', deferListener);
    }
  }

Some working proof of concept:

一些工作概念证明:

angular.module('app', []).controller('app', function($scope) {
  $scope.user = {}
  $scope.handleSubmit = function(user) {
    alert('passed name ' + JSON.stringify(user))
  }
})

$(function() {
  $('#run').click(function() {
    fillElement($('[ng-model="user.name"]'), 'some user name')
    sendForm($('[ng-submit="handleSubmit(user)"]'));
  })

  function fillElement($el, text) {
    $el.val(text).trigger('input')
  }

  function sendForm($form) {
    $form.submit()
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div>
  <button id="run">Execute `input` event outside AngularJS</button>
</div>
<div ng-app="app">
  <div ng-controller="app">
    <form ng-submit="handleSubmit(user)">
      <input type="text" ng-model="user.name" />
      <input type="submit" id="submit" value="Submit" />
    </form>
  </div>
</div>

#2


3  

You should use the data binding of AngularJS, you put an ng-model on the input so you need to change that value to get/set the input value, in you controller you can do:

您应该使用AngularJS的数据绑定,在输入上放置一个ng-model,这样您就需要更改该值来获取/设置输入值,您可以在控制器中执行以下操作:

JSFiddle

的jsfiddle

.controller('myCtrl', function ($scope) {
    $scope.addressTypes = [];
    $scope.addressTypes['onetype'] = { FirstName: 'Dave'};
});

#3


2  

use angular.element

使用angular.element

angular.element(document.querySelector("#shippingAddr-first-name")).val("Dave");