For anyone interested, you could use the following custom binding, which allows binding a file input element to a knockout observable containing the File.
It handles setting the observable to the chosen file (as answered by @nemesv), as well as clearing the input element when the observable is being set to null (see this answer):
ko.bindingHandlers.fileUpload = {
init: function (element, valueAccessor) {
$(element).change(function () {
valueAccessor()(element.files[0]);
});
},
update: function (element, valueAccessor) {
if (ko.unwrap(valueAccessor()) === null) {
$(element).wrap('<form>').closest('form').get(0).reset();
$(element).unwrap();
}
}
};
Example:
function Example() {
var self = this;
self.uploadFile = ko.observable(null);
self.uploadName = ko.computed(function() {
return !!self.uploadFile() ? self.uploadFile().name : '-';
});
self.clear = function() {
self.uploadFile(null);
};
};
ko.bindingHandlers.fileUpload = {
init: function(element, valueAccessor) {
$(element).change(function() {
valueAccessor()(element.files[0]);
});
},
update: function(element, valueAccessor) {
if (ko.unwrap(valueAccessor()) === null) {
$(element).wrap('<form>').closest('form').get(0).reset();
$(element).unwrap();
}
}
};
ko.applyBindings(new Example());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="file" data-bind="fileUpload: uploadFile">
<br/>
<br/>Selected file name: <span data-bind="text: uploadName"></span>
<br/>
<button data-bind="click: clear">Clear input</button>