Bind value of an input in controller- AngularJS - javascript

I am working with JSP and Angular JS. I have a JSP page with a hidden input field. a session attribute is set to its value as follows.
String policy = (String)session.getAttribute("POLICY_CHANGE");
<input type="hidden" value="<%=policy%>" name="policy" ng-model="$scope.policyChange" />
How can i bind the value of the input field to a variable $scope.policy in my controller.
JS
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.policyChange= ; // i want to bind the input field value here.
});

You can do this setting ng-model directive for your input:
<input type="hidden" value="<%=policy%>" name="ng2_session" ng-modal="vm.policyChange" ng-model="policy" ng-init="policy='<%=policy%>'" />
In the controller you have to use watch method.
$watch helps to listen for $scope changes
JS
app.controller('myCtrl', function($scope) {
console.log($scope.policy); // i want to bind the input field value here.
});
Simple example:
function MyCtrl($scope) {
$scope.$watch('policy', function() {
console.log($scope.policy);
});
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<h2>Todo</h2>
<div ng-controller="MyCtrl">
<input type="text" ng-model="policy" ng-init="policy='Bob'"/>
</div>
</div>
Note: Usually, watch method it is very helpful when you want to run some code when the $scope.variable it is changed.

Related

AngularJS : ng-model doesn't update correctly with ng-keydown. ng-model off by one character

I am looking at text input on AngularJS as it changes by the user.
However, it seems that when I print to the console from my .js, the ng-model is off by one character because there seems to be a lag with the update by one keydown.
For example:
If the user types "hello" I see "hell" until another keydown is triggered, which will then update what I see to "hello" but the user input could be "helloW"
If that makes sense... Sorry.
Basically, is there a way that I can force update my ng-model from my controller so that I can see the user input as it comes in with each keydown?
I cannot post my code, sorry.
Use ng-change with ng-model
var myApp = angular.module('app',[]);
myApp.controller('Main', function ($scope) {
$scope.print = function(){
console.log($scope.myname);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="Main">
<input type="text" name="inputbox" ng-change="print()" ng-model="myname">
</body>
try using "ng-keyup" with "ng-model" instead of ng-keydown :)
Here the doc:
https://docs.angularjs.org/api/ng/directive/ngKeyup
var app = angular.module('app',[]);
app.controller('MyController', function ($scope) {
$scope.onKeyUpPrint = function(){
// You can name the function as you want
// scope will be triggered exactly on key Up
console.log($scope.inputModel);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="MyController">
<h1>Use ng-keyup<h1>
<input type="text" name="inputbox" ng-keyup="onKeyUpPrint()" ng-model="inputModel">
</body>

Undefined value from text area in AngularJS

I am creating one form using Bootstrap & AngularJS. I am using CK editor in my page as textarea. But I am not able to retrieve the value of the textarea while the value of the input text field is easily captured in my AngularJS controller. Following is the code snippet:
HTML page:
<div class="container">
<div ng-controller="controller">
<form role="form">
<label for="sd"><b>Short Description: </b></label>
<input ng-model="sdesc" class = "form-control input-xxlarge" type = "text" placeholder ="Provide a short description here."/>
<br/>
<label for="dt"><b>Details: </b></label>
<textarea ng-model="details" class="form-control" name="details_editor" id="details_editor"></textarea>
<br/>
<button class = "btn btn-primary" ng-click="submitted()">Ask It!</button>
<script>
CKEDITOR.replace('details_editor');
</script>
</form>
</div>
<br/>
<hr>
</div>
JS
app.controller('controller', ['$scope', function($scope){
$scope.submitted = function(){
var sdesc = $scope.sdesc;
var details = $scope.details;
alert($scope.details);
};
}]);
The alert shows undefined for the text area value.
Please help me solve the issue.
You are using the plain Javascript version of CK editor and hence Angular is not getting notified to update the ng-model value of that textarea.
Basically, Angular runs a digest cycle to update all views and models but since in this case the values being changed in the CK editor is happening outside the Angular.s context which is not updating the ng-model value.
To fix this, we added a small directive and notifying the change in the ng-model to the Angular by using the $timeout. (We can also use the $apply directive, but it may fail sometimes if the digest cycle is already in progress)
Example directive:
var app = angular.module("your-app-name", []);
app.directive("ckEditor", ["$timeout", function($timeout) {
return {
require: '?ngModel',
link: function ($scope, element, attr, ngModelCtrl) {
var editor = CKEDITOR.replace(element[0]);
console.log(element[0], editor);
editor.on("change", function() {
$timeout(function() {
ngModelCtrl.$setViewValue(editor.getData());
});
});
ngModelCtrl.$render = function (value) {
editor.setData(ngModelCtrl.$modelValue);
};
}
};
}]);
Remove, your following code:
<script>
CKEDITOR.replace('details_editor');
</script>
And, modify your text-editor like:
<textarea ng-model="details" class="form-control" ck-editor name="details_editor" id="details_editor"></textarea>
I found ng-ckeditor to implement ckeditor in angularjs.
Please refer this :https://github.com/esvit/ng-ckeditor. I tried it, It is easy to implement and working as expected

Angularjs - assigning logic between two models

I am new to Angular. It is a very simple question -
in my index.html I am defining two models on two text boxes :-
<html><head><script...></head><body ng-app="myApp"ng-controller="MainController" >
<input ng-model="tb1" type="text" name="numberofusers"/>
<input ng-model="tb2" type="text"></input>
</body></html>
And in my app.js I am defining like this
var app = angular.module('myApp', []);
app.controller('MainController', ['$scope', function($scope){
$scope.tb1 = $scope.tb2;
}]);
Now, what I want is that whatever I type in first text box (tb1) automatically typed to second text box (tb2) and vise-versa, but that is not happening.
Any guess ?
Your code in controller $scope.tb1 = $scope.tb2; would only be executed once (when controller initializes), that's why it doesn't work.
You need to bind input elements to the same model then Angular will handle two-way binding for you automatically.
<input ng-model="tb1" type="text" name="numberofusers"/>
<input ng-model="tb1" type="text"></input>
Or if you want to use two different models for different elements, you can add a hook to input's ng-change event listener like
<input ng-model="tb1" type="text" name="numberofusers" ng-change="tb2 = tb1"/>
<input ng-model="tb2" type="text" ng-change="tb1 = tb2"></input>
Then these two elements would sync automatically. But you know what, ng-change can only monitor user input change, that means, if you change tb1 or tb2 programmably, ng-change will not be triggered.
In this case, you should monitor model's change using $scope.$watch
$scope.$watch('tb1', function(newValue) {
$scope.tb2 = newValue;
}));
Currently it's beyond your requirement.
This is because controller will only execute once and if there is any value in $scope.tb2 will assign to $scope.tb1 but intially both of them are blank .
So you need to $watch the changes and assign value to each other like :-
$scope.$watch('tb1',function(newVal){
$scope.tb2=newVal;
})
$scope.$watch('tb2',function(newVal){
$scope.tb1=newVal;
})
And if you want to manage it on front end you can use ng-change directive like
<input ng-model="tb1" type="text" ng-change="tb2=tb1" name="numberofusers"/>
<input ng-model="tb2" type="text" ng-change="tb1=tb2"></input>
You can use two-way binding to achieve that. An example is: JSFiddle
Create your directive:
var app = angular.module('myApp', []);
app.controller("myCtrl", function($scope) {
$scope.myName = 'Carl';
}).directive("myDirective", function() {
return {
restrict: 'AE',
scope: {
twowayBindingProp: '=myName'
}
}
});
And bind it through:
<div ng-app="myApp">
<div ng-controller="myCtrl">
<h1>From parent: </h1>
<h3>parentProp2: <input ng-model="myName"></h3>
<div my-directive my-name="myName">
<h1>From child: </h1>
<h3>twowayBindingProp: {{ twowayBindingProp }}</h3>
<h1>Set from child:</h1>
twowayBindingProp: <input ng-model="twowayBindingProp">
</div>
</div>
</div>

How can I unbind(remove) angular models when not in DOM

Here is a simple demonstration of what I'm struggling to achieve.
<div ng-controller="MyCtrl">
<input type="button" ng-click="a=!a" value="toggle a"/>
<div ng-if="a">
<input type="text" ng-model="del.a1" />{{del}}
</div>
<input type="text" ng-model="del.a2" />
{{del}}
</div>
Initially the value of del is {} and ng-if is false the property a1 is under ng-if condition.
Test Case :
step 1 : toggle the ng-if to true so that a1 is visible
step 2 : enter some value into a1 (you can anytime enter value in property a2)
step 3 : now if i again toggle ng-if to false what I'm looking for is the property a1 is to be removed from model.(i.e i just want angular to bind those models which are visible on DOM) like this
Here is the FIDDLE for the above test case.
I guess the problem is with model used as object. but I need a solution in model as object only as I have done lot of coding based on this.
Hope I'm clear with the question.
pls Help
You can watch a value using $scope.$watch and delete a1 key from del object when a is set to false
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
$scope.del = {};
$scope.a = false;
$scope.$watch('a', function(value) {
if (!value) {
delete $scope.del['a1'];
}
});
})
Please see working demo below
var myApp = angular.module('app', []);
myApp.controller('MyCtrl', function($scope) {
$scope.del = {};
$scope.a = false;
$scope.$watch('a', function(value) {
if (!value) {
delete $scope.del['a1'];
}
});
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MyCtrl">
<input type="button" ng-click="a=!a" value="toggle a" />
<div ng-if="a">
<input type="text" ng-model="del.a1" placeholder="a1" />{{del}}</div>
<input type="text" ng-model="del.a2 " placeholder="a2" />{{del}}
</div>
In your example only the models visible in the DOM are watched.
If you mean you want the model value removed from the object then you would need to have a watch on 'a' that knows what values to remove from the model.

Angular.js : How to bind "change" event to service

First of all, I'm new to angular.js...
I have a HTML5 page where I can add new URLs with a name. Now, I want to have a check to a back-end service to check if the URL already exist. How can I bind the “onChange” event on the input boxes to a service function?
I have tried to find the solution, but I have not been able to find anything that describes this easily.
<div ng-controller="newLink">
<input class="url" value="{{Url}}" ng-model="Url" placeholder="Please type a URL"/>
<input class="name" value="{{Name}}" ng-model="Name" placeholder="Type a name" />
<div class="status"></div>
</div>
<script>
app.controller('newLink', ['$scope', 'appService', function ($scope, appService) {
$scope.Name = '';
$scope.Url = '';
}]);
</script>
You can use the ngChange directive
<input ng-change="onChange()">
// in controller
$scope.onChange = function(){
// call your service function here
}
For further information, see: http://docs.angularjs.org/api/ng/directive/ngChange
Two simple solutions to this problem:
use ng-change directive:
<input ng-change="doSomething()">
$scope.doSomething = function() {};
$watch value change
<input ng-model="Url">
$scope.$watch('Url', function() {});

Categories