File upload not working using knockout js. I have tried with below code but not working. Please mention where I am doing wrong.
This is my file control and button. I am
<input type="file" id="FileName" style="width:180px" data-bind="value:addModel.InputFileName" />
function ()
{
var files = $("#FileName").get(0).files;
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
}
$.ajax({
type: "POST",
url: '/api/Controller' + '/?id=' + id ),
contentType: false,
processData: false,
data: data,
success: function (result) {},
error: function (xhr, status, p3, p4) {}
});
}
For Magento 2 below code is useful to display uploaded image by knockout js.
In html file
<img class="myImage" data-bind="attr: {src: photoUrl() || 'images/tempImage.png'}"/>
<input data-bind="event: {change: fileUpload}" type="file" accept="image/*" class="fileChooser"/>
Js file need to code as below
define(['ko', 'uiComponent', 'jquery'], function (ko, Component, $) {
'use strict';
var photoUrl;
return Component.extend({
photoUrl : ko.observable(),
fileUpload: function(data, e)
{
var file = e.target.files[0];
var reader = new FileReader();
reader.onloadend = function (onloadend_e)
{
var result = reader.result; // Here is your base 64 encoded file. Do with it what you want.
self.photoUrl(result);
};
if(file)
{
reader.readAsDataURL(file);
}
},
});
});
}
above code is working fine with my project.
Seems like you need a custom knockout binding for file uploading. There are various api/libs available that handles all the error cases with additional features. Try this: https://github.com/TooManyBees/knockoutjs-file-binding
You can do the following:
View :
<input type="file" id="files" name="files[]" multiple data-bind=" event:{change: $root.fileSelect}" />
<output id="list"></output>
<ul>
<!-- ko foreach: files-->
<li>
<span data-bind ="text: name"></span>: <img class="thumb" data-bind = "attr: {'src': src, 'title': name}"/>
</li>
<!-- /ko -->
</ul>
JS:
var ViewModel = function() {
var self = this;
self.files= ko.observableArray([]);
self.fileSelect= function (elemet,event) {
var files = event.target.files;// FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
self.files.push(new FileModel(escape(theFile.name),e.target.result));
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
};
};
var FileModel= function (name, src) {
var self = this;
this.name = name;
this.src= src ;
};
ko.applyBindings(new ViewModel());
You can find the demo in the link: http://jsfiddle.net/fPWFd/436/
I came up with this solution for my current project.
<img class="myImage" data-bind="attr: {src: $root.photoUrl() || 'images/tempImage.png'}"/>
<input data-bind="event: {change: $root.fileUpload}" type="file" accept="image/*" class="fileChooser"/>
<script>
var myController = function()
{
var self = this;
this.photoUrl = ko.observable();
this.fileUpload = function(data, e)
{
var file = e.target.files[0];
var reader = new FileReader();
reader.onloadend = function (onloadend_e)
{
var result = reader.result; // Here is your base 64 encoded file. Do with it what you want.
self.photoUrl(result);
};
if(file)
{
reader.readAsDataURL(file);
}
};
};
</script>