I am using dropzone to upload files to my server without any issues, i would like to add extra parameters such a meta data.
Any ideas on how to do this?
Code Below and just using controller in normal fashion
<div class="row">
<div class="col-lg-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Select</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
</a>
</div>
</div>
<div class="ibox-content">
<form id="my-awesome-dropzone" class="dropzone" action="#Url.Action(" FileUploadHandler ", "Controller ")" method="post" enctype="multipart/form-data">
<div class="dropzone-previews"></div>
<button type="submit" class="btn btn-primary pull-right">Submit your application</button>
</form>
<div>
<div class="m text-right">test</div>
</div>
</div>
</div>
</div>
</div>
`
< script type = "text/javascript" >
$(document).ready(function() {
Dropzone.options.myAwesomeDropzone = {
autoProcessQueue: false,
parallelUploads: 1,
maxFiles: 1,
maxFilesize: 2000,
paramName: "test,123",
acceptedFiles: ".zip",
// Dropzone settings
init: function() {
var myDropzone = this;
this.element.querySelector("button[type=submit]").addEventListener("click", function(e) {
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
//Get All information to submit to server
var appName = "";
var typeOfApp = 1;
var commandLine = "";
var osType = 1;
});
this.on("sending", function(file, xhr, data) {
data.append("filetype", "avataruploadtype");
});
}
}
});
`
The way you have it set up, you're just submitting the form, so one easy approach is to just add inputs (or hidden fields) to the form and handle the multipart form data on the server.
See here for detail:
https://github.com/enyo/dropzone/wiki/Combine-normal-form-with-Dropzone
Related
Html:
<body ng-app ng-controller="OrderFormController">
<!--<h1 class="errorHeader">List of Classes</h1>-->
<header>
<div class="container">
<div id="branding">
<h1>Apex <span class="highlight"> Editor </span> </h1>
</div>
</div>
</header>
<div class="col-md-12 col-lg-12">
<div class="panel with-nav-tabs panel-default">
<div class="panel-heading">
<ul class="nav nav-tabs">
<li class="active">Apex Editor</li>
</ul>
</div>
<div class="panel-body">
<div>
<input type="text" name="apexClass" id="autocomplete" placeholder="Type the name of the Apex class you want to edit"/>
</div>
<div class="btn-group-vertical" style="padding: 1%">
<button type="button" class="btn btn-primary" id="editBtn">Edit</button>
</button>
</div>
<div class="tab-content" align="left">
<div id='error' style='display:none'>{{apexClassWrapperError.message}}</div>
<div>{{apexClassWrapper.name}}</div>
<img src="../img/ajax-loader.gif" id="loaderImage" style='display:none'>
<form>
<textarea ng-model="apexClassWrapper.body" id="code" name="code" readonly="true" >{{apexClassWrapper.body}}</textarea>
</form>
</div>
<button type="button" class="btn btn-primary" id="saveBtn" ng-click="postdata(apexClassWrapper)">Save</button>
</div>
</div>
</div>
<script src="../js/makeEditable.js"></script>
<script>
$(function() {
var editor = CodeMirror.fromTextArea(document.getElementById("code"),{
linenumber : true,
matchBrackes: true,
mode: "text/x-apex"
})
});
</script>
<footer>
<p>Web based Apex Editor</p>
<p>Developed By - Nagendra Kumar Singh</p>
</footer>
</body>
CSS and JS files included at top:
<script src="../js/codemirror.js"></script>
<script src="../js/apex.js"></script>
<script src="../js/matchbrackets.js"></script>
<link href="../css/codemirror.css" rel="stylesheet"/>
The controller is a simple one fetching the class through a RESTApi.
function OrderFormController($scope, $http) {
$('#autocomplete').autocomplete({
type: 'POST',
serviceUrl: 'http://localhost:8989/getSuggestion',
onSelect: function (suggestion) {
console.log('suggestion.value -> '+suggestion.value);
var data = {
apexClassName:suggestion.value
};
var config = {
params: data
};
$('#loaderImage').show();
$http.get("http://localhost:8989/getApexBody",config).then(function (response) {
$scope.apexClassWrapper = response.data;
$('#loaderImage').hide();
});
}
});
};
But I can only see {{apexClassWrapper.body}} in my text area, I dont see the real code when using CodeMirror, If I remove code mirror , I can see the class, but I cannot figure out a way to show the body with CodeMirror included.
There are no errors in console log and all the JS and CSS files are loaded perfectly. Please help.
Ok, So I think I may have figured it out. What I did is I set a timeout for the codemirror code to run as follows in the js file and removed it from the index.html.
$('#loaderImage').show();
$http.get("http://localhost:8989/getApexBody", config).then(function (response) {
$scope.apexClassWrapper = response.data;
$('#loaderImage').hide();
if(globalEditor) {
globalEditor.toTextArea();
}
setTimeout(function (test) {
var editor = CodeMirror.fromTextArea(document.getElementById('apexBody'), {
lineNumbers: true,
matchBrackets: true,
mode: "text/x-apex"
});
globalEditor = $('.CodeMirror')[0].CodeMirror;
}), 2000
});
The only issue in this answer is that, it creates multiple code editor window when I try to load different classes. How can I resolve that?
So finally got it working, defined a global variable and using the method toTextArea
I'm using jquery dropzone.js. To load the form I'm using mustache like below. But I can't innit the dropzone after the page is fully loaded because there is no form loaded on that moment. Is there a option to init the dropzone after it's loaded?
Mustache file with the form:
<div class="col-lg-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Dropzone Area</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
<li>Config option 1
</li>
<li>Config option 2
</li>
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form id="my-awesome-dropzone" class="dropzone" action="#">
<div class="dropzone-previews"></div>
<button type="submit" class="btn btn-primary pull-right">Submit this form!</button>
</form>
<div>
<div class="m text-right"><small>DropzoneJS is an open source library that provides drag'n'drop file uploads with image previews: https://github.com/enyo/dropzone</small> </div>
</div>
</div>
</div>
</div>
The functions to load the mustache and init the dropzone:
<script>
$( document ).ready(function() {
// get the mustache
loadDropZone();
// HOW CAN I DO THIS AFTER THE DROPZONE FORM IS CREATED?
// init dropzone
Dropzone.options.myAwesomeDropzone = {
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
// Dropzone settings
init: function () {
var myDropzone = this;
this.element.querySelector("button[type=submit]").addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
this.on("sendingmultiple", function () {
});
this.on("successmultiple", function (files, response) {
});
this.on("errormultiple", function (files, response) {
});
}
}
});
function loadDropZone() {
$.get(websiteUrl + 'storages/mustache/image-drop-zone.mst', function(template) {
Mustache.parse(template); // speeds up future uses
var rendered = Mustache.render(template);
$('#block-container').append(rendered);
});
}
</script>
You should initialize dropzone programatically instead of using the options and the auto discover feature.
Should look like this:
<script>
Dropzone.autoDiscover = false; // This is optional in this case
$( document ).ready(function() {
// get the mustache
loadDropZone();
// Now that the form is loaded you can initialize dropzone by creating an instance
// init dropzone
var myAwesomeDropzone = new Dropzone("form#my-awesome-dropzone", {
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
// Dropzone settings
init: function () {
var myDropzone = this;
this.element.querySelector("button[type=submit]").addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
this.on("sendingmultiple", function () {
});
this.on("successmultiple", function (files, response) {
});
this.on("errormultiple", function (files, response) {
});
}
}
});
function loadDropZone() {
$.get(websiteUrl + 'storages/mustache/image-drop-zone.mst', function(template) {
Mustache.parse(template); // speeds up future uses
var rendered = Mustache.render(template);
$('#block-container').append(rendered);
});
}
</script>
I am having an issue with alpacajs form not submitting data from a textbox if the user does not tab off the textbox before clicking the submit button, if the user has 5 fields to fill out all but the last one is included in the json results.
<div class="panel-group" id="accordian" role="tablist">
<div class="panel-placeholder"></div>
</div>
<div>
<button class="btn btn-default" type="submit">Submit</button>
</div>
<script id="panel-template" type="text/x-handlebars-template">
{{#each panels}}
<div class="panel panel-primary">
<div class="panel-heading">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#{{panelId}}">
{{title}}
</a>
</h4>
</div>
<div id="{{panelId}}" class="panel-collapse collapse in">
<div class="panel-body">
{{#each sections}}
<div id={{formId}}></div>
{{/each}}
</div>
</div>
</div>
{{/each}}
</script>
and the js code
function onData(formData) {
var friendlyData = "";
// Grab the template script
var templateScript = $("#panel-template").html();
// Compile the template
var compiledTemplate = Handlebars.compile(templateScript);
var compiledHtml = compiledTemplate(formData);
// Add the compiled html to the page
$('.panel-placeholder').html(compiledHtml);
//submit all data
$("[type='submit']").click(function () {
var postData = {
data: JSON.stringify(formData),
friendlyData: friendlyData,
storeData: storeData,
origUrl: origUrl
}
$.ajax({
url: apiUrl + "submit/",
data: postData,
dataType: 'json',
type: 'POST',
success: function (data) {
alert("Data was saved");
},
error: function (err) {
alert(err.statusText);
}
});
});
}
Any help with this would be great, I have not been able to find a solution.
Thank you
Currently I'm using the bootstrap theme config of dropzone.js, e.g. http://www.dropzonejs.com/bootstrap.html. What I want to achieve here is, add one input box to let the user input custom pic title, and another td in the table to show the response info(e.g. full link to the uploaded pic). After uploading done, send the pic title and pic link to another API endpoint to save them.
Tried to work with listening on addedFile and success but with no luck...The preview template is almost the same as in the docs. Really not skillful in HTML and Javascript. :(
<div class="table table-striped files" id="previews">
<div id="template" class="file-row">
<!-- This is used as the file preview template -->
<div>
<span class="preview"><img data-dz-thumbnail /></span>
</div>
<div>
<p class="name" data-dz-name></p>
<strong class="error text-danger" data-dz-errormessage></strong>
</div>
<div>
<p class="title">
<input type="text" name="title" id="title" placeholder="Input pic title or comment here!">
</p>
</div>
<div>
<!-- URL returned should be here? -->
<p id="fpurl" class="error text-danger"></p>
</div>
<div>
<p class="size" data-dz-size></p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress></div>
</div>
</div>
<div>
<button class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start</span>
</button>
<button data-dz-remove class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel</span>
</button>
<button data-dz-remove class="btn btn-danger delete">
<i class="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
</div>
</div>
</div>
JS code below:
var previewNode = document.querySelector("#template");
previewNode.id = "";
var previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);
var myDropzone = new Dropzone(document.body, {
url: "http://upload/file/url",
paramName: "fpfile",
thumbnailWidth: 80,
thumbnailHeight: 80,
headers: {"Cache-Control": null},
parallelUploads: 20,
previewTemplate: previewTemplate,
autoQueue: false, // Make sure the files aren't queued until manually added
previewsContainer: "#previews", // Define the container to display the previews
});
myDropzone.on("addedfile", function(file) {
// Hookup the start button
file.previewElement.querySelector(".start").onclick = function() { myDropzone.enqueueFile(file); };
});
// Update the total progress bar
myDropzone.on("totaluploadprogress", function(progress) {
document.querySelector("#total-progress .progress-bar").style.width = progress + "%";
});
myDropzone.on("success", function(file, response) {
var j = $.parseJSON(response);
var responseurl = $.parseJSON(j).url;
var fname = file.name;
// alert(file.name);
});
myDropzone.on("sending", function(file, xhr, data) {
// Auth info
data.append("Authorization", "Secret code here");
// Show the total progress bar when upload starts
document.querySelector("#total-progress").style.opacity = "1";
// And disable the start button
file.previewElement.querySelector(".start").setAttribute("disabled", "disabled");
});
// Hide the total progress bar when nothing's uploading anymore
myDropzone.on("queuecomplete", function(progress) {
document.querySelector("#total-progress").style.opacity = "0";
});
// Setup the buttons for all transfers
// The "add files" button doesn't need to be setup because the config
// `clickable` has already been specified.
document.querySelector("#actions .start").onclick = function() {
myDropzone.enqueueFiles(myDropzone.getFilesWithStatus(Dropzone.ADDED));
};
document.querySelector("#actions .cancel").onclick = function() {
myDropzone.removeAllFiles(true);
};
I'm trying to accomplish like this
Trying to show preview of the images that I want to upload, but nothing is showing up. I'm looking at my log and when I try to upload, the log is spitting out stuff, mostly Image Exists (0.2ms) and Image Load (0.3ms), and showing SELECT 1 AS.... SQL syntax
This is my form.html.erb
<%= simple_form_for #photo, html: { multipart: true, id: 'bePhoto' } do |f| %>
<div class="row fileupload-buttonbar">
<div class="col-lg-7">
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
<input type="file" name="photos[]" multiple>
</span>
<button type="submit" class="btn btn-primary start">
<i class="glyphicon glyphicon-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" class="btn btn-warning cancel">
<i class="glyphicon glyphicon-ban-circle"></i>
<span>Cancel upload</span>
</button>
<button type="button" class="btn btn-danger delete">
<i class="glyphicon glyphicon-trash"></i>
<span>Delete</span>
</button>
<input type="checkbox" class="toggle">
<!-- The global file processing state -->
<span class="fileupload-process"></span>
</div>
<!-- The global progress state -->
<div class="col-lg-5 fileupload-progress fade">
<!-- The global progress bar -->
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar progress-bar-success" style="width:0%;"></div>
</div>
<!-- The extended global progress state -->
<div class="progress-extended"> </div>
</div>
</div>
<!-- The table listing the files available for upload/download -->
<table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
<% end %>
Then I have this javascript
$(function () {
$('#bePhoto').fileupload();
$('#bePhoto').addClass('fileupload-processing');
$.ajax({
// Uncomment the following to send cross-domain cookies:
//xhrFields: {withCredentials: true},
url: $('#bePhoto').fileupload('option', 'url'),
dataType: 'json',
context: $('#beTripForm')[0]
}).always(function () {
$(this).removeClass('fileupload-processing');
}).done(function (result) {
$(this).fileupload('option', 'done')
.call(this, $.Event('done'), {result: result});
});
});
I also have this
<script src="http://blueimp.github.io/JavaScript-Templates/js/tmpl.min.js"></script>
<script src="http://blueimp.github.io/JavaScript-Load-Image/js/load-image.all.min.js"></script>
<script src="http://blueimp.github.io/JavaScript-Canvas-to-Blob/js/canvas-to-blob.min.js"></script>
<script src="http://blueimp.github.io/Gallery/js/jquery.blueimp-gallery.min.js"></script>
And this:
//= require jquery-fileupload/basic
//= require jquery-fileupload/basic-plus
I pretty much tried to mimic the sample demo, but not sure if I'm doing this correctly.
If your concern is to display the selected image before uploading and upload them during form submit I tried to write custom script for this.Please have a look and let me know.
Here I read the input file content and display them in image tag as thumbnail.It doesn't show the progress of file uploading but all the files are submitted during form submit event.
Please add a div to display the thumnail image just above the file input field
<div class="row" id="uploader-wrapper"></div>
<%= f.file_field(:photo, id: 'photo_upload_btn', multiple: true) %>
And add event listner for your file input field.
$("#photo_upload_btn").change(function () {
displayThumbnail(this);
});
Add the following Javasript code to display the Thumbnail
function displayThumbnail(input) {
for( var i = 0;i<input.files.length;i++){
if (input.files && input.files[i]) {
var reader = new FileReader();
reader.onload = function (e) {
if ($('#photo_upload_btn').valid()) {
var $newImageThumbnail = makeElement('img',{ class: "image-frame",src: e.target.result});
$('#uploader-wrapper').append($newImageThumbnail);
}
};
reader.readAsDataURL(input.files[i]);
}
}
}
function makeElement(element, options) {
var $elem = document.createElement(element);
$.each(options, function (key, value) {
$elem.setAttribute(key, value);
});
return $elem;
}
Also don't forget to style the thumbnail
.image-frame {
border: 1px dashed #333;
width: 150px;
height: 150px;
margin: 0 0 10px;
}