Save state of ng-change local scope in Datepicker - javascript

I have come across what seems like a very simple issue, but I cannot figure out how to fix it. I posted this question originally, but it seems the issue is with the scope.
So basically, this is what is happening:
I have a datepicker inside a form. When the user selects a date, ng-change will trigger and it calls the function setDate(date).
In debug mode, I confirmed that the selected data indeed is passed to the function.
Inside the function, $scope.simStartDate variable is assigned this value and I can see its value changing.
However, when I later go to submit the form, $scope.simStartDate is back with its original initialized value.
I have put a breakpoint at the initialization $scope.simStartDate = new Date(), but it does not hit. Meaning that the variable is not initialized again.
I have tried using a $scope variable in the ng-model, but still the same issue.
This makes me think that ng-change creates a local scope and updates a local variable, which I cannot access later. Is my understanding correct? If not how can I fix this?
This is my HTML:
<div class="row" ng-controller="DashboardParamsFormCtrl">
<div class="col-sm-6">
<div class="form-group">
<label for="inputFirstName">Simulation start date</label>
<p class="input-group">
<input type="text" class="form-control"
uib-datepicker-popup="{{format}}"
datepicker-options="options"
ng-model="date"
ng-change="setDate(date)"
is-open="opened" ng-required="true"
close-text="Close"
alt-input-formats="altInputFormats"
show-button-bar="true" />
<span class="input-group-btn">
<button type="button" class="btn btn-default"
ng-click="open()">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
</div>
</div>
This is the JS:
angular.module('BlurAdmin.pages.dashboard')
.controller('DashboardParamsFormCtrl', DashboardParamsFormCtrl);
/** #ngInject */
function DashboardParamsFormCtrl(baConfig, layoutPaths, baUtil, $scope)
{
$scope.ParamsFormBtnClicked = function()
{
console.log("Date: " + $scope.simStartDate);
}
$scope.open = open;
$scope.opened = false;
$scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
$scope.format = $scope.formats[0];
$scope.options = {
showWeeks: false
};
function open() {
$scope.opened = true;
}
$scope.simStartDate = new Date();
$scope.date = new Date();
$scope.setDate = function(startDate)
{
$scope.simStartDate = startDate;
}
}
})();
Thank you.

your passing new date(); without value, it will get current date. you should pass ng-model value inside new date();
like this.
$scope.simStartDate = new Date(date);
$scope.date = new Date(date);
hope this link will help you too plnkr

Related

Datepicker value into string in Angularjs

