Skip to content

Commit 2bfff46

Browse files
committed
feat(form) input file type, without tests :-(.
Browser doesn't allow to set file input type to be set by javascript. How do I test it?
1 parent db06136 commit 2bfff46

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

src/ng/directive/input.js

+64-1
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,42 @@ var inputType = {
267267
*/
268268
'email': emailInputType,
269269

270+
/**
271+
* @ngdoc inputType
272+
* @name angular.module.ng.$compileProvider.directive.input.file
273+
*
274+
* @description
275+
* HTML file input field.
276+
*
277+
* @param {string} ngModel Assignable angular expression to data-bind to.
278+
* @param {string} multiple Allows multiple files selection.
279+
* @param {string=} name Property name of the form under which the control is published.
280+
*
281+
* @example
282+
<doc:example>
283+
<doc:source>
284+
<script>
285+
function Ctrl($scope) {
286+
}
287+
</script>
288+
<form name="myForm" ng-controller="Ctrl">
289+
file: <input type="file" ng-model="file"> single file selection.<br/>
290+
files: <input type="file" ng-model="files" multiple> multi-file selection.<br/>
291+
<tt>file.name = {{file.name}}</tt><br/>
292+
<tt>files.length = {{files.length}}</tt><br/>
293+
</form>
294+
</doc:source>
295+
<doc:scenario>
296+
it('should change state', function() {
297+
expect(binding('file.name')).toBeUndefined();
298+
299+
input('file').select('a file name');
300+
expect(binding('file.name')).toEqual('a file name');
301+
});
302+
</doc:scenario>
303+
</doc:example>
304+
*/
305+
'file': fileInputType,
270306

271307
/**
272308
* @ngdoc inputType
@@ -575,6 +611,33 @@ function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) {
575611
ctrl.$parsers.push(emailValidator);
576612
}
577613

614+
function fileInputType(scope, element, attr, ctrl) {
615+
element.bind('change', function() {
616+
scope.$apply(function() {
617+
var files = element[0].files,
618+
isValid = true;
619+
620+
if (attr.accept) {
621+
var i, j, acceptType, fileType,
622+
types = map(attr.accept.split(','), function(t) { return trim(t).split('/'); });
623+
for (i = 0; i < files.length && isValid; ++i) {
624+
fileType = files[i].type.split('/');
625+
isValid = false;
626+
for (j = 0; j < types.length && !isValid; ++j) {
627+
acceptType = types[j];
628+
isValid = acceptType[0] === fileType[0] && (acceptType[1] === '*' || acceptType[1] === fileType[1]);
629+
}
630+
}
631+
}
632+
ctrl.$setValidity('file', isValid);
633+
634+
var viewValue;
635+
if (isValid) viewValue = attr.multiple ? files : files[0];
636+
ctrl.$setViewValue(viewValue);
637+
});
638+
});
639+
}
640+
578641
function radioInputType(scope, element, attr, ctrl) {
579642
// make the name unique, if not defined
580643
if (isUndefined(attr.name)) {
@@ -896,7 +959,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', 'ngModel', '$e
896959
} catch(e) {
897960
$exceptionHandler(e);
898961
}
899-
})
962+
});
900963
}
901964
};
902965

0 commit comments

Comments
 (0)