I want to submit text stored in a ng-model via JavaScript. I have the following code:
<!DOCTYPE html>
<html>
<script src=".1.5/angular.min.js"></script>
<body>
<div ng-app>
<div ng-controller="Ctrl">
<form ng-submit="submit()">Enter text here:
<input type="text" ng-model="in" name="text" />
<input type="submit" id="submit" value="Submit" /> <pre>Last input: {{active}}</pre>
</form>
</div>
</div>
<script>
function Ctrl($scope, $http) {
$scope.active = "none";
$scope.in = "enter input here";
$scope.submit = function () {
$http.post("do_something.php",{sometext:$scope.in})
.then(function(response) {
$scope.active = response.data;
});
};
}
</script>
</body>
</html>
I want to write an extension, that enters text into the input field and submits it.
I use JavaScript to access the elements which have the ng-model, and change their value:
document.getElementsByTagName("input")[0].value="hello";
this only changes the text in my input field, but does not affect the actual in-variable. when submitting the form via
document.getElementsByTagName("input")[1].click()
The submitted input is not the input it previously changed to, but instead the old input - not visible any more.
I think this is because changing values via Javascript does not change the ng-model according to the input fields value.
How can I do this properly?
I want to submit text stored in a ng-model via JavaScript. I have the following code:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis./ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<body>
<div ng-app>
<div ng-controller="Ctrl">
<form ng-submit="submit()">Enter text here:
<input type="text" ng-model="in" name="text" />
<input type="submit" id="submit" value="Submit" /> <pre>Last input: {{active}}</pre>
</form>
</div>
</div>
<script>
function Ctrl($scope, $http) {
$scope.active = "none";
$scope.in = "enter input here";
$scope.submit = function () {
$http.post("do_something.php",{sometext:$scope.in})
.then(function(response) {
$scope.active = response.data;
});
};
}
</script>
</body>
</html>
I want to write an extension, that enters text into the input field and submits it.
I use JavaScript to access the elements which have the ng-model, and change their value:
document.getElementsByTagName("input")[0].value="hello";
this only changes the text in my input field, but does not affect the actual in-variable. when submitting the form via
document.getElementsByTagName("input")[1].click()
The submitted input is not the input it previously changed to, but instead the old input - not visible any more.
I think this is because changing values via Javascript does not change the ng-model according to the input fields value.
How can I do this properly?
Share Improve this question asked Apr 18, 2016 at 15:20 Peter1807Peter1807 1849 bronze badges 4- 1 I'm a bit confused. You're setting the input value as "enter input here" are you wanting to use that as a placeholder initially? – Rob Commented Apr 18, 2016 at 15:25
- Do you use $scope.$apply after you set the value? – sebenalern Commented Apr 18, 2016 at 15:25
- You should put this in a directive. this article shows you the Agular way without the use of $apply – ste2425 Commented Apr 18, 2016 at 15:32
- @Rob Yes, it's probably bad form, this was just an example for me to work with and i could not bother to fill the field by hand. sebenalern No, i'll give it a try tomorrow, thanks! ste2425 I'll read it tomorrow, thanks! – Peter1807 Commented Apr 18, 2016 at 20:34
2 Answers
Reset to default 6This is not very good idea to modify Angular models from outside of the Angular app itself. But given that you have a good reason for that you can do it like this:
var input = angular.element(document.getElementsByTagName("input")[0]);
var model = input.controller('ngModel');
model.$setViewValue('New value');
model.$render();
input.parent('form').triggerHandler('submit');
By working with ngModelController directly you have a benefit that you don't have to know the actual model name. You just use ngModelController API. Another benefit is that you don't need to do error prone stuff like document.getElementsByTagName("input")[1].click()
. Instead, just directly trigger function used by ngSubmit
directive.
Here is a quick demo:
function Ctrl($scope) {
$scope.in = "enter input here";
$scope.submit = function() {
alert('Value submitted: ' + $scope.in);
};
}
function updateModel() {
var input = angular.element(document.getElementsByTagName("input")[0]);
var model = input.controller('ngModel');
model.$setViewValue('New value');
model.$render();
input.parent('form').triggerHandler('submit');
}
<script src="http://ajax.googleapis./ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<div ng-app ng-controller="Ctrl">
<form ng-submit="submit()">
Enter text here:
<input type="text" ng-model="in" name="text" />
<input type="submit" id="submit" value="Submit" />
</form>
</div>
<hr>
<p>Set model from outside of the Angular app.</p>
<button onclick="updateModel()">Set model</button>
You are going out from the angular environment... That should be avoided, but, sometimes it's needed: in that case you need to manually trigger the $digest
cycle, this is an example:
function onNoNgClick() {
var $scope = angular.element(document.getElementById('TestForm')).scope();
$scope.$apply(function() {
$scope.value = 'FOOBAZ';
return $scope.submitRequest();
});
}
function TestCtrl($scope) {
$scope.value = 'Initial Value';
$scope.submitRequest = function() {
console.log('sendData', $scope.value);
};
}
angular
.module('test', [])
.controller('TestCtrl', TestCtrl);
document.addEventListener('DOMContentLoaded', function() {
return document.getElementById('NoNG').addEventListener('click', onNoNgClick);
});
.no-ng {
padding: 1em;
border: 1px solid green;
margin: 5px;
}
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<section ng-app='test'>
<div ng-controller="TestCtrl">
<form ng-submit="submitRequest()" name="testRequest" id="TestForm">
<input type="text" ng-model="value" />
<button type="submit">Submit</button>
</form>
</div>
</section>
<div class="no-ng"><button id="NoNG">SetText: FOOBAZ</button></div>