{ div, input } = React.DOM BLANK_FUNCTION = () -> class @DropZone extends React.Component constructor: (props) -> super props @state = entity: props.entity record: props.record reader: null shared: new App.Shared() url: props.url @propTypes = # record: React.PropTypes.node entity: React.PropTypes.string # rkey: React.PropTypes.number id: React.PropTypes.string classes: React.PropTypes.string url: React.PropTypes.string onDragStart: React.PropTypes.func onDragEnter: React.PropTypes.func onDrop: React.PropTypes.func disabled: React.PropTypes.bool @defaultProps: -> disabled: true entity: 'stock_item' record: '' classes: '' id: 'dropzone' # rkey: 0 onDragStart: BLANK_FUNCTION onDragEnter: BLANK_FUNCTION onDrop: BLANK_FUNCTION # reader = () -> # # currentFile: (f) => # # # # if (i>-1) # # # remove element # # ids = @state.filesID.slice() # copy array # # ids.splice(i, 1) # remove element # # @setState filesID: ids # update state # # else # # @setState filesID: progressPercentElement = '' abortRead: () => @reader.abort() preventDefaultClick: (e) => e.preventDefault() e.stopPropagation() onDragStart: (e) => @preventDefaultClick(e) onDragOver: (e) => @preventDefaultClick(e) # if(this.containerAcceptsDropData(e.dataTransfer.types)) { e.preventDefault(); } # var over = parseInt(e.currentTarget.dataset.key); # if(e.clientY - e.currentTarget.offsetTop > e.currentTarget.offsetHeight / 2) { over++; } # if(over !== this.state.hoverOver) { this.setState({ hoverOver: over }); } e.dataTransfer.dropEffect = 'copy'; return false; onDragEnter: (e) => @preventDefaultClick(e) $('#drop_zone_upload_bay').addClass('hovering_files') onDragLeave: (e) => @preventDefaultClick(e) $('#drop_zone_upload_bay').removeClass('hovering_files') onDrop: (e) => @preventDefaultClick(e) dt = e.dataTransfer @handleFiles(dt.files) clickDropZone: (e) => $('#file_browser').trigger('click') changeDropZone: (e) => dt = e.target @handleFiles(dt.files) # .drop_zone.delimiter # .drop_zone.upload_bay.stitched # .drop_zone.file_browser # %input{ type: "file", multiple: true, id: "file_browser" } # .drop_zone.user_notice # %span # træk dine filer her; eller tryk og vælg # .drop_zone.file_hangar # # :coffeescript # $('.drop_zone.user_notice').on 'dragenter', (e) => # $('.drop_zone.upload_bay').addClass 'hovering_files' # $('.drop_zone.user_notice').on 'dragleave', (e) => # $('.drop_zone.upload_bay').removeClass 'hovering_files' # $('.drop_zone.user_notice').on 'click', (e) => # $('#file_browser').trigger 'click' render: -> photos = React.createElement( Photos, url: @props.url, pollInterval: 2000, id: 'existing_photos', classes: 'drop_zone existing_file_hangar', entity: @props.entity ) if @props.disabled div className: 'drop_zone file_hangar row' id: 'photos' photos else try div className: 'drop_zone delimiter' div className: 'drop_zone upload_bay row stitched' id: 'drop_zone_upload_bay' onClick: @clickDropZone div className: 'drop_zone file_browser' input className: "file_browser" type: "file" id: "file_browser" name: "files" multiple: 'true' onChange: @changeDropZone div className: 'drop_zone user_notice' onDragOver: @onDragOver onDragEnter: @onDragEnter onDragLeave: @onDragLeave # onClick: @clickDropZone onDrop: @onDrop 'træk dine billeder herover og slip dem; eller klik her og vælg dem!' div className: "progress" id: "progress_bar" div className: "percent" '0%' div className: 'drop_zone file_hangar row' id: 'photos' photos catch div className: '' @state.err handleFiles: (files) => @bindDeleteActions() count = 0 for file in files count=count+1 # Only process image files. continue if (!file.type.match('image.*')) file.id=Date.now() + count # place file in the dropzone @placeFileInDOM(file) # start uploading it # @uploadFile(file) bindDeleteActions: => $(document.body).unbind('click.delete_photo') $(document.body).on 'click.delete_photo', 'i.delete.file_upload', @handleDelete handleDelete: (e) => e.preventDefault() id=$(e.target).closest('.row').find('input.files_uploaded').first().val() jqxhr = $.ajax method: 'DELETE' url: "/photos/" + id + ".js" dataType: 'html' jqxhr.done (r) => $(e.target).closest('.card').fadeOut 'slow', () => #animate({ "opacity": "0" }, "slow" ) $(e.target).closest('.card').remove() jqxhr.fail (e,msg) => swal "Fejl!", "Det var ikke muligt at slette billedet - fejlen er:\n" + msg, "error" uploadFile: (f) => formData = new FormData() formData.append 'photo[image]', f $('#drop_zone_upload_bay').removeClass('hovering_files').addClass('loading_files') jqxhr = $.ajax url : '/photos.js' type : 'POST' data : formData processData: false contentType: false dataType: 'html' .done (r) => console.log r $('#drop_zone_upload_bay').removeClass('loading_files') $('#photos_'+f.id+'_id').val(r.replace(/\s/g, "")) .fail (e,msg) => $('#photos_'+f.id+'_id').closest('.card').remove() $('#drop_zone_upload_bay').removeClass('loading_files') $('#drop_zone_upload_bay').addClass('error_loading_files') setTimeout(@removeLoadError,2000) swal "Fejl!", "Der opstod desværre en fejl - beskrivelsen er:\n" + msg, "error" errorHandler: (evt) => switch evt.target.error.code when evt.target.error.NOT_FOUND_ERR then alert('File Not Found!') when evt.target.error.NOT_READABLE_ERR then alert('File is not readable') when evt.target.error.ABORT_ERR then console.log 'aborted!! line 227 in dropzone.js.jsx.coffee' else alert('An error occurred reading this file.') removeLoadError: (e) => $('#drop_zone_upload_bay').removeClass('error_loading_files') showProgress: (p) => progressPercentElement = document.querySelector('.percent') progressPercentElement.style.width = p + '%' progressPercentElement.textContent = p + '%' if p>99 @state.shared.fadeItOut document.getElementById('progress_bar') updateProgress: (e) => # e is an ProgressEvent. percentLoaded = 0 if (e.lengthComputable) percentLoaded = Math.round((e.loaded / e.total) * 100) # Increase the progress bar length. @showProgress(percentLoaded) if (percentLoaded < 100) @showProgress(100) if (percentLoaded > 99) placeFileInDOM: (file) => # Reset progress indicator on new file selection. # @updateProgress '' @reader = new FileReader() # @currentFile(file) @reader.onerror = @errorHandler @reader.onprogress = @updateProgress @reader.onabort = (e) => alert('File read cancelled') @reader.onloadstart = (e) => document.getElementById('progress_bar').className = 'loading' @reader.onload = (e) => # Render thumbnail. img = document.createElement('div') img.className = "col sl12 m6 l3" img.innerHTML = [ '
', '
', '', '', '
', '', '
', window.build_drop_zone_photo file, @props.entity '
', '
', '
' ].join('') document.getElementById('photos').appendChild(img, null) @uploadFile file # Ensure that the progress bar displays 100% at the end. @showProgress(100) # Read in the image file as a data URL. @reader.readAsDataURL(file)