Update ng-model of input after input's value changed with jquery unsuccessfully - javascript

SITUATION:
This is just an example of what I'm trying to accomplish in a real project, where I get an array of names from a web service, then I locate the inputs with those names, select them and then set their values using jQuery.
PROBLEM:
What I need is to know how to update the ng-model of those fields which I changed their value attribute using jQuery
I have tried these
Update Angular model after setting input value with jQuery
Angular model doesn't update when changing input programmatically
Update HTML input value changes in angular ng-model
...but I haven't had luck with any of those options.
I'm using AngularJS v1.4.8 and jQuery v1.11.1
I have tried setting the input type to hidden and type text with style: display:none but I can't get it working properly.
Here is a demo of what I'm trying to do. This has and input and an span bind with the same ng-model.
When you click the button, it's supposed to change the input value using jQuery and then update the ng-model.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
</head>
<body data-ng-app="app">
<div data-ng-controller="myCtrl as ctrl">
<span>Value: {{ctrl.myValue}}</span>
<input name="myId" type="hidden" data-ng-model="ctrl.myValue" />
<button data-ng-click="ctrl.changeValue('ValueChanged')">Change Value</button>
</div>
<script>
//my controller
angular.module('app', [])
.controller('myCtrl', function(){
var vm = this;
vm.wizard = {
changeValue: fnChangeValue
}
return vm.wizard;
function fnChangeValue(newValue){
var e = $('#myId');
e.val(newValue);
e.trigger('input'); //first option
//e.triggerHandler('change'); //second option
}
});
</script>
</body>
</html>

Fixed ID and added jQuery's change() which is probably what you tried to do. Below you can find your code fixed. And here is how this is usually done with AngularJS alone: https://jsfiddle.net/rwtm1uh9/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<div data-ng-app="app">
<div data-ng-controller="myCtrl as ctrl">
<span>Value: {{ctrl.myValue}}</span>
<input id="myId" data-ng-model="ctrl.myValue" />
<button data-ng-click="ctrl.changeValue('ValueChanged')">Change Value</button>
</div>
<script>
//my controller
angular.module('app', [])
.controller('myCtrl', function() {
var vm = this;
vm.wizard = {
changeValue: fnChangeValue
}
return vm.wizard;
function fnChangeValue(newValue) {
var e = $('#myId');
e.val(newValue);
e.change();
}
});
</script>
</div>

You write var e = $('#myId'); and inside your input there is
<input name="myId" type="hidden" data-ng-model="ctrl.myValue2" />
I think you missed the id attribute try this instead :
<input id="myId" type="hidden" data-ng-model="ctrl.myValue2" />

Related

on-click event does not make the other field editable in one-click?

