Skip to content

Commit c38e1aa

Browse files
committed
feat(input) add support to for week
Add support to date filter for outputing week of year Partially closes angular#757
1 parent 9c6d95e commit c38e1aa

File tree

3 files changed

+108
-58
lines changed

3 files changed

+108
-58
lines changed

src/ng/directive/input.js

+35-36
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\
1212
var EMAIL_REGEXP = /^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$/;
1313
var NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/;
1414
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)$/;
1616
var WEEK_REGEXP = /^(\d{4})-W(\d\d)$/;
1717

1818
var inputType = {
@@ -165,7 +165,7 @@ var inputType = {
165165
* @description
166166
* HTML5 or text input with datetime validation and transformation. In browsers that do not yet support
167167
* the HTML5 date input, a text element will be used. The text must be entered in a valid ISO-8601
168-
* local datetime format (yyyy-MM-ddTHH:mm:ss), for example: `2010-12-28T14:57:12`. Will also accept a valid ISO
168+
* local datetime format (yyyy-MM-ddTHH:mm), for example: `2010-12-28T14:57`. Will also accept a valid ISO
169169
* datetime string or Date object as model input, but will always output a Date object to the model.
170170
*
171171
* @param {string} ngModel Assignable angular expression to data-bind to.
@@ -184,27 +184,27 @@ var inputType = {
184184
<doc:source>
185185
<script>
186186
function Ctrl($scope) {
187-
$scope.value = '2010-12-28T14:57:12';
187+
$scope.value = '2010-12-28T14:57';
188188
}
189189
</script>
190190
<form name="myForm" ng-controller="Ctrl as dateCtrl">
191-
Pick a date between in 2013:
192-
<input type="date" name="input" ng-model="value"
193-
placeholder="yyyy-MM-dd" min="2013-01-01T00:00:00" max="2013-12-31T00:00:00" required />
194-
<span class="error" ng-show="myForm.input.$error.required">
195-
Required!</span>
196-
<span class="error" ng-show="myForm.input.$error.datetimelocal">
197-
Not a valid date!</span>
198-
<tt>value = {{value}}</tt><br/>
199-
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
200-
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
201-
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
202-
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
191+
Pick a date between in 2013:
192+
<input type="datetime-local" name="input" ng-model="value"
193+
placeholder="yyyy-MM-ddTHH:mm" min="2001-01-01T00:00" max="2013-12-31T00:00" required />
194+
<span class="error" ng-show="myForm.input.$error.required">
195+
Required!</span>
196+
<span class="error" ng-show="myForm.input.$error.datetimelocal">
197+
Not a valid date!</span>
198+
<tt>value = {{value}}</tt><br/>
199+
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
200+
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
201+
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
202+
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
203203
</form>
204204
</doc:source>
205205
<doc:scenario>
206206
it('should initialize to model', function() {
207-
expect(binding('value')).toEqual('2010-12-28T14:57:12');
207+
expect(binding('value')).toEqual('2010-12-28T14:57');
208208
expect(binding('myForm.input.$valid')).toEqual('true');
209209
});
210210
@@ -215,7 +215,7 @@ var inputType = {
215215
});
216216
217217
it('should be invalid if over max', function() {
218-
input('value').enter('2015-01-01T23:59:59');
218+
input('value').enter('2015-01-01T23:59');
219219
expect(binding('value')).toEqual('');
220220
expect(binding('myForm.input.$valid')).toEqual('false');
221221
});
@@ -254,18 +254,18 @@ var inputType = {
254254
}
255255
</script>
256256
<form name="myForm" ng-controller="Ctrl as dateCtrl">
257-
Pick a date between in 2013:
258-
<input type="date" name="input" ng-model="value"
259-
placeholder="yyyy-MM-dd" min="2012-W32" max="2013-W52" required />
260-
<span class="error" ng-show="myForm.input.$error.required">
261-
Required!</span>
262-
<span class="error" ng-show="myForm.input.$error.week">
263-
Not a valid date!</span>
264-
<tt>value = {{value}}</tt><br/>
265-
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
266-
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
267-
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
268-
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
257+
Pick a date between in 2013:
258+
<input type="week" name="input" ng-model="value"
259+
placeholder="YYYY-W##" min="2012-W32" max="2013-W52" required />
260+
<span class="error" ng-show="myForm.input.$error.required">
261+
Required!</span>
262+
<span class="error" ng-show="myForm.input.$error.week">
263+
Not a valid date!</span>
264+
<tt>value = {{value}}</tt><br/>
265+
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
266+
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
267+
<tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
268+
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
269269
</form>
270270
</doc:source>
271271
<doc:scenario>
@@ -289,7 +289,7 @@ var inputType = {
289289
</doc:example>
290290
*/
291291
'week': weekInputType,
292-
292+
293293
/**
294294
* @ngdoc inputType
295295
* @name ng.directive:input.number
@@ -730,7 +730,6 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
730730
}
731731
}
732732

733-
734733
function weekInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
735734
textInputType(scope, element, attr, ctrl, $sniffer, $browser);
736735

@@ -774,7 +773,6 @@ function weekInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter)
774773

775774
if(attr.max) {
776775
var maxValidator = function(value) {
777-
debugger;
778776
var valTime = getTime(value),
779777
maxTime = getTime(attr.max);
780778

@@ -843,6 +841,8 @@ function weekInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter)
843841
}
844842
}
845843

844+
}
845+
846846
function dateTimeLocalInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter) {
847847
textInputType(scope, element, attr, ctrl, $sniffer, $browser);
848848

@@ -863,7 +863,7 @@ function dateTimeLocalInputType(scope, element, attr, ctrl, $sniffer, $browser,
863863

864864
ctrl.$formatters.push(function(value) {
865865
if(isDate(value)) {
866-
return $filter('date')(value, 'yyyy-MM-ddTHH:mm:ss');
866+
return $filter('date')(value, 'yyyy-MM-ddTHH:mm');
867867
}
868868
return ctrl.$isEmpty(value) ? '' : '' + value;
869869
});
@@ -904,10 +904,9 @@ function dateTimeLocalInputType(scope, element, attr, ctrl, $sniffer, $browser,
904904
MM = +parts[2] - 1,
905905
dd = +parts[3],
906906
HH = +parts[4],
907-
mm = +parts[5],
908-
ss = +parts[6];
907+
mm = +parts[5];
909908

910-
return +new Date(yyyy, MM, dd, HH, mm, ss);
909+
return +new Date(yyyy, MM, dd, HH, mm);
911910
}
912911

913912
return NaN;

src/ng/filter/filters.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ function weekGetter(size) {
254254
result = 1 + Math.round(diff / 6.048e8);
255255

256256
return padNumber(result, size);
257-
}
257+
};
258258
}
259259

260260
function ampmGetter(date, formats) {

test/ng/directive/inputSpec.js

+72-21
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,6 @@ describe('input', function() {
751751

752752

753753
// INPUT TYPES
754-
755754
describe('week', function (){
756755
it('should set the view if the model is valid ISO8601 week', function() {
757756
compileInput('<input type="week" ng-model="secondWeek"/>');
@@ -798,6 +797,58 @@ describe('input', function() {
798797

799798

800799

800+
describe('min', function (){
801+
beforeEach(function (){
802+
compileInput('<input type="week" ng-model="value" name="alias" min="2013-W01" />');
803+
scope.$digest();
804+
});
805+
806+
it('should invalidate', function (){
807+
changeInputValueTo('2012-W12');
808+
expect(inputElm).toBeInvalid();
809+
expect(scope.value).toBeFalsy();
810+
expect(scope.form.alias.$error.min).toBeTruthy();
811+
});
812+
813+
it('should validate', function (){
814+
changeInputValueTo('2013-W03');
815+
expect(inputElm).toBeValid();
816+
expect(+scope.value).toBe(+new Date(2013, 0, 17));
817+
expect(scope.form.alias.$error.min).toBeFalsy();
818+
});
819+
});
820+
821+
describe('max', function(){
822+
beforeEach(function (){
823+
compileInput('<input type="week" ng-model="value" name="alias" max="2013-W01" />');
824+
scope.$digest();
825+
});
826+
827+
it('should validate', function (){
828+
changeInputValueTo('2012-W01');
829+
expect(inputElm).toBeValid();
830+
expect(+scope.value).toBe(+new Date(2012, 0, 5));
831+
expect(scope.form.alias.$error.max).toBeFalsy();
832+
});
833+
834+
it('should invalidate', function (){
835+
changeInputValueTo('2013-W03');
836+
expect(inputElm).toBeInvalid();
837+
expect(scope.value).toBeUndefined();
838+
expect(scope.form.alias.$error.max).toBeTruthy();
839+
});
840+
});
841+
});
842+
}
843+
844+
changeInputValueTo('stuff');
845+
expect(inputElm.val()).toBe('stuff');
846+
expect(scope.value).toBeUndefined();
847+
expect(inputElm).toBeInvalid();
848+
});
849+
850+
851+
801852
describe('min', function (){
802853
beforeEach(function (){
803854
compileInput('<input type="week" ng-model="value" name="alias" min="2013-W01" />');
@@ -846,30 +897,30 @@ describe('input', function() {
846897
compileInput('<input type="datetime-local" ng-model="lunchtime"/>');
847898

848899
scope.$apply(function(){
849-
scope.lunchtime = '2013-12-16T11:30:15';
900+
scope.lunchtime = '2013-12-16T11:30';
850901
});
851902

852-
expect(inputElm.val()).toBe('2013-12-16T11:30:15');
903+
expect(inputElm.val()).toBe('2013-12-16T11:30');
853904
});
854905

855906
it('should set the view if the model if a valid Date object.', function(){
856907
compileInput('<input type="datetime-local" ng-model="tenSecondsToNextYear"/>');
857908

858909
scope.$apply(function (){
859-
scope.tenSecondsToNextYear = new Date(2013, 11, 31, 23, 59, 50);
910+
scope.tenSecondsToNextYear = new Date(2013, 11, 31, 23, 59);
860911
});
861912

862-
expect(inputElm.val()).toBe('2013-12-31T23:59:50');
913+
expect(inputElm.val()).toBe('2013-12-31T23:59');
863914
});
864915

865916
it('should set the model undefined if the view is invalid', function (){
866917
compileInput('<input type="datetime-local" ng-model="breakMe"/>');
867918

868919
scope.$apply(function (){
869-
scope.breakMe = new Date(2009, 0, 6, 16, 25, 10);
920+
scope.breakMe = new Date(2009, 0, 6, 16, 25);
870921
});
871922

872-
expect(inputElm.val()).toBe('2009-01-06T16:25:10');
923+
expect(inputElm.val()).toBe('2009-01-06T16:25');
873924

874925
try {
875926
//set to text for browsers with datetime-local validation.
@@ -886,70 +937,70 @@ describe('input', function() {
886937

887938
describe('min', function (){
888939
beforeEach(function (){
889-
compileInput('<input type="datetime-local" ng-model="value" name="alias" min="2000-01-01T12:30:10" />');
940+
compileInput('<input type="datetime-local" ng-model="value" name="alias" min="2000-01-01T12:30" />');
890941
scope.$digest();
891942
});
892943

893944
it('should invalidate', function (){
894-
changeInputValueTo('1999-12-31T01:02:03');
945+
changeInputValueTo('1999-12-31T01:02');
895946
expect(inputElm).toBeInvalid();
896947
expect(scope.value).toBeFalsy();
897948
expect(scope.form.alias.$error.min).toBeTruthy();
898949
});
899950

900951
it('should validate', function (){
901-
changeInputValueTo('2000-01-01T23:02:01');
952+
changeInputValueTo('2000-01-01T23:02');
902953
expect(inputElm).toBeValid();
903-
expect(+scope.value).toBe(+new Date(2000, 0, 1, 23, 2, 1));
954+
expect(+scope.value).toBe(+new Date(2000, 0, 1, 23, 2));
904955
expect(scope.form.alias.$error.min).toBeFalsy();
905956
});
906957
});
907958

908959
describe('max', function (){
909960
beforeEach(function (){
910-
compileInput('<input type="datetime-local" ng-model="value" name="alias" max="2019-01-01T01:02:03" />');
961+
compileInput('<input type="datetime-local" ng-model="value" name="alias" max="2019-01-01T01:02" />');
911962
scope.$digest();
912963
});
913964

914965
it('should invalidate', function (){
915-
changeInputValueTo('2019-12-31T01:02:03');
966+
changeInputValueTo('2019-12-31T01:02');
916967
expect(inputElm).toBeInvalid();
917968
expect(scope.value).toBeFalsy();
918969
expect(scope.form.alias.$error.max).toBeTruthy();
919970
});
920971

921972
it('should validate', function() {
922-
changeInputValueTo('2000-01-01T01:02:03');
973+
changeInputValueTo('2000-01-01T01:02');
923974
expect(inputElm).toBeValid();
924-
expect(+scope.value).toBe(+new Date(2000, 0, 1, 1, 2, 3));
975+
expect(+scope.value).toBe(+new Date(2000, 0, 1, 1, 2));
925976
expect(scope.form.alias.$error.max).toBeFalsy();
926977
});
927978
});
928979

929980
it('should validate even if max value changes on-the-fly', function(done) {
930-
scope.max = '2013-01-01T01:02:03';
981+
scope.max = '2013-01-01T01:02';
931982
compileInput('<input type="datetime-local" ng-model="value" name="alias" max="{{max}}" />');
932983
scope.$digest();
933984

934-
changeInputValueTo('2014-01-01T12:34:56');
985+
changeInputValueTo('2014-01-01T12:34');
935986
expect(inputElm).toBeInvalid();
936987

937-
scope.max = '2001-01-01T01:02:03';
988+
scope.max = '2001-01-01T01:02';
938989
scope.$digest(function () {
939990
expect(inputElm).toBeValid();
940991
done();
941992
});
942993
});
943994

944995
it('should validate even if min value changes on-the-fly', function(done) {
945-
scope.min = '2013-01-01T01:02:03';
996+
scope.min = '2013-01-01T01:02';
946997
compileInput('<input type="datetime-local" ng-model="value" name="alias" min="{{min}}" />');
947998
scope.$digest();
948999

949-
changeInputValueTo('2010-01-01T12:34:56');
1000+
changeInputValueTo('2010-01-01T12:34');
9501001
expect(inputElm).toBeInvalid();
9511002

952-
scope.min = '2014-01-01T01:02:03';
1003+
scope.min = '2014-01-01T01:02';
9531004
scope.$digest(function () {
9541005
expect(inputElm).toBeValid();
9551006
done();

0 commit comments

Comments
 (0)