Reputation: 595
I'm trying to create a multi step form with angular, that contains a datetimepicker, using ui.router and ui.angular.datetimepicker.
i've got the form all working and loading the picker ok, but I'm getting a strange error:
Uncaught TypeError: object is not a functionangular-animate.js:938 (anonymous function)
2angular.js:11607 TypeError: Cannot read property 'then' of undefined
at Object.ngIfWatchAction [as fn] (angular.js:21974)
at Scope.$get.Scope.$digest (angular.js:14243)
at Scope.$get.Scope.$apply (angular.js:14506)
at HTMLSpanElement.<anonymous> (angular.js:21443)
at HTMLSpanElement.eventHandler (angular.js:3014)angular.js:11607 (anonymous function)angular.js:8557 $getangular.js:14261 $get.Scope.$digestangular.js:14506 $get.Scope.$applyangular.js:21443 (anonymous function)angular.js:3014 eventHandler
whenever I select the dates on the form. I'm a noob to angular and trying to work out what this is - I'm adding the angular-animate.js file from Google's hosted libraries so this is ok - can anyone help?
I have the following app:
angular.module('formApp', ['ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.bootstrap.datetimepicker' ])
// configuring our routes
// =============================================================================
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show our basic form (/form)
.state('form', {
url: '',
templateUrl: 'views/home.html',
controller: 'formController'
})
// nested states
// each of these sections will have their own view
// url will be nested (/form/profile)
.state('form.date', {
url: '',
templateUrl: 'views/form-date.html'
})
// url will be /form/interests
.state('form.address', {
url: '/',
templateUrl: 'views/form-interests.html'
})
// url will be /form/payment
.state('form.payment', {
url: '/',
templateUrl: 'views/form-payment.html'
})
// url will be /form/payment
.state('form.appointments', {
url: '/appointments',
});
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/');
})
I have the following home.html:
<div id="form-container">
<div class="page-header text-center">
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".date"><span>1</span> Date</a>
<a ui-sref-active="active" ui-sref=".address"><span>2</span> Address</a>
<a ui-sref-active="active" ui-sref=".payment"><span>3</span> Payment</a>
</div>
</div>
<!-- use ng-submit to catch the form submission and use our Angular function -->
<form id="signup-form" ng-submit="processForm()">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
and then to inject the form-date.html:
<h3>When would you like a helper?</h3>
<datetimepicker data-ng-model="formData.date"
data-datetimepicker-config="{ startView:'day', minView:'hour' }" />
<div> You've selected: {{formData.date}}</div>
<div class="form-group row">
<div class="col-xs-6 col-xs-offset-3">
<a ui-sref="form.payment" class="btn btn-block btn-info">
Next Section <span class="glyphicon glyphicon-circle-arrow-right"></span>
</a>
</div>
I'm using a custom CSS for the animation styling styling:
/* ANIMATION STYLINGS
============================================================================= */
#signup-form { position:relative; min-height:300px; overflow:hidden; padding:30px; }
#form-views { width:auto; }
/* basic styling for entering and leaving */
/* left and right added to ensure full width */
#form-views.ng-enter,
#form-views.ng-leave { position:absolute; left:30px; right:30px;
transition:0.5s all ease; -moz-transition:0.5s all ease; -webkit-transition:0.5s all ease;
}
/* enter animation */
#form-views.ng-enter {
-webkit-animation:slideInRight 0.5s both ease;
-moz-animation:slideInRight 0.5s both ease;
animation:slideInRight 0.5s both ease;
}
/* leave animation */
#form-views.ng-leave {
-webkit-animation:slideOutLeft 0.5s both ease;
-moz-animation:slideOutLeft 0.5s both ease;
animation:slideOutLeft 0.5s both ease;
}
/* ANIMATIONS
============================================================================= */
/* slide out to the left */
@keyframes slideOutLeft {
to { transform: translateX(-200%); }
}
@-moz-keyframes slideOutLeft {
to { -moz-transform: translateX(-200%); }
}
@-webkit-keyframes slideOutLeft {
to { -webkit-transform: translateX(-200%); }
}
/* slide in from the right */
@keyframes slideInRight {
from { transform:translateX(200%); }
to { transform: translateX(0); }
}
@-moz-keyframes slideInRight {
from { -moz-transform:translateX(200%); }
to { -moz-transform: translateX(0); }
}
@-webkit-keyframes slideInRight {
from { -webkit-transform:translateX(200%); }
to { -webkit-transform: translateX(0); }
}
EDIT - Controller:
angular.module('formApp')
.controller('formController', ['$scope', function($scope) {
$scope.beforeRender = function ($view, $dates, $leftDate, $upDate, $rightDate) {
var index = Math.floor(Math.random() * $dates.length);
$dates[index].selectable = false;
}
// we will store all of our form data in this object
$scope.formData = {};
$scope.formData.date = "";
$scope.opened = false;
$scope.time1 = new Date();
$scope.showMeridian = true;
//Datepicker
$scope.dateOptions = {
'year-format': "'yy'",
'show-weeks' : false,
'show-time':true
};
// function to process the form
$scope.processForm = function() {
alert('awesome!');
var appointment = new Appointment();
console.log(appointment);
};
}]);
The services come from the following plugin:
https://github.com/dalelotts/angular-bootstrap-datetimepicker
so would suspect it's not in there - but as I'm a noob i'm a little lost :-/
Upvotes: 1
Views: 2744
Reputation: 710
I found this to cause the issue:
You may be having the options setup in date picker. ie:
datepicker-options="dateOptions"
Now, try adding the options to your controller. ie:
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
If it helps - my HTML looked like this:
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="dd/MM/yyyy" ng-model="dt" is-open="status.opened"
min-date="minDate" max-date="'2020-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
Upvotes: 1
Reputation: 22323
Angular-Animate is a core library, and it's functionality is directly based on the core Angular library. It is critical that these libraries remain in sync. You must use the identical version for both libraries.
Upvotes: 0