1/* 2 * File input binding for knockout.js 3 * Jesse Kipp - Nov 14, 2013 4 * 5 * A special binding for file input elements. Think of it like 'value', but 6 * storing the encoded data from a FileReader object. 7 * 8 * Usage 1: 9 * <input type='file' data-bind='file: fileInput'> 10 * If fileInput is an observable, it will be assigned the value of the base64 11 * encoded file data. 12 * 13 * Usage 2: 14 * <input type='file' data-bind='file: {data: fileInput, name: fileName}'> 15 * When passing an object, use the following keys 16 * data: the observable to store the file data (required) 17 * name: the observable to store the file name 18 * allowed: permitted content types (text/javascript, etc), as a string or 19 * array of strings. All other types will be ignored. 20 * prohibited: content types that will always be ignored. 21 * reader: an existing FileReader object. If not defined, creates a new 22 * one internally. 23 */ 24 25(function () { 26 var factory = function (ko) { 27 28 ko.bindingHandlers['file'] = { 29 init: function(element, valueAccessor, allBindings) { 30 var fileContents, fileName, allowed, prohibited, reader; 31 32 if ((typeof valueAccessor()) === "function") { 33 fileContents = valueAccessor(); 34 } else { 35 fileContents = valueAccessor()['data']; 36 fileName = valueAccessor()['name']; 37 38 allowed = valueAccessor()['allowed']; 39 if ((typeof allowed) === 'string') { 40 allowed = [allowed]; 41 } 42 43 prohibited = valueAccessor()['prohibited']; 44 if ((typeof prohibited) === 'string') { 45 prohibited = [prohibited]; 46 } 47 48 reader = (valueAccessor()['reader']); 49 } 50 51 reader || (reader = new FileReader()); 52 reader.onloadend = function() { 53 fileContents(reader.result); 54 } 55 56 var handler = function() { 57 var file = element.files[0]; 58 59 // Opening the file picker then canceling will trigger a 'change' 60 // event without actually picking a file. 61 if (file === undefined) { 62 fileContents(null) 63 return; 64 } 65 66 if (allowed) { 67 if (!allowed.some(function(type) { return type === file.type })) { 68 console.log("File "+file.name+" is not an allowed type, ignoring.") 69 fileContents(null) 70 return; 71 } 72 } 73 74 if (prohibited) { 75 if (prohibited.some(function(type) { return type === file.type })) { 76 console.log("File "+file.name+" is a prohibited type, ignoring.") 77 fileContents(null) 78 return; 79 } 80 } 81 82 reader.readAsDataURL(file); // A callback (above) will set fileContents 83 if (typeof fileName === "function") { 84 fileName(file.name) 85 } 86 } 87 88 ko.utils.registerEventHandler(element, 'change', handler); 89 } 90 } 91 } 92 93 if ((typeof define === 'function') && define.amd) { 94 define(['knockout'], factory); 95 } else { 96 factory(ko); 97 } 98})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.