Angular-strap datepicker doesn't update existing model value - angularjs

I am using angular-strap datepicker from http://mgcrea.github.io/angular-strap/##datepickers for my angularjs SPA project. when editing an existing record using ngModel two way binding, Angular doesn't detect the date field change and even if I force the form to save by updating another non date field, the new date is not updated in backend. Here is the related part in my html file:
<input name="DecisionDatePicker" id="ddpID" type="text" class="form-control input-medium" tabindex="14" placeholder="{{vm.format}}"
data-date-format="MM-dd-yyyy"
data-ng-model="vm.formData.dateDecision"
data-ng-required="vm.decisionDateRequired"
bs-datepicker />
I do not do anything special in my js file. I am using breezejs for my data handling and it is working fine for other fields.
what am I doing wrong? Any help is appreciated.

I've had this same problem and I solved with a custom directive that updates the model when the bs-datepicker dispatches a blur event:
angular.module('moduleName').directive('updateModelOnBlur',
['$parse', function($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elm, attrs) {
elm.bind("blur", function (event) {
scope.$apply(function () {
var model = $parse(attrs.ngModel);
model.assign( scope, elm.context.value );
});
});
}
};
}]
);
I know this is just a hack, and not a final solution for the problem. But, if you are stuck and want to keep going, sometimes a hack might be useful.
You can also include $filter service in the directive if you want to manipulate date format before updating model. ;)

Related

Angular Pikaday multiple date format

I am using Pikaday date picker plugin in my angular JS app.
Is it possible to have different format for view and different format while submitting?
For ex: 01 Jan 2014 (Display)
01/01/2014 (while submitting the form)
I know i can apply a filter while posting the content. However, since the date picker is been used in many places i have to do it at all the places separately. It will be great if the plugin updates my ng-model with a certain format but displays it differently.
You can get this by using angularjs directive (formatters and parsers).
For example using moment.js:
app.directive('fdate', function () {
return {
require: 'ngModel',
link: function(elem, $scope, attrs, ngModel){
ngModel.$formatters.push(function(val)
{
return moment(val).format("DD/MM/YYYY");
});
ngModel.$parsers.push(function(val){
return moment(val, "DD/MM/YYYY").valueOf();
});
}
}
});
and in your html:
<input type="text" ng-model="obj.yourdate" fdate>
i found this fiddle as an example:
http://jsfiddle.net/arunpjohny/wNBAn/

In angularJS, why is my model not updating when linking the input to a datepicker?

