@@ -13,7 +13,7 @@ picker.directive 'dateRangePicker', ($compile, $timeout, $parse, dateRangePicker
13
13
scope :
14
14
min : ' ='
15
15
max : ' ='
16
- model : ' =ngmodel '
16
+ model : ' =ngModel '
17
17
opts : ' =options'
18
18
clearable : ' ='
19
19
link : ($scope , element , attrs , modelCtrl ) ->
@@ -22,16 +22,14 @@ picker.directive 'dateRangePicker', ($compile, $timeout, $parse, dateRangePicker
22
22
opts = angular .merge ({}, dateRangePickerConfig, customOpts)
23
23
_picker = null
24
24
25
- clear = ->
25
+ _clear = ->
26
26
_picker .setStartDate ()
27
27
_picker .setEndDate ()
28
28
29
29
_setDatePoint = (setter ) ->
30
30
(newValue ) ->
31
- if (_picker)
32
- if not newValue
33
- then clear ()
34
- else setter (moment (newValue))
31
+ if _picker and newValue
32
+ setter (moment (newValue))
35
33
36
34
_setStartDate = _setDatePoint (m ) ->
37
35
if (_picker .endDate < m)
@@ -43,27 +41,27 @@ picker.directive 'dateRangePicker', ($compile, $timeout, $parse, dateRangePicker
43
41
_picker .setStartDate (m)
44
42
_picker .setEndDate (m)
45
43
46
- # Watchers enable resetting of start and end dates
47
- $scope .$watch ' model.startDate' , _setStartDate
48
- $scope .$watch ' model.endDate' , _setEndDate
49
-
50
- _format = (viewVal ) ->
44
+ # Formats the obj into the string for the element input
45
+ _format = (objValue ) ->
51
46
f = (date ) ->
52
47
if not moment .isMoment (date)
53
48
then moment (date).format (opts .locale .format )
54
49
else date .format (opts .locale .format )
55
50
56
- if opts .singleDatePicker
57
- then f (viewVal .startDate )
58
- else [f (viewVal .startDate ), f (viewVal .endDate )].join (opts .locale .separator )
51
+ if objValue and objValue .startDate
52
+ if opts .singleDatePicker
53
+ then f (objValue .startDate )
54
+ else [f (objValue .startDate ), f (objValue .endDate )].join (opts .locale .separator )
55
+ else ' '
59
56
60
- _parse = ( value ) ->
61
- f = ( val ) ->
62
- moment (val, opts . locale . format )
63
- if opts . singleDatePicker
64
- then f (value)
65
- else value . split ( opts . locale . separator ). map (f )
57
+ # Sets the viewValue as well as updating the input element's value
58
+ # Note: This is necessary as we don't allow the date picker to update the text (using autoUpdateInput: false)
59
+ _setViewValue = ( objValue ) ->
60
+ value = _format (objValue)
61
+ el . val (value)
62
+ modelCtrl . $setViewValue (value )
66
63
64
+ # Validation for our min/max
67
65
_validate = (validator ) ->
68
66
(boundary , actual ) ->
69
67
if boundary and actual
@@ -73,57 +71,74 @@ picker.directive 'dateRangePicker', ($compile, $timeout, $parse, dateRangePicker
73
71
_validateMin = _validate (min , start ) -> min .isBefore (start) or min .isSame (start, ' day' )
74
72
_validateMax = _validate (max , end ) -> max .isAfter (end) or max .isSame (end, ' day' )
75
73
74
+ # Formatter should return just the string value of the input
75
+ # It is used for comparison of if we should re-render
76
76
modelCtrl .$formatters .push (val) ->
77
77
if val and val .startDate
78
78
then _format (val)
79
79
else ' '
80
80
81
+ # Render should update the date picker start/end dates as necessary
82
+ # It should also set the input element's val with $viewValue as we don't let the rangepicker do this
83
+ modelCtrl .$render = () ->
84
+ # Update the calendars
85
+ if modelCtrl .$modelValue and modelCtrl .$modelValue .startDate
86
+ _setStartDate (modelCtrl .$modelValue .startDate )
87
+ _setEndDate (modelCtrl .$modelValue .endDate )
88
+ else
89
+ _clear ()
90
+ # Update the input
91
+ el .val (modelCtrl .$viewValue )
92
+
93
+ # This should parse the string input into an updated model object
81
94
modelCtrl .$parsers .push (val) ->
82
- # Check if input is valid.
83
- value =
95
+ # Parse the string value
96
+ f = (value ) ->
97
+ moment (value, opts .locale .format )
98
+ objValue =
84
99
startDate : null
85
100
endDate : null
86
101
if angular .isString (val) and val .length > 0
87
- x = _parse (val)
88
- value .startDate = x[0 ]
89
- value .endDate = x[1 ]
90
- value
102
+ if opts .singleDatePicker
103
+ objValue .startDate = f (val)
104
+ else
105
+ x = val .split (opts .locale .separator ).map (f)
106
+ objValue .startDate = x[0 ]
107
+ objValue .endDate = x[1 ]
108
+ objValue
91
109
92
110
modelCtrl .$isEmpty = (val ) ->
93
- # modelCtrl is empty if val is invalid or any of the ranges are not set.
94
- not val or val .startDate == null or val .endDate == null
95
-
96
- modelCtrl .$render = ->
97
- if modelCtrl .$modelValue and modelCtrl .$modelValue .startDate != null
98
- _setStartDate (modelCtrl .$modelValue .startDate )
99
- _setEndDate (modelCtrl .$modelValue .endDate )
100
- else
101
- clear ()
111
+ # modelCtrl is empty if val is empty string
112
+ not val and val .length > 0
102
113
114
+ # _init has to be called anytime we make changes to the date picker options
103
115
_init = ->
104
- el .daterangepicker opts
116
+ # disable autoUpdateInput, can't handle empty values without it. Our callback here will
117
+ # update our $viewValue, which triggers the $parsers
118
+ el .daterangepicker angular .extend (opts, {autoUpdateInput : false }), (start , end ) ->
119
+ _setViewValue ({startDate : start, endDate : end})
105
120
106
121
# Needs to be after daterangerpicker has been created, otherwise
107
122
# watchers that reinit will be attached to old daterangepicker instance.
108
123
_picker = el .data (' daterangepicker' )
109
124
110
- # Ability to attach event handlers. See https://github.com/fragaria/angular-daterangepicker/pull/62
125
+ # Ability to attach event handlers. See https://github.com/fragaria/angular-daterangepicker/pull/62
111
126
for eventType, callbackFunction of opts .eventHandlers
112
127
el .on eventType, () ->
113
128
$scope .$evalAsync (callbackFunction)
114
129
115
- if attrs .clearable
116
- locale = opts .locale || {}
117
- locale .cancelLabel = opts .clearLabel
118
- opts .locale = locale
119
-
120
- el .on ' cancel.daterangepicker' , () ->
121
- modelCtrl .$setViewValue ({startDate : null , endDate : null })
122
- modelCtrl .$render ()
123
- return el .trigger ' change'
124
-
125
130
_init ()
126
131
132
+ # Watchers enable resetting of start and end dates
133
+ # Update the date picker, and set a new viewValue of the model
134
+ $scope .$watch ' model.startDate' , (n ) ->
135
+ _setStartDate (n)
136
+ _setViewValue ($scope .model )
137
+ $scope .$watch ' model.endDate' , (n ) ->
138
+ _setEndDate (n)
139
+ _setViewValue ($scope .model )
140
+
141
+ # Add validation/watchers for our min/max fields
127
142
_initBoundaryField = (field , validator , modelField , optName ) ->
128
143
if attrs[field]
129
144
modelCtrl .$validators [field] = (value ) ->
@@ -135,11 +150,23 @@ picker.directive 'dateRangePicker', ($compile, $timeout, $parse, dateRangePicker
135
150
_initBoundaryField (' min' , _validateMin, ' startDate' , ' minDate' )
136
151
_initBoundaryField (' max' , _validateMax, ' endDate' , ' maxDate' )
137
152
153
+ # Watch our options
138
154
if attrs .options
139
155
$scope .$watch ' opts' , (newOpts ) ->
140
- opts = angular .merge (opts, newOpts, { autoUpdateInput : false } )
156
+ opts = angular .merge (opts, newOpts)
141
157
_init ()
142
158
, true
143
159
160
+ # Watch clearable flag
161
+ if attrs .clearable
162
+ $scope .$watch ' clearable' , (newClearable ) ->
163
+ if newClearable
164
+ opts = angular .merge (opts, {locale : {cancelLabel : opts .clearLabel }})
165
+ _init ()
166
+ el .on ' cancel.daterangepicker' , (
167
+ if newClearable
168
+ then _setViewValue .bind (this , {startDate : null , endDate : null })
169
+ else null )
170
+
144
171
$scope .$on ' $destroy' , ->
145
172
_picker ? .remove ()
0 commit comments