<!--Below is the html code-->
<div ng-init="InitializeFields()">
<input type="text" on-click="makeOtherReadOnly('1')"
readonly="show_or_not_first"/>
<input type="text" on-click="makeOtherReadOnly('2')" readonly="show_or_not_second"/>
</div>
// Now inside javascript
$scope.makeOtherReadOnly=function(number){
if(number==='1'){
show_or_not_second=true;
show_or_not_first=false;
show_or_not_second=true;
}else if(number==='2'){
show_or_not_first=true;
show_or_not_second=false;
}
};
$scope.Initializer=function(){
show_or_not_first=false;
show_or_not_second=false;
}
$scope.Initializer();
the problem that I am facing is as I click on the input field, it should turn the other field to readonly after pafe gets loaded and we have either field clicked, but it requires two click...
Every help is appreciated.
Try changing on-click to ng-click.
You need to correct few things ion your code :
change on-click to ng-click, So your function can be called from HTML.
Change readonly to ng-readonly, So you can utilize $scope property
In your ng-init, I guess you need to call Initializer() method to initialize default value.
Further just to make 2 input box readonly, you can chieve this by 1 flag. and no string comparison.
Simple Demo :
angular.module('myApp', []).controller('myCtrl', function($scope) {
$scope.makeOtherReadOnly = function(boolValue) {
console.log(boolValue);
$scope.data.first = boolValue;
};
$scope.Initializer = function() {
$scope.data = {
first: false
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-init="Initializer()">
First: <input type="text" ng-click="makeOtherReadOnly(false)"
ng-readonly="data.first" />
Second: <input type="text" ng-click="makeOtherReadOnly(true)"
ng-readonly="!data.first" />
</div>
</div>
There are two scopes here
javascript and angular
sometimes inside ng-click, javqascript function don't work
so change on-click to ng-click.

Angular using ng-model in input field get null

I know how to pass a value from a view to a controller using ng-model. In the controller it just gets the value from the view using this code $scope.name = this.ngmodelnameinview.
Is it compulsory to use ng-model in field view?
but my problem now is, I have + button, which when I click the button it will automatically put the value inside input text field.
<button data-ng-click="adultCount = adultCount+1"> + </button>
<input type="text" name="totTicket" value="{{adultCount}}">
see picture below:
but when I add ng-model inside input field, it returns null
<input type="text" name="totTicket" value="{{adultCount}}" ng-model="adultcount">
How to fix this? Thanks!
It is giving null just because you have set a value "adultCount" and in ng-model you had given a different name "adultcount" ('c' is in lower case). By updating ng-model with "adultCount", will solve this issue.
JavaScript is case sensitive:
JavaScript is case-sensitive and uses the Unicode character set.1
Use the same case for the scope variable. Update the input attribute ng-model to match the varible - i.e.:
<input type="text" name="totTicket" value="{{adultCount}}" ng-model="adultcount">
should be:
<input type="text" name="totTicket" value="{{adultCount}}" ng-model="adultCount">
<!-- ^ -->
See this demonstrated in the snippet below:
angular.module('app', [])
.controller('ctrl', function($scope) {
//adultCount could be initialized here
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<button data-ng-click="adultCount = adultCount+1"> + </button>
totTicket:
<input type="text" name="totTicket" value="{{adultCount}}">
totTicket (adultCount):
<input type="text" name="totTicket" value="{{adultCount}}" ng-model="adultCount">
</div>
——
1https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types

Angular js remove leading & trailing spaces from the input textbox

See this Plunkr : http://plnkr.co/edit/YAQooPn0UERDI5UEoQ23?p=preview
Type text as "_______what___ever_____"
(without quotes & _ represents spaces.)
Angular is removing spaces (from front & back & not in between) from the model (which is my desired behavior), but my textbox is keeping the spaces.
how can I remove the spaces from the textbox also ? i.e. I want the textbox also to reflect the value in model.
Edit: Better explanation of my needs.
For Eg:
If I typed "___What_Ever____" ( without quote & _ is space),
1) my textbox will show me same what i have typed i.e. "___What_Ever____"
2) while my model will show me "What Ever".
I want my textbox's value also to be as "What Ever".
HTML :
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="style.css" />
<script data-require="jquery#1.9.0" data-semver="1.9.0" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.js"></script>
<script data-require="angular.js#1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MyCtrl">
<input type="text" ng-model="modelVal">
<br>
model value is "{{modelVal}}"
</body>
</html>
JS :
angular.module('app', [])
.controller('MyCtrl', function($scope) {
$scope.modelVal="";
})
Would this work? - Plunker
ng-blur doesn't work with your Plunker because the version of AngularJS you are loading (1.0.7) is quite old. I replaced it with the latest version (1.5.6). I also use ng-trim="false" to get the correct text input by the user.
Markup
<body ng-controller="MyCtrl">
<input type="text" ng-model="modelVal" ng-change="change()" ng-blur="blur()" ng-trim="false">
<br>
model value is "{{newModelVal}}"
</body>
JS
angular.module('app', [])
.controller('MyCtrl', function($scope) {
$scope.modelVal="";
$scope.change = function () {
$scope.newModelVal = $scope.modelVal;
}
$scope.blur = function () {
$scope.modelVal = $scope.newModelVal.trim();
}
})
You can do this,
<body ng-controller="MyCtrl">
<input type="text" ng-change="modelVal = modelVal.split(' ').join('')" ng-model="modelVal">
<br>
model value is "{{modelVal}}"
</body>
DEMO
EDIT:
You can use ngTrim which is provided by Angular itself
<input type="text" ng-trim="true" ng-model="modelVal">
<br> model value is "{{modelVal}}"
DEMO

AngularJS: Target a form with Controller As syntax in an object

Note: I did look around here on SO for solutions, yet no one had the additional issue of the function being in an object.
I have a form in my Angular JS app:
<div ng-app="plunker">
<div ng-controller="PMTController as pmt">
<form name="myForm">
<div class="form-group">
<input type="text" class="form-control" />
</div>
<button class="btn btn-primary" ng-click="pmt.search.resetSearchForm()">Reset</button>
</form>
</div>
</div>
Further, I have a controller with an object:
app.controller('PMTController', function($log) {
var _this = this;
_this.search = {
resetSearchForm: function () {
$log.debug('test');
// how to target the form?
}
};
})
My ng-click works, as the log.debug works. But no amount of tweaking to target the form so that I can reset the entire thing (empty all the fields) works.
I can do $window.myForm.reset(); but how could I do this from angular?
Note please my main issue/question is how to correctly target the form from inside that resetSearchForm function in the search object.
Note I tried changing the form name to pmt.myForm or pmt.search.myForm to no avail.
I tried $setPristine and $setUntouched() but they don't seem to clear the fields.
I know I can assign a model and assign it to all the form controls, but this is for a prototype so I'd rather do a simple reset.
I made a pen: https://codepen.io/smlombardi/pen/YWOPPq?editors=1011#0
Here is my take on your codepen that will hopefully resolve the issue:
https://codepen.io/watsoncn/pen/YWOXqZ?editors=1011
Explanation:
Angular's documentation provides an example of a "Form Reset" button, but you can apply the same logic towards resetting after submission:
Documentation:https://docs.angularjs.org/guide/forms
with a plunker:
Live Example:https://plnkr.co/edit/?p=preview
The example shows the use of Angular's copy method that creates a deep copy of whatever you pass it as a parameter and assigns it to the ng-model that is put on a particular input field. In this case they simply pass it an empty master object.
You need to make sure to add an ng-model attribute to your inputs, then create a reset function that can run after submission. Another common option would be to simply set each input's ng-model to empty strings in the submission function, such as $scope.inputModel = ""
Is this what you were hoping for? I might have misunderstood the question. I will happily take another crack at it if there is still confusion.
To get the form in your controller you just need to name your form this way:
<form name="pmt.myForm">
Here's a complete demo:
(function() {
"use strict";
angular
.module('plunker', [])
.controller('PMTController', PMTController);
PMTController.$inject = ['$log'];
function PMTController($log) {
var _this = this;
_this.model = {};
_this.search = {
resetSearchForm: function() {
console.log(_this.myForm); // -> Form reference
_this.model = {};
}
};
}
})();
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body ng-controller="PMTController as pmt">
<div class="col-md-12">
<form name="pmt.myForm">
<div class="form-group">
<input type="text" ng-model="pmt.model.example" class="form-control" />
<input type="text" ng-model="pmt.model.example2" class="form-control" />
<input type="text" ng-model="pmt.model.example3" class="form-control" />
</div>
<button class="btn btn-primary" ng-click="pmt.search.resetSearchForm()">Reset</button>
</form>
<hr> All fields:
<pre ng-bind="pmt.model | json"></pre>
</div>
</body>
</html>

Submit updated ng-model via JavaScript

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.com/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?
This 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.com/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.com/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>

Categories