I'm a little lost here. I defined an angular directive that creates a datepicker (the bootstrap datepicker by eternicode(https://github.com/eternicode/bootstrap-datepicker/)):
The datepicker appears to work visually. It pops up, and puts a value in my textbox. But the angular model is not updated unless I edit the textbox by hand.
My directive:
myApp.directive('ccDatePicker', function ($compile) {
return {
restrict: 'EA',
template: '<input type="text" ng-model="ngModel" />',
require: '^ngModel',
scope: {
ngModel: '='
},
replace: false ,
link: function (scope, element, attrs) {
element.children(0)
.on('change', function () { scope.$digest(); })
.datepicker({ format: 'yyyy/mm/dd', autoclose: true });
}
};
});
My HTML:
<label>Due date: <cc-date-picker ng-model="todoObject.dueBy" /></label>
<div>
dueBy: {{todoObject.dueBy}} (updates when editing textbox by hand, but not when using date picker)
</div>
I used scope.$digest to refresh the model, and I also tried scope.$apply. No luck.
How do I get my angular model to update when the user chooses a date in the date picker?
I had a similar problem when trying to make a datepicker directive based on a jQuery plugin, because the datepikcer's onSelect() event happens outside the angular world and no notifications are raised, you need to call a $scope.$apply() force a digest to let angular know that it should update the model value:
onSelect: function (date) {
scope.$apply(function () {
ngModelCtrl.$setViewValue(date);
});
}
Also in the snippet you posted, I don't see where you're setting the models value, hence this line:
ngModelCtrl.$setViewValue(date);
EDIT
I made a plunk demonstrating what needs to be done. On an unrelated note, why don't you use the angular-ui datepicker?
if you set the dueBy date first (eg.
$scope.todoObject={dueBy:"04/27/2015"};
how to make the dropdown show the initial value when it's first displayed?
http://plnkr.co/edit/xOzfQOOMe1GFoB1tfQiF?p=preview

use third party lib in angular directive

i want create an angular directive for persian datepicker, javascript lib that i want to use is http://jspersiandatepicker.codeplex.com/, and my code is :
<input type="text" persiandatepicker ng-model="mydate" />{{mydate}}
directive('persiandatepicker', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
if (!ngModel) return;
ngModel.$render = function () {
element.bind("click", function () {
PersianDatePicker.Show(this, ngModel.$viewValue || '');
});
};
}
};
});
this code show datepicker when click on input and when select date show in input, but model not bind and not change how can i do binding in this sample??
this link in plunker is my code : http://plnkr.co/edit/AQsvlbdGHCVpjMeCbR3c?p=preview
You need to let angular know that the value has changed. It looks like the datepicker calls _textBox.onchange(); when it is finished updating the textbox so you can hook into that event. You will need to wrap your code in
element.bind("onchange", function () {
scope.$apply(function() {
//Code to update model goes here.
//Basically you will need to copy the textbox's contents to the model,
// you may wish to convert to a date object as well
}
}
The angularui datepicker source code is only 120 lines long and could be a great resource if you are looking for an example on creating a datepicker directive.
Currently there is a good one Available. it's a Persian angularjs calendar:
Amin Rahimi's angularjs Datepicker .
Also you can use this version of angular-ui bootstrap that has persian calendar: persian angular bootstrap

AngularJS datepicker ui-date bad updates

The two-way data-binding appears to be causing bad updates to the field. Clicking on the field raises the datepicker fine, but if you attempt to edit the field by directly typing in a date, it doesn't quite work.
Here's the fiddle demonstrating the issue: http://jsfiddle.net/vSNJF/
<input type="text" ng-model="name" ui-date-format='m/d/yy' ui-date>
Compare the keyboard-editing under Angular to the standard jquery UI date picker behavior here: http://jqueryui.com/datepicker/
How can I make ui-date delay updating the model until after the interactive calendar is dismissed?
You've got quite a big directive there, I am not sure if anyone is going to go through the whole code to find what is causing the problem. To help I will leave a simpler datepicker directive that behaves exactly like Jquery UI's but without all the features you have implemented in yours, maybe if your start from this point and go adding features it would be easier to debug the problem.
The directive is:
directive('datepicker', function() {
return {
restrict: 'A',
require : 'ngModel',
link : function (scope, element, attrs, ngModelCtrl) {
$(function(){
element.datepicker({
dateFormat:'dd/mm/yy',
onSelect:function (date) {
ngModelCtrl.$setViewValue(date);
scope.$apply();
}
});
});
}
}
});
Here is a Plunker and a blog post about it.

Angular (directive newbie): How to add date time-picker to ngModel so that it can be validated?

I am very new to Angular and have a specific use case in mind
I have a form which has two fields - Name and datetime.
The name is ng-model but datetime is not since it is not part of Angular and is a jquery component
What I want to do?
Here is the plunker = http://plnkr.co/edit/wGrvXAFmPGoYSwh9GfxH?p=preview
a.) I want to associate date to ngModel like ngModel="transaction.date"
b.) validate it as required using Angular way
Something which will look like (much like Angular)
<input type="text" name="transactionDate" ng-model="transaction.date" data-date-format="yyyy-mm-dd hh:ii" required>
Why?
a.) To to things Angular way
b.) It makes model more consistent to test, validate
I asked this question on Stackoverflow and it was recommended to use custom directive, can someone give me direction with example how to do it?
Please guide me further since I am not able to validate it currently
Thank you very much
Based on Ketan's answer, I had to write a new directive and associate the value form jQuery to ng-model, which then is validated with form. The directive looks like
app.directive('dateTime', function(){
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel){
if (!ngModel) {
console.log('no model, returning');
return;
}
element.bind('blur keyup change', function() {
console.log('datetime changed: ', $('.form_datetime input').val());
scope.$apply(read);
});
read();
function read() {
ngModel.$setViewValue(element.val());
}
}
}
});
The plunker can be found here
Assuming you know how to write directives, you need to use the NgModelController inside your directive and use the $setViewValue(value) method. (See example the below page).
http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController
This has to be called from your custom Datepicker event which triggers when the user completes the selection.

Resources