$scope.$watch getting undefined new and old value angularjs - javascript

<input
type="text"
datetime-picker
date-format="dd-MM-yyyy hh:mm a"
future-only
readonly
name="flg_{{user.user_id}}"
ng-model="orderItems[user.user_id].flg_time"
ng-click="saveOrder(user, orderItems[user.user_id])"
>
<input
type="text"
datetime-picker
date-format="dd-MM-yyyy hh:mm a"
future-only
name="dep_{{user.user_id}}"
ng-model="orderItems[user.user_id].dep_time"
ng-click="saveOrder(user, orderItems[user.user_id])"
>
var userInfo = auth.getCurrentUser().children;
angular.forEach(userInfo, function(item, key){
$scope.$watch('[orderItems[item.user_id].flg_time, orderItems[item.user_id].dep_time]', function(newVal, oldVal){
console.log("N", newVal); // undefined
console.log("O", oldVal); // undefined
if (newVal !== oldVal && typeof oldVal !== 'undefined') {
var orderItems = {
'order_id' : $scope.order.order_id,
'flg_time' : newVal[0],
'dep_time' : newVal[1],
}
$scope.saveOrder(item, orderItems);
}
}, true);
});
What i want to set value of new value into the original text box but it always says old and new value is undefined it should return the input value please guide what's wrong in it.
Thanks in advance

instead of $scope.$watch use $scope.$watchcollection,because $watch only uses for 1 element if you go array elements than watchollection is better
Hope it helpsfull.

Related

Daterangepicker change angularjs

