knockout-file-bindings
Version:
HTML5 File bindings for knockout js with drag and drop and custom input buttons
161 lines (128 loc) • 5.56 kB
Markdown
knockout-file-bindings
======================
HTML5 File bindings for knockout js with drag and drop support and custom input buttons
## [See it in action](http://codepen.io/mrsafraz/pen/uIrwC)
## Basic Usage
**View Model**
```javascript
viewModel.fileData = ko.observable({
dataURL: ko.observable()
});
viewModel.fileData().dataURL.subscribe(function(dataURL){
// dataURL has changed do something with it!
});
```
along with `dataURL`, you can have any of `bindaryString`, `text`, `arrayBuffer` or `base64String` based on your needs. See [Anvanced Usage](#advanced-usage) section below
**View**
```html
<input type="file" data-bind="fileInput: fileData">
```
With custom file input (`knockout-file-bindings.css` should be included)
```html
<!-- with custom file input: -->
<input type="file" data-bind="fileInput: fileData, , customFileInput: {}">
```
with Drag and Drop container (`knockout-file-bindings.css` should be included)
```html
<div data-bind="fileDrag: fileData">
<input type="file" data-bind="fileInput: fileData, , customFileInput: {}">
</div>
```
with an Upload preview
```html
<div data-bind="fileDrag: fileData">
<div class="image-upload-preview">
<img data-bind="attr: { src: fileData().dataURL }, visible: fileData().dataURL">
</div>
<div class="image-upload-input">
<input type="file" data-bind="fileInput: fileData, , customFileInput: {}">
</div>
</div>
```
## Advanced usage
**View Model**
```javascript
ko.fileBindings.defaultOptions = {
wrapperClass: 'input-group',
fileNameClass: 'disabled form-control',
noFileText: 'No file chosen',
buttonGroupClass: 'input-group-btn',
buttonClass: 'btn btn-primary',
clearButtonClass: 'btn btn-default',
buttonText: 'Choose File',
changeButtonText: 'Change',
clearButtonText: 'Clear',
fileName: true, // show the selected file name?
clearButton: true, // show clear button?
onClear: function(fileData, options) {
if (typeof fileData.clear === 'function') {
fileData.clear();
}
}
};
// change a default option
ko.fileBindings.defaultOptions.buttonText = 'Browse';
viewModel.fileData = ko.observable({
file: ko.observable(), // will be filled with a File object
// Read the files (all are optional, e.g: if you're certain that it is a text file, use only text:
binaryString: ko.observable(), // FileReader.readAsBinaryString(Blob|File) - The result property will contain the file/blob's data as a binary string. Every byte is represented by an integer in the range [0..255].
text: ko.observable(), // FileReader.readAsText(Blob|File, opt_encoding) - The result property will contain the file/blob's data as a text string. By default the string is decoded as 'UTF-8'. Use the optional encoding parameter can specify a different format.
dataURL: ko.observable(), // FileReader.readAsDataURL(Blob|File) - The result property will contain the file/blob's data encoded as a data URL.
arrayBuffer: ko.observable(), // FileReader.readAsArrayBuffer(Blob|File) - The result property will contain the file/blob's data as an ArrayBuffer object.
// a special observable (optional)
base64String: ko.observable(), // just the base64 string, without mime type or anything else
// you can have observable arrays for each of the properties above, useful in multiple file upload selection (see Multiple file Uploads section below)
// in the format of xxxArray: ko.observableArray(),
/* e.g: */ fileArray: ko.observableArray(), base64StringArray: ko.observableArray(),
});
viewModel.fileData().text.subscribe(function(text){
// do something
});
viewModel.fileData().base64String.subscribe(function(base64String){
sendToServer(base64String);
});
```
Recommended:
[Reading HTML5 files](http://www.html5rocks.com/en/tutorials/file/dndfiles/#toc-reading-files)
**View**
```html
<div class="well" data-bind="fileDrag: fileData">
<div class="form-group row">
<div class="col-md-6">
<img style="height: 125px;" class="img-rounded thumb" data-bind="attr: { src: fileData().dataURL }, visible: fileData().dataURL">
<div data-bind="ifnot: fileData().dataURL">
<label class="drag-label">Drag file here</label>
</div>
</div>
<div class="col-md-6">
<input type="file" data-bind="fileInput: fileData, customFileInput: {
buttonClass: 'btn btn-success',
fileNameClass: 'disabled form-control'
}" accept="image/*">
</div>
</div>
</div>
```
## Multiple file Uploads
**View**
To support multiple files to be selected, you should add HTML5 `multiple` attribute
```html
<input type="file" multiple data-bind="fileInput: fileData">
```
**View Model**
you should have the `fileData` object exactly like above, except you can add `xxxArray` observable array properties where `xxx` is either `file`, `bindaryString`, `text`, `dataURL`, `arrayBuffer` or `base64String`
```javascript
viewModel.fileData = ko.observable({
file: ko.observable(), dataURL: ko.observable(), // you can still have the above methods if you want to focus on the first file
// xxxArray: ko.observableArray(), all are optional
fileArray: ko.observableArray(),
binaryStringArray: ko.observableArray(),
textArray: ko.observableArray(),
dataURLArray: ko.observableArray(),
arrayBufferArray: ko.observableArray(),
base64StringArray: ko.observableArray(),
});
viewModel.fileData().fileArray.subscribe(function(fileArray){
// fileArray has changed do something with it!
});
```