@@ -12,7 +12,11 @@ var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\
12
12
var EMAIL_REGEXP = / ^ [ A - Z a - z 0 - 9 . _ % + - ] + @ [ A - Z a - z 0 - 9 . - ] + \. [ A - Z a - z ] { 2 , 6 } $ / ;
13
13
var NUMBER_REGEXP = / ^ \s * ( \- | \+ ) ? ( \d + | ( \d * ( \. \d * ) ) ) \s * $ / ;
14
14
var DATE_REGEXP = / ^ ( \d { 4 } ) - ( \d { 2 } ) - ( \d { 2 } ) $ / ;
15
- var DATETIMELOCAL_REGEXP = / ^ ( \d { 4 } ) - ( \d \d ) - ( \d \d ) T ( \d \d ) : ( \d \d ) : ( \d \d ) $ / ;
15
+ var DATETIMELOCAL_REGEXP = / ^ ( \d { 4 } ) - ( \d \d ) - ( \d \d ) T ( \d \d ) : ( \d \d ) $ / ;
16
+ < << << << HEAD
17
+ var WEEK_REGEXP = / ^ ( \d { 4 } ) - W ( \d \d ) $ / ;
18
+ = === ===
19
+ >>> >>> > e60a44c . . . feat ( input ) add support for datetime - local
16
20
17
21
var inputType = {
18
22
@@ -164,7 +168,7 @@ var inputType = {
164
168
* @description
165
169
* HTML5 or text input with datetime validation and transformation. In browsers that do not yet support
166
170
* the HTML5 date input, a text element will be used. The text must be entered in a valid ISO-8601
167
- * local datetime format (yyyy-MM-ddTHH:mm:ss ), for example: `2010-12-28T14:57:12 `. Will also accept a valid ISO
171
+ * local datetime format (yyyy-MM-ddTHH:mm), for example: `2010-12-28T14:57`. Will also accept a valid ISO
168
172
* datetime string or Date object as model input, but will always output a Date object to the model.
169
173
*
170
174
* @param {string } ngModel Assignable angular expression to data-bind to.
@@ -183,27 +187,27 @@ var inputType = {
183
187
<doc:source>
184
188
<script>
185
189
function Ctrl($scope) {
186
- $scope.value = '2010-12-28T14:57:12 ';
190
+ $scope.value = '2010-12-28T14:57';
187
191
}
188
192
</script>
189
193
<form name="myForm" ng-controller="Ctrl as dateCtrl">
190
- Pick a date between in 2013:
191
- <input type="date " name="input" ng-model="value"
192
- placeholder="yyyy-MM-dd " min="2013 -01-01T00:00:00 " max="2013-12-31T00:00 :00" required />
193
- <span class="error" ng-show="myForm.input.$error.required">
194
- Required!</span>
195
- <span class="error" ng-show="myForm.input.$error.datetimelocal">
196
- Not a valid date!</span>
197
- <tt>value = {{value}}</tt><br/>
198
- <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
199
- <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
200
- <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
201
- <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
194
+ Pick a date between in 2013:
195
+ <input type="datetime-local " name="input" ng-model="value"
196
+ placeholder="yyyy-MM-ddTHH:mm " min="2001 -01-01T00:00" max="2013-12-31T00:00" required />
197
+ <span class="error" ng-show="myForm.input.$error.required">
198
+ Required!</span>
199
+ <span class="error" ng-show="myForm.input.$error.datetimelocal">
200
+ Not a valid date!</span>
201
+ <tt>value = {{value}}</tt><br/>
202
+ <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
203
+ <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
204
+ <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
205
+ <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
202
206
</form>
203
207
</doc:source>
204
208
<doc:scenario>
205
209
it('should initialize to model', function() {
206
- expect(binding('value')).toEqual('2010-12-28T14:57:12 ');
210
+ expect(binding('value')).toEqual('2010-12-28T14:57');
207
211
expect(binding('myForm.input.$valid')).toEqual('true');
208
212
});
209
213
@@ -214,14 +218,84 @@ var inputType = {
214
218
});
215
219
216
220
it('should be invalid if over max', function() {
217
- input('value').enter('2015-01-01T23:59:59 ');
221
+ input('value').enter('2015-01-01T23:59');
218
222
expect(binding('value')).toEqual('');
219
223
expect(binding('myForm.input.$valid')).toEqual('false');
220
224
});
221
225
</doc:scenario>
222
226
</doc:example>
223
227
*/
224
228
'datetime-local' : dateTimeLocalInputType ,
229
+ << < << << HEAD
230
+
231
+ /**
232
+ * @ngdoc inputType
233
+ * @name ng.directive:input.week
234
+ *
235
+ * @description
236
+ * HTML5 or text input with week-of-the-year validation and transformation to Date. In browsers that do not yet support
237
+ * the HTML5 week input, a text element will be used. The text must be entered in a valid ISO-8601
238
+ * week format (yyyy-W##), for example: `2013-W02`. Will also accept a valid ISO
239
+ * week string or Date object as model input, but will always output a Date object to the model.
240
+ *
241
+ * @param {string } ngModel Assignable angular expression to data-bind to.
242
+ * @param {string= } name Property name of the form under which the control is published.
243
+ * @param {string= } min Sets the `min` validation error key if the value entered is less than `min`.
244
+ * @param {string= } max Sets the `max` validation error key if the value entered is greater than `max`.
245
+ * @param {string= } required Sets `required` validation error key if the value is not entered.
246
+ * @param {string= } ngRequired Adds `required` attribute and `required` validation constraint to
247
+ * the element when the ngRequired expression evaluates to true. Use `ngRequired` instead of
248
+ * `required` when you want to data-bind to the `required` attribute.
249
+ * @param {string= } ngChange Angular expression to be executed when input changes due to user
250
+ * interaction with the input element.
251
+ *
252
+ * @example
253
+ <doc:example>
254
+ <doc:source>
255
+ <script>
256
+ function Ctrl($scope) {
257
+ $scope.value = '2013-W01';
258
+ }
259
+ </script>
260
+ <form name="myForm" ng-controller="Ctrl as dateCtrl">
261
+ Pick a date between in 2013:
262
+ <input type="week" name="input" ng-model="value"
263
+ placeholder="YYYY-W##" min="2012-W32" max="2013-W52" required />
264
+ <span class="error" ng-show="myForm.input.$error.required">
265
+ Required!</span>
266
+ <span class="error" ng-show="myForm.input.$error.week">
267
+ Not a valid date!</span>
268
+ <tt>value = {{value}}</tt><br/>
269
+ <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
270
+ <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
271
+ <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
272
+ <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
273
+ </form>
274
+ </doc:source>
275
+ <doc:scenario>
276
+ it('should initialize to model', function() {
277
+ expect(binding('value')).toEqual('2013-W01');
278
+ expect(binding('myForm.input.$valid')).toEqual('true');
279
+ });
280
+
281
+ it('should be invalid if empty', function() {
282
+ input('value').enter('');
283
+ expect(binding('value')).toEqual('');
284
+ expect(binding('myForm.input.$valid')).toEqual('false');
285
+ });
286
+
287
+ it('should be invalid if over max', function() {
288
+ input('value').enter('2015-W01');
289
+ expect(binding('value')).toEqual('');
290
+ expect(binding('myForm.input.$valid')).toEqual('false');
291
+ });
292
+ </doc:scenario>
293
+ </doc:example>
294
+ */
295
+ 'week' : weekInputType ,
296
+
297
+ = === ===
298
+ >>> >>> > e60a44c . . . feat ( input ) add support for datetime - local
225
299
/**
226
300
* @ngdoc inputType
227
301
* @name ng.directive:input.number
@@ -669,6 +743,121 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
669
743
}
670
744
}
671
745
746
+ << < << << HEAD
747
+
748
+ function weekInputType ( scope , element , attr , ctrl , $sniffer , $browser , $filter ) {
749
+ textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) ;
750
+
751
+ ctrl . $parsers . push ( function ( value ) {
752
+ if ( ctrl . $isEmpty ( value ) ) {
753
+ ctrl . $setValidity ( 'week' , true ) ;
754
+ return value ;
755
+ }
756
+
757
+ if ( WEEK_REGEXP . test ( value ) ) {
758
+ ctrl . $setValidity ( 'week' , true ) ;
759
+ return new Date ( getTime ( value ) . time ) ;
760
+ }
761
+
762
+ ctrl . $setValidity ( 'week' , false ) ;
763
+ return undefined ;
764
+ } ) ;
765
+
766
+ ctrl . $formatters . push ( function ( value ) {
767
+ if ( isDate ( value ) ) {
768
+ return $filter ( 'date' ) ( value , 'yyyy-Www' ) ;
769
+ }
770
+ return ctrl . $isEmpty ( value ) ? '' : '' + value ;
771
+ } ) ;
772
+
773
+ if ( attr . min ) {
774
+ var minValidator = function ( value ) {
775
+ var valTime = getTime ( value ) ,
776
+ minTime = getTime ( attr . min ) ;
777
+
778
+ var valid = ctrl . $isEmpty ( value ) ||
779
+ valTime . time >= minTime . time ;
780
+
781
+ ctrl . $setValidity ( 'min' , valid ) ;
782
+ return valid ? value : undefined ;
783
+ } ;
784
+
785
+ ctrl . $parsers . push ( minValidator ) ;
786
+ ctrl . $formatters . push ( minValidator ) ;
787
+ }
788
+
789
+ if ( attr . max ) {
790
+ var maxValidator = function ( value ) {
791
+ var valTime = getTime ( value ) ,
792
+ maxTime = getTime ( attr . max ) ;
793
+
794
+ var valid = ctrl . $isEmpty ( value ) ||
795
+ valTime . time <= maxTime . time ;
796
+
797
+ ctrl . $setValidity ( 'max' , valid ) ;
798
+ return valid ? value : undefined ;
799
+ } ;
800
+
801
+ ctrl . $parsers . push ( maxValidator ) ;
802
+ ctrl . $formatters . push ( maxValidator ) ;
803
+ }
804
+
805
+ function getFirstThursday ( year ) {
806
+ var d = 1 , date ;
807
+ while ( true ) {
808
+ date = new Date ( year , 0 , d ++ ) ;
809
+ if ( date . getDay ( ) === 4 ) {
810
+ return date ;
811
+ }
812
+ }
813
+ }
814
+
815
+ function getThisThursday ( date ) {
816
+ return new Date ( date . getFullYear ( ) , date . getMonth ( ) , date . getDate ( ) + ( 4 - date . getDay ( ) ) ) ;
817
+ }
818
+
819
+ var MILLISECONDS_PER_WEEK = 6.048e8 ;
820
+
821
+ function getWeek ( date ) {
822
+ var firstThurs = getFirstThursday ( date . getFullYear ( ) ) ,
823
+ thisThurs = getThisThursday ( date ) ,
824
+ diff = + thisThurs - + firstThurs ;
825
+
826
+ return 1 + Math . round ( diff / MILLISECONDS_PER_WEEK ) ;
827
+ }
828
+
829
+ function getTime ( isoWeek ) {
830
+ if ( isDate ( isoWeek ) ) {
831
+ return {
832
+ year : isoWeek . getFullYear ( ) ,
833
+ week : getWeek ( isoWeek ) ,
834
+ time : + isoWeek
835
+ } ;
836
+ }
837
+
838
+ if ( isString ( isoWeek ) ) {
839
+ WEEK_REGEXP . lastIndex = 0 ;
840
+ var parts = WEEK_REGEXP . exec ( isoWeek ) ;
841
+ if ( parts ) {
842
+ var year = + parts [ 1 ] ,
843
+ week = + parts [ 2 ] ,
844
+ firstThurs = getFirstThursday ( year ) ,
845
+ addDays = ( week - 1 ) * 7 ;
846
+
847
+ return {
848
+ time : + new Date ( year , 0 , firstThurs . getDate ( ) + addDays ) ,
849
+ week : week ,
850
+ year : year
851
+ } ;
852
+ }
853
+ }
854
+
855
+ return NaN ;
856
+ }
857
+ }
858
+
859
+ === = ===
860
+ >>> > >>> e60a44c . . . feat ( input ) add support for datetime - local
672
861
function dateTimeLocalInputType ( scope , element , attr , ctrl , $sniffer , $browser , $filter ) {
673
862
textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) ;
674
863
@@ -689,7 +878,7 @@ function dateTimeLocalInputType(scope, element, attr, ctrl, $sniffer, $browser,
689
878
690
879
ctrl . $formatters . push ( function ( value ) {
691
880
if ( isDate ( value ) ) {
692
- return $filter ( 'date' ) ( value , 'yyyy-MM-ddTHH:mm:ss ' ) ;
881
+ return $filter ( 'date' ) ( value , 'yyyy-MM-ddTHH:mm' ) ;
693
882
}
694
883
return ctrl . $isEmpty ( value ) ? '' : '' + value ;
695
884
} ) ;
@@ -730,10 +919,9 @@ function dateTimeLocalInputType(scope, element, attr, ctrl, $sniffer, $browser,
730
919
MM = + parts [ 2 ] - 1 ,
731
920
dd = + parts [ 3 ] ,
732
921
HH = + parts [ 4 ] ,
733
- mm = + parts [ 5 ] ,
734
- ss = + parts [ 6 ] ;
922
+ mm = + parts [ 5 ] ;
735
923
736
- return + new Date ( yyyy , MM , dd , HH , mm , ss ) ;
924
+ return + new Date ( yyyy , MM , dd , HH , mm ) ;
737
925
}
738
926
739
927
return NaN ;
0 commit comments