I have a date range picker and I need to add a listener everytime i change the range of the values so i sent the startDate and endDate in my url to a restapi and then make a query to my databse with that valeus and get new rows.
My problem is with the listener.. I need something like "onChange" when i set new dates.
View:
<div class="form-group col-md-3 mb0" ng-if="timerange == 'custom'">
<div class="row">
<label class="col-sm-3 control-label pt7">Custom</label>
<div class="col-sm-9">
<input type="text" id="customrange" name="customrange" ng-model="parent.customrange" ng-change="applyOptions()" class="form-control" ui-jq="daterangepicker" ui-options="{format: 'YYYY/MM/DD',startDate: '{{startdate}}',endDate: '{{enddate}}', maxDate:'{{enddate}}'}" />
</div>
</div>
</div>
Controller:
var rangeSelector = document.getElementsByTagName('select')[1]; //1h 24h 1w custom
if(rangeSelector.value == 'custom'){
var datePicker = document.getElementById("customrange").getAttribute('ui-options');
var split = datePicker.split(",");
var startDate = split[1].split(': ')[1].replace(/["']/g, '');
var endDate = split[2].split(': ')[1].replace(/["']/g, '');
if (startDate !== undefined) {
url += '&startDate='+startDate;
}
if (endDate !== undefined) {
url += '&endDate='+endDate;
}
i tried 2 optiuons but i cant get into that code when i put a breakpoint on it..
$scope.$watch("customrange", function() {
console.log("I've changed : ");
});
and
rangeSelector.addEventListener("change", function(e){
if(rangeSelector.value == "custom"){
e.preventDefault();
customrange = document.getElementById("customrange");
customrange.addEventListener("change", function(){
startEndDate = controllerScope.getStartEndTimestamps();
});
}
}, false);
Anyone can help me please??
Image of problem
Updated:
The problem is that your $watch is not checking the correct model.
Your $watch should be called as follows:
$scope.$watch("parent.customrange", function(newValue, oldValue) {
console.log("I've changed : ");
});
To watch the object "parent":
$scope.$watch("parent", function(newValue, oldValue) {
console.log("I've changed : ");
}, true);
The true sets the optional objectEquality check.
Angular $watch Documentation:
When objectEquality == true, inequality of the watchExpression is determined according to the angular.equals function. To save the value of the object for later comparison, the angular.copy function is used. This therefore means that watching complex objects will have adverse memory and performance implications.

store scope value, for it to be compared

I'm doing a ng-blur and sending the current value of a input into a function. My problem is that I want to save the previous input value and pass that into the blur function, because if value is same no action.
<input type="text" class="input__text" name="name" ng-model="name" ng-blur="bluryLines(name)">
$scope.bluryLines = function(oldValue, value) {
if (value !== '' | value !== oldValue) {
console.log('some action');
} else {
console.log('is empty');
}
};
Use ng-change to call your function and use ng-model-options="{ updateOn: 'blur' }"
Docs: https://docs.angularjs.org/api/ng/directive/ngModelOptions
<input type="text" class="input__text" name="name" ng-model="name" ng-change="bluryLines()" ng-model-options="{ updateOn: 'blur' }">
Plunker: https://plnkr.co/edit/BLFj5iRtF3xUxIQEk8UT?p=preview
Keep a copy of the value in a variable at the end of the $scope.bluryLines function. You don't even need to pass any argument to the controller function.
var oldName;
$scope.bluryLines = function() {
if ($scope.name !== '' | $scope.name !== oldName) {
console.log('some action');
} else {
console.log('is empty');
}
// copy $scope.name
oldName = angular.copy($scope.name);
};
See this Plunker.

Using ng-class with mutiple conditions

I want to set 1 of 3 different classes on a span based on the result of a function. My javascript below seems to be returning the correct value, however my markup is always showing the 'require-matched' class.
How can I write an ng-class directive to accommodate this?
HTML:
<span ng-class="{'require-empty': 0,
'require-matched': 1,
'require-not-matched':2 [form.username.$validators.status]}">
</span>
JS:
ctrl.$validators.status = function (value) {
var expression = /^[-\w]+$/;
if (value != null && value != undefined && value != '' && value != ' ') {
if (expression.test(value))
return 1;
if (!expression.test(value))
return 2;
}
else {
return 0;
}
}
This is incorrect usage of validation in Angular. ctrl.$validators.status should return boolean: true for valid result (required-matched in your terminology) and false otherwise (required-not-match). In case of invalid validation ngModelController will receive boolean flag which you can use in view to style control or show error message.
require-empty that you have should be handled by required validator instead of making status validator do this also.
So what you would probably want to have:
ctrl.$validators.status = function(value) {
if (value) {
var expression = /^[-\w]+$/;
return expression.test(value.trim());
}
return false;
}
or directive can be as concise as
ctrl.$validators.status = function(value) {
return value && /^[-\w]+$/.test(value.trim());
}
Corresponding field in HTML will be (providing that the directive name is status):
<input type="text" name="test" ng-model="testModel" status required>
<div class="error" ng-show="testForm.test.$error.required">The field is required.</div>
<div class="error" ng-show="testForm.test.$error.status">The value should match pattern.</div>
Demo: http://plnkr.co/edit/YALB4Vbi5FzNH5FCfwB5?p=preview

Blank or empty number text box instead of zero value

I have number text box as shown below.
<input type="number" ng-model="item.TotalUnitsCompleted" />
TotalUnitsCompleted model is an int field.So could you tell me how to set a blank or empty value instead of 0 on the above text box ? At this moment it shows as 0. Thanks in advance.
Note : I don't like to change the int model to string.
You just need to set item.TotalUnitsCompleted = undefined;
If you are using ngTable, just ng-init on each loop ng-init="item.TotalUnitsCompleted = undefined"
Here is an Example:
<input type="number" ng-model="TotalUnitsCompleted" ng-init="TotalUnitsCompleted = initTotalUnits(TotalUnitsCompleted)"/>
Controller:
app.controller('MainCtrl', function($scope) {
$scope.TotalUnitsCompleted = 5;
$scope.initTotalUnits = function(units) {
return (typeof units !== 'undefined' && units > 0 && units !== null) ? units : undefined;
}
});
Plunker

Knockout.js conditional binding

How do you have conditional binding based on other properties?
Example..
var ViewModel = {
IsAdded = ko.observable(),
AddedBy = ko.observable()
}
When I display it.. I don't want to show AddedBy if IsAddedBy is null or false
Something like this..
&ltinput type="text" data-bind="value: if (IsAdded != null && IsAdded) { AddedBy }"/>
I know that isn't right, but something like that...
What I would do is this;
var ViewModel = function() {
this.IsAdded = ko.observable('True');
this.AddedBy = ko.observable('Test');
this.AddedByText = ko.computed(function(){
if ( this.AddedBy() != null && this.IsAdded() ) return this.AddedBy()
return "";
}, this);
}
Then your input would be
<input type="text" data-bind="value: AddedByText" />
This way you are keeping the logic contained within your ViewModel and separate from the HTML.
This question is old but it might help someone else looking
<input type="text" data-bind="value: IsAdded ? AddedBy : "" "/>
Basically if IsAdded is not null then set the value to AddedBy, else do nothing

Categories

Resources