UNPKG

mongorilla

Version:

Mongorilla is a simple, clean, and powerful NodeJS based content moderator for MongoDB.

205 lines (176 loc) 8.79 kB
(function() { /** * Backbone Forms File editor * @author gerardobort <gerardobort@gmail.com> * @requires fancy-file */ Backbone.Form.editors.Image = Backbone.Form.editors.Base.extend({ tagName: 'div', defaultValue: '', initialize: function(options) { var editor = this; var options = options || {}; //Set initial value if (options.model) { if (!options.key) throw "Missing option: 'key'"; this.model = options.model; // string from model this.value = this.model.get(options.key); } else if (options.value) { // object from list this.value = options.value; } this.$el.removeClass('form-control'); this.$el.addClass('bbf-image'); editor.options = options; _.extend(editor, _.pick(options, 'key', 'form')); var schema = editor.schema = options.schema || {}; editor.validators = options.validators || schema.validators; // taken from: https://developer.mozilla.org/en-US/docs/Web/API/FileReader?redirectlocale=en-US&redirectslug=DOM%2FFileReader#readAsDataURL%28%29 this.oFReader = new FileReader(); this.rFilter = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i; }, /** * Adds the editor to the DOM */ render: function() { var editor = this; editor.$el.css({ width: 290, display: 'block' }); editor.$el.toggle(false); editor.$el.html( '<a class="img-link" href="#" target="_blank">' + '<img src="" class="image-preview img-thumbnail" style="display:block;max-height:300px;" />' + '</a>' + '<input name="upload" type="file" data-toggle="fancyfile" />' + '<button class="btn btn-danger remove-file"><i class="glyphicon glyphicon-remove"></i></button>' + '<div class="progress-container"></div>' ); setTimeout(function () { // once appended to the DOM editor.$el.toggle(true); $('[type="file"]', editor.$el).fancyfile({ text : '', icon : '<i class="glyphicon glyphicon-camera"></i>', style : 'btn-info', placeholder : 'Select Image…' }); $('.fancy-file', editor.$el).toggle(!editor.value); $('.remove-file', editor.$el).toggle(!!editor.value); $('.image-preview', editor.$el).toggle(!!editor.value); }, 200) if (editor.value) { if ('object' === typeof editor.value) { $('.img-link', editor.$el).attr('href', '/api/fs.files/' + editor.value._id + '/raw'); if (editor.value.metadata && editor.value.metadata.s3_url) { $('.image-preview', editor.$el).attr('src', editor.value.metadata.s3_url); } else { $('.image-preview', editor.$el).attr('src', '/api/fs.files/' + editor.value._id + '/raw'); } } else { $('.img-link', editor.$el).attr('href', '/api/fs.files/' + editor.value + '/raw'); $('.image-preview', editor.$el).attr('src', '/api/fs.files/' + editor.value + '/raw'); } } this._delegateEvents(); return this; }, _delegateEvents: function () { var editor = this; editor.oFReader.onload = function (oFREvent) { $('.image-preview', editor.$el).one('load', function () { $('.image-preview', editor.$el).toggle(true); }); $('.image-preview', editor.$el).attr('src', oFREvent.target.result); }; $('[type="file"]', editor.$el).on('change', function (event) { if (this.files.length === 0) { return; } var oFile = this.files[0]; // only in the case of images... TODO if (!editor.rFilter.test(oFile.type)) { alert("You must select a valid image file!"); return; } editor.oFReader.readAsDataURL(oFile); //--- var xhr = new XMLHttpRequest(); xhr.open('POST', '/api/fs.files'); $('.fancy-file', editor.$el).toggle(false); xhr.upload.onprogress = function (e) { console.log(e.loaded + ' of ' + e.total); var percent = (e.loaded/(e.total||1))*100 + '%'; $('.progress-container .progress-bar', editor.$el) .css('width', percent) .text('Uploading... ' + (percent === '100%' ? '(Waiting for a response)' : percent)); }; xhr.onload = function (xhr) { var response = JSON.parse(arguments[0].currentTarget.response); editor.setValue(response.data[0]._id); $('.remove-file', editor.$el).toggle(!!editor.value); $('.fancy-file', editor.$el).toggle(!editor.value); $('.image-preview', editor.$el).toggle(!!editor.value); $('.progress-container', editor.$el).html(''); $('.img-link', editor.$el).attr('href', '/api/fs.files/' + editor.value._id + '/raw'); }; var form = new FormData(); var collectionName = $('#collection-form').data('collection-name'); // TODO get this var in a better manner form.append(collectionName + '.' + editor.options.key, this.files[0]); xhr.send(form); $('.progress-container', editor.$el).html( '<div class="progress progress-striped">' + ' <div class="progress-bar" style="width:0%;"></div>' + '</div>' ); //--- }); $('.remove-file', editor.$el).on('click', function (event) { event.preventDefault(); require(['/third-party/alertify.js/lib/alertify.min.js'], function () { alertify.confirm('Are you sure you want to remove this image?', function (ok) { if (ok) { $.ajax({ url: '/api/fs.files/' + editor.value._id, method: 'DELETE' }) .success(function () { editor.setValue(null); $('[type="file"]', editor.$el).val(null); $('.image-preview', editor.$el).attr('src', 'about:blank'); $('.remove-file', editor.$el).toggle(!!editor.value); $('.fancy-file', editor.$el).toggle(!editor.value); $('.image-preview', editor.$el).toggle(!!editor.value); }) .error(function () { alert('An error has occurred.'); }) } }); }); }); }, /** * Returns the current editor value * @return {String} */ getValue: function() { // set the file object w/ObjectId if (this.value && 'object' === typeof this.value) { //return this.value._id; } return this.value; }, /** * Sets the value of the form element * @param {String} */ setValue: function(value) { // set the file object w/ObjectId if (value && 'object' === typeof value) { //value = value._id; } this.value = value; this.render(); }, focus: function () { $('[type="file"]', this.$el).get(0).focus(); }, blur: function () { $('[type="file"]', this.$el).get(0).blur(); } }); }());