I'm trying to get datepicker value into a string or usable format for passing as a parameter to a get method. However,
the get method i tried always give an error, what is the best way to convert a datepicker value into a string?
<div ng-app="getserviceApp" ng-controller="getserviceCtrl">
<button ng-click="FunctionLoadData()">Load Data</button>
<input type="date" ng-model="from_date" />
<input type="date" ng-model="to_date" />
<script type="text/javascript">
var app = angular.module('getserviceApp', [])
app.controller('getserviceCtrl', function ($scope, $http) {
var FromDate = new Date($scope.from_date.selectedDate);
var ToDate = new Date($scope.from_date.selectedDate);
There are some discrepancies in the ng-models and the name of your $scope variables.
In your controller you should have something like
app.controller('getserviceCtrl', function ($scope, $http) {
$scope.from_date = new Date();
$scope.to_date = new Date();
$scope.loadData = function(){
console.log($scope.from_date.toISOString().split('T')[0])
console.log($scope.to_date.toISOString().split('T')[0])
//prints the dates in yyyy-MM-dd format
}
}
And in your HTML
<div ng-app="getserviceApp" ng-controller="getserviceCtrl">
<button ng-click="loadData()">Load Data</button>
<input type="date" ng-model="from_date" />
value = {{from_date | date: "yyyy-MM-dd"}}//Display the date
<input type="date" ng-model="to_date" />
value = {{from_date | date: "yyyy-MM-dd"}}
</div>
I think mistake is from_date.selectedDate. Use just model from_date
Here is working stackblitz.

Updating date in controller not reflected in input type=date

In AngularJS, I have on the DOM side:
<input class="form-control" type="date" ng-model="scope.status.date"
ng-change="scope.reloadDay()" ng-model-options="{debounce:200}">
In the back I have a function:
scope.changeDate = function() {
var current_date = scope.status.date;
current_date.setDate(current_date.getDate() - 1);
scope.status['date'] = current_date;
}
This results that indeed scope.status.date is updated, but in the input box it stays the same.
What is happening here?
Construct a new Date:
$scope.changeDate = function() {
var current_date = $scope.status.date;
current_date.setDate(current_date.getDate() - 1);
$scope.status.date = new Date(current_date);
};
This will trigger the $render() function of the ngModelController.
The DEMO
angular.module("app",[])
.controller("ctrl", function($scope) {
$scope.status = {date: new Date()};
$scope.changeDate = function() {
var current_date = $scope.status.date;
current_date.setDate(current_date.getDate() - 1);
$scope.status.date = new Date(current_date);
};
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
<input class="form-control" type="date" ng-model="status.date"
ng-model-options="{debounce:200}">
<br>
<button ng-click="changeDate()">Change Date</button>
</body>
Would have never thought of this that this triggers the render(). May I ask how you found this in the documentations? What did you look for?
From the Docs:
$render();
Since ng-model does not do a deep watch, $render() is only invoked if the values of $modelValue and $viewValue are actually different from their previous values. If $modelValue or $viewValue are objects (rather than a string or number) then $render() will not be invoked if you only change a property on the objects.
— AngularJS ngModelController API Reference - $render
For more information, see
How does data binding work in AngularJS?
AngularJS Developer Guide - Scope $watch Depths
Please check a date format, date format should be "yyyy-mm-dd"

Datepicker ui-bootstrap setting value from model

I'm using the ui-bootstrap datepicker for my angular form. When I get the json from the database and set the value on the form the Date shows on the input but I can't submit because the input does not recognise the value from the scope, and I have to pick again the dates. I'll explain better:
This is my datepicker options in the controller that I copied from the documentation:
$scope.today = function() {
$scope.dt = new Date();
};
$scope.today();
$scope.clear = function() {
$scope.dt = null;
};
$scope.open = function( $event ) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
$scope.open2 = function( $event ) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened2 = true;
};
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
$scope.formats = [ 'dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate' ];
$scope.format = $scope.formats[ 0 ];
My edit input is like this:
<div class="input-group"><input name="StartDate" type="text" class="form-control" popup-placement="top-left" datepicker-popup="{{format}}" is-open="opened" close-text="Close" ng-model="period.StartDate" id="StartDate" required />
<span class="input-group-btn">
<button type="button" class="btn btn-default calendar-input" ng-click="open($event)"><i class="fa fa-calendar"></i></button>
</span></div>
For debug purpose I showed the $scope.period.StarDate and at the beginning the date shows without quotes, but if choose again on the picker it shows with quotes.
What I tried was to filter the data before show it on the view like this:
$scope.period.StartDate = $filter('date')($scope.period.StartDate, 'dd-MMMM-yyyy');
The date is show it fine on the input and does let me submit it, but it saves only 0000-00-00 on the database. How do I filter the date from the json for the datepicker can recognize the data?
UPDATE
The data Type on the database is "date" only, and when I do the query the json brings the date like this: 2017-07-30T00:00:00.000Z
Even if I don't put required on the datepicker, it expect a date before doing the submit.

How can angular ui-bootstrap datepicker settings be declared in one place?

I'm using angular-ui datepicker and currently have the settings declared in a controller, eg:
$scope.date = new Date();
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
In order to be DRY, I want to declare this in one place, so that the datepicker can be used anywhere, without having to declare the settings each time.
I've tried putting them into a factory that would be injected into a controller, but with no success. I'm quite new to building factories/services.
I found this SO question that mentions declaring the settings under the config method, like this:
.config(['datepickerConfig', function(datepickerConfig) {
datepickerConfig.showWeeks = false;
}]);
But this doesn't work for me for some reason.
How can I declare the datepicker settings in once place to be used globally, or for injection?
To declare datepicker in 'one place' for easy re-use, I built a factory for the data/config:
.factory('datepickerService', function() {
var factory = {};
factory.date = new Date();
factory.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
this.opened = true;
};
return factory;
});
Then a datepicker controller that injects the datepickerService, hooking the $scope up with the factory config.
.controller('datepickerCtrl', function ($scope, datepickerService) {
$scope.date = datepickerService.date;
$scope.open = datepickerService.open;
});
A directive:
.directive('supermanDatepicker', function () {
return {
templateUrl:'views/partials/datepicker.html'
};
});
HTML partial template with the standard ui-boostrap datepicker (but declaring the controller)
<div class="input-group" ng-controller="datepickerCtrl">
<input type="text"
class="form-control"
datepicker-popup="{{format}}"
ng-model="shortDate"
placeholder="dd-mm-yyyy"
is-open="opened"
min-date="minDate"
datepicker-options="dateOptions"
date-disabled="disabled(date, mode)"
ng-required="true"
close-text="Close" />
<span class="input-group-btn">
<button type="button"
class="btn"
ng-click="open($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</div>
Then finally, it can be plugged into any view:
<div superman-datepicker></div>

Setting options to datepicker in angular-ui bootstrap

I'm trying to use datepicker component from angular-ui bootstrap lib as descibed here: http://angular-ui.github.io/bootstrap/
And I try to set options for the popup picker and accoriding to the documentation I should pass options for datepicker as JSON using the datepicker-options attribute.
In my view I have:
<div class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
And in my controller I have:
$scope.dateOptions = {'show-button-bar': 'false', 'close-text':'SomeText'};
$scope.today = function() {
$scope.dt = new Date();
};
$scope.today();
$scope.showWeeks = false;
$scope.clear = function () {
$scope.dt = null;
};
$scope.toggleMin = function() {
$scope.minDate = ( $scope.minDate ) ? null : new Date();
};
$scope.toggleMin();
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
$scope.format = 'dd/MM/yyyy'
As you can see at the beginning I try to set the options:
$scope.dateOptions = {'show-button-bar': 'false', 'close-text':'SomeText'};
however, it doesn't seem to work, the datepicker does not change.
Any ideas what I'm doing wrong?
I found the solution to this, I put the options as attributes, e.g.:
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt" is-open="opened" min="minDate" max="'2014-12-31'" datepickerOptions="dateOptions" ng-required="true" show-button-bar="false"/>
so I put show-button-bar as the attribute and not as a part of object passed to datepickerOptions.
You are using dash-cased option names. These dash-cased names are only required when using them as single attributes on an element. i.e.
<input type="text" datepicker-popup="{{format}}" starting-day="1" ng-model="dt" >
However datepicker-options expects named options in json with camelCased format as following:
datepicker-options="{startingDay: 1, yearFormat: 'yy'}"
<input type="text" datepicker-popup="{{format}}"
datepicker-options="{startingDay: 1, yearFormat: 'yy'}" ng-model="dt" >
or
$scope.options = {
'startingDay': 1,
'yearFormat': 'yy'
}
<input type="text" datepicker-popup="{{format}}"
datepicker-options="{{options}}" ng-
The attribute starting-day="1" should also work on the datepicker input, as told at https://angular-ui.github.io/bootstrap/#/datepicker, but I can't seem to get that working (using version 0.12.1)
I know this an old question but thought I'd point out where you were probably having trouble.
In your controller you are assigning to $scope.dateOptions twice and therefore overwriting your first assignment.
So your initial assignment of:
$scope.dateOptions = {'show-button-bar': 'false', 'close-text':'SomeText'};
Is overwritten when you do this towards the end:
$scope.dateOptions = {
'year-format': "'yy'",
'starting-day': 1
};
According to datePicker documentation, popup setting can be globally configured through the datepickerPopupConfig, so you have to add it into you controller.
yourApp.controller('YourController', function ($scope, datepickerPopupConfig) {
datepickerPopupConfig.showButtonBar = true;
datepickerPopupConfig.closeText = 'I am done';
datepickerPopupConfig.clearText = 'Wipe it out';
}
Setting closeText doesn't work for some reason. I don't know why.
Example on Plunker for playing.
datepicker-options was introduced in version 0.11 so make sure you are using angular-ui-bootstrap version 0.11 or higher
Looks like your dateOptions object keys are not camelCased. Try this:
$scope.dateOptions = {
'showButtonBar': 'false',
'closeText':'SomeText'
};
Html attributes should be dash-cased, like show-button-bar, or close-text, etc.
Notice the difference between the datepicker-options html attribute and the datepickerOptions javascript object.
Just provide close-text, current-text and clear-text attributes in the input :)
<input type="text" uib-datepicker-popup ng-model="dt" is-open="popup2.isopen" datepicker-options="dateOptions" ng-required="true" close-text="your close text here" current-text="Your current text here (today for example)" clear-text="Your clear-text here"/>
The site is pretty lite on examples. For me, with version 1.1.1, I passed in the config object as an attrib:
datepicker-options="datepickerOptions"
And in the controller, was able to set some options:
$scope.datepickerOptions = {
formatYear: 'yy',
startingDay: 0,
showWeeks: false
};
But 'showButtonBar' doesn't cooperate, so looking through the code I saw 'uibDatepickerPopupConfig'. I pass that in and and set it separately and it works:
.controller('DatepickerCtrl', function ($scope, uibDatepickerPopupConfig){
uibDatepickerPopupConfig.showButtonBar = false;
With 'datepickerPopupConfig' I get the provider error:
Unknown provider: datepickerPopupConfigProvider <- datepickerPopupConfig

Categories

Resources