I'm having a problem sending the images have a text area field for the client to send a description of the photo, and when he sent to the database sends as if all had the same description that was being inserted only one description,
I'm using the library DROPZONE.JS http://dropzonejs.com/
Follow my code .. Help me please.
Dropzone.options.upload = {
thumbnailWidth: 246,
thumbnailHeight: 173,
enqueueForUpload:false,
paramName: "userfile",
sending: function(file, xhr, formData) {
formData.append("titulo", $("#titulo").val());
formData.append("evento", <?php echo $this->uri->segment(4); ?>);
formData.append("capa", $("#cap").val());
}
};
function upload() {
var dz = Dropzone.forElement("#upload");
for (var i = 0; i < dz.files.length; i++) {
dz.filesQueue.push(dz.files[i]);
}
dz.processQueue();
}
As stated there can only be one DOM element having an id in the whole document or you will have issues. This can be solved on the fly by adding the file name to the id of your text box field.
Add code for your text box in the previewTemplate
previewTemplate: "<div class=\"dz-preview dz-file-preview\"> ...
<input type=\"text\" class=\"titulo\" data-dz-titulo >
...
data-dz-errormessage></span></div>\n</div>"
When the previewTemplate is rendered by the addedfile function create an id called titulo + file.name to give your element a unique id. This can be done by adding a line of code in the addedfile function.
addedfile: function(file) {
file.previewElement = Dropzone.createElement(this.options.previewTemplate);
...
file.previewElement.querySelector("[data-dz-titulo]").id = "titulo" + file.name;
...
file.previewElement.querySelector("[data-dz-size]").innerHTML = this.filesize(file.size);
},
Now you will also have to use the file name to get the matching titulo in the sending function.
sending: function(file, xhr, formData) {
var filetitulo = document.getElementById('titulo' +file.name).value;
formData.append("titulo", filetitulo);
});
When you use $("#titulo") you refer to the input / textarea having the id of titulo.
For example <input type="text" id="titulo">.
There can only be one DOM element having an id in the whole document.
Change your element to <input type="text" class="titulo"> then you use something like $(".titulo")[0], $(".titulo")[1] to select the fields.
Related
I have inherited a legacy system that I need to maintain. This system has a fileupload using Dropify. When creating a new record, one can select an image file and it gets uploaded correctly. When editing the record, one can update a new image using this widget and it works fine too. Now what I want to do is, when editing the record, I want to be able to delete the existing uploaded image associated with the record. I am not sure how to do this.
When I mouseover the imageupload Dropify widget I get a "Remove" option shown, but clicking on it does not do anything. I checked the code and I found the following:
$(document).ready(function()
{
$('.dropify').dropify();
// Used events
var drEvent = $('.dropify-event').dropify();
drEvent.on('dropify.beforeClear', function(event, element) {
return confirm("Do you really want to delete \"" + element.filename + "\" ?");
});
drEvent.on('dropify.afterClear', function(event, element) {
alert('File deleted');
});
});
But clicking on the "Remove" on Dropify widget does not trigger neither the confirm nor the alert.
The dropify widget code itself is like follows:
<input
type="file"
name="image"
id="fileChooser"
class="dropify"
data-default-file="" />
The PHP file upload script in the backend looks pretty standard:
if ($_FILES['image']['name'])
{
$productId = getProductId();
$file_name = $productId . $_FILES['image']['name'];
$file_size = $_FILES['image']['size'];
$file_tmp = $_FILES['image']['tmp_name'];
$file_type = $_FILES['image']['type'];
$file_ext = strtolower(end(explode('.', $_FILES['image']['name'])));
move_uploaded_file($file_tmp, "uploads/product/" . $file_name);
}
It would be great to get some pointers on how to delete images using dropify.
Looks like you are missing the dropify-event class on your input tag. After adding that it works fine. But even without the class, deletion still worked, except it didn't have a fancy alert message. Maybe the snippet below, which works, can help you onto the right track.
$('.dropify').dropify();
// Used events
var drEvent = $('.dropify-event').dropify();
drEvent.on('dropify.beforeClear', function(event, element) {
return confirm("Do you really want to delete \"" + element.file.name + "\" ?");
});
drEvent.on('dropify.afterClear', function(event, element) {
alert('File deleted');
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/Dropify/0.2.2/css/dropify.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Dropify/0.2.2/js/dropify.min.js"></script>
<input type="file" name="image" id="fileChooser" class="dropify dropify-event" data-default-file="" />
I have one upload button to upload multiple files and each time i select file then jquery onchange is called and i can set only one value to hidden input .My question is how i can store all file names in hidden input value so i can store all file name in database.
<input type="hidden" name="croppedDocumentActivity[]" id="croppedDocumentActivity" value="" visibility="hidden">
$('#activityAddOrEditFile').on('change', function(){
var file = $("#activityAddOrEditFile")[0].files[0];
var fileTypes = ['jpg', 'jpeg', 'png', 'bmp', 'gif','pdf','docx'];
var a = new Array();
a.push(file.name);
$('#croppedDocumentActivity').val(a);
})
On your script, you can just call a function that will append a new hidden element inside the form. So when you submit the form, all of the newly added elements will be passed at the same time. Try something like this.
$('#activityAddOrEditFile').on('change', function(){
var file = $("#activityAddOrEditFile")[0].files[0];
appendSomething(file.name); //appends new hidden element
})
public function appendSomething(filename) {
$('#yourform').append('<input type="hidden" name="croppedDocumentActivity[]" value='+filename+'>');
}
im working on custom post in wordpress, in this custom post i wanna add many photos using wp_attachment the problem im having here is that when i click addmore nothing happen, its like if wordpress is ignoring my jquery file
my code
<div class="col-sm-9">
<input type="file" name="aduploadfiles[]" id="uploadfiles2" size="35" class="form-control" />
<input type="button" id="add_more2" class="upload" value="add more photo"/>
</div>
and this is the javascript im using
var abc = 0; //Declaring and defining global increement variable
$(document).ready(function() {
//To add new input file field dynamically, on click of "Add More Files" button below function will be executed
$('#add_more2').click(function() {
$(this).before($("<div/>", {id: 'uploadfiles2'}).fadeIn('slow').append(
$("<input/>", {name: 'aduploadfiles[]', type: 'file', id: 'aduploadfiles',size:'35', class:'form-control'})
));
});
//following function will executes on change event of file input to select different file
$('body').on('change', '#file', function(){
if (this.files && this.files[0]) {
abc += 1; //increementing global variable by 1
var z = abc - 1;
var x = $(this).parent().find('#previewimg' + z).remove();
$(this).before("<div id='abcd"+ abc +"' class='abcd'><img id='previewimg" + abc + "' src=''/></div>");
var reader = new FileReader();
reader.onload = imageIsLoaded;
reader.readAsDataURL(this.files[0]);
$(this).hide();
$("#abcd"+ abc).append($("<img/>", {id: 'img', src: 'x.png', alt: 'delete'}).click(function() {
$(this).parent().parent().remove();
}));
}
});
//To preview image
function imageIsLoaded(e) {
$('#previewimg' + abc).attr('src', e.target.result);
};
$('#upload').click(function(e) {
var name = $(":file").val();
if (!name)
{
alert("First Image Must Be Selected");
e.preventDefault();
}
});
});
this works fine when i try it in a wordpress pages but in dashboard itdoesn't want to work even my javascript is loaded
There are several issues:
1. $ is not available. Use jQuery
In WordPress, jQuery runs in compatibility mode, i.e. the $ shortcut is not available. You can solve this by capturing jQuery as function argument in the ready method, like this:
jQuery(document).ready(function($) {
The rest of the code in the ready callback can then continue to use $.
2. Wrong selector for file upload input element
You mentioned the wrong id in the jQuery selector: your file upload element has id uploadfiles2, not file. So change:
$('body').on('change', '#file', function(){
To:
$('body').on('change', '[name="aduploadfiles[]"]', function(){
3. Duplicate id values
Each time when you add a new button, you create a div with an id of uploadfiles2: but that id already exists. In HTML id values must be unique, otherwise unexpected things happen.
All the elements you create dynamically should get a dynamically created (distinct) id value (or no id at all).
I have the following code for multiple file input
<form action="" enctype = "multipart/form-data" method="post" name="login">
<input type = "file" name = "photo[]" id = "files" multiple onchange = "handleFileSelect(this.files)"/><br/>
<div id="selectedFiles"></div>
<input type="submit" value="Sign In">
</form>
The javascript equivalent function is.
selDiv = document.querySelector("#selectedFiles");
function handleFileSelect(e) {
if(!this.files) return;
selDiv.innerHTML = "";
var files = e;
for(var i=0; i<files.length; i++) {
var f = files[i];
selDiv.innerHTML += f.name + "<br/>";
}
}
What I am getting is upon uploading the second file. The FileList gets overwritten and instead of having 2 files, second file is present in the FileList. Here FileList is passed by this.files.
Also upon passing to the server only second image is passed. I have googled throughly but could not find answer. I would appreciate if anyone could help.
...multiple file input ... The FileList gets overwritten...
Actually that's how the HTML file input with the multiple attribute works—the user must select all the files they want to upload at once, using shift or control click. If the user operates the same file input upload process a second time anything selected prior is discarded and only the most recent selections remain in the FileList.
But isn't there any way for the user upload file multiple times.
To let your site users use an HTML file input element multiple times and keep all the previous selections, you'll need to write to hidden form elements the file (base64 data) received each time the file element is used.
For example:
<form action="process.php" method="post" name="uploadform" enctype="multipart/form-data">
// other form elements if needed
<input type="submit">
</form>
<!-- outside the form, you don't want to upload this one -->
<input type="file" id="upfiles" name="upfiles">
<script>
document.getElementById('upfiles').addEventListener('change', handle_files, false);
function handle_files(evt) {
var ff = document.forms['uploadform'];
var files = evt.target.files;
for ( var i = 0, file; file = files[i]; i++ ) {
var reader = new FileReader();
reader.onload = (function(file) {
return function (ufile) {
var upp = document.createElement('input');
upp['type'] = 'hidden';
upp['name'] = +new Date + '_upfile_' + file.name.replace(/(\[|\]|&|~|!|\(|\)|#|\|\/)/ig, '');
upp.value = ufile.target.result;
ff.appendChild(upp);
}
}(file));
reader.readAsDataURL(file);
}
}
</script>
Next, you need to write a script to run on the server to process the hidden base64 fields. If using PHP you can:
<?php
$path = 'path/to/file/directory/';
// this is either:
// - the absolute path, which is from server root
// to the files directory, or
// - the relative path, which is from the directory
// the PHP script is in to the files directory
foreach ( $_POST as $key => $value ) { // loop over posted form vars
if ( strpos($key, '_upfile_') ) { // find the file upload vars
$value = str_replace(' ', '+', $value); // url encode
file_put_contents($path.$key, base64_decode($value));
// convert data to file in files directory with upload name ($key)
}
}
?>
I ran into the same problem. Thanks for the question and answer. I managed to add several files by adding to the DOM input type file and delegating the click to the detached element :
<form method="POST" enctype="multipart/form-data" action="/echo/html">
<button class="add">
Add File
</button>
<ul class="list">
</ul>
<button>
Send Form
</button>
</form>
With the javascript :
$('form button.add').click(function(e) {
e.preventDefault();
var nb_attachments = $('form input').length;
var $input = $('<input type="file" name=attachment-' + nb_attachments + '>');
$input.on('change', function(evt) {
var f = evt.target.files[0];
$('form').append($(this));
$('ul.list').append('<li class="item">'+f.name+'('+f.size+')</li>');
});
$input.hide();
$input.trigger('click');
});
It is working with Edge, Chrome 50 and firefox 45, but I don't know the compatibility with older versions or other browsers.
See the this fiddle.
I want to list selected file from file input.
<div class="fileUpload myButton">
<span>Upload</span>
<input type="file" name="imageURL[]" id="imageURL" multiple="" class="file" />
</div>
<div id="file-list">
</div>
I have this code
(function () {
var filesUpload = document.getElementById("imageURL"),z
fileList = document.getElementById("file-list");
function uploadFile (file) {
var li = document.createElement("li"),
div = document.createElement("div"),
reader,
xhr,
fileInfo;
li.appendChild(div);
// Present file info and append it to the list of files
fileInfo = "<div class=\"neutral\">File: <strong>" + file.name + "</strong> with the size <strong>" + parseInt(file.size / 1024, 10) + "</strong> kb is in queue.</div>";
div.innerHTML = fileInfo;
fileList.appendChild(div);
}
function traverseFiles (files) {
if (typeof files !== "undefined") {
for (var i=0, l=files.length; i<l; i++) {
uploadFile(files[i]);
}
}
else {
fileList.innerHTML = "<div class=\"neutral\">Your browser does not support Multiple File Upload, but you can still upload your file. We recommend you to upload to a more modern browser, like Google Chrome for example.<div>";
}
}
filesUpload.addEventListener("change", function () {
traverseFiles(this.files);
}, false);
})();
But the problem is when the user selects another files it is added to the list but the old files is not uploaded when the form is submitted.
Simplified: when the user selects file1.pdf and file2.pdf
The list shows file1.pdf and file2.pdf
When he selects again another files file3.pdf and file4.pdf
the list shows file1.pdf , file2.pdf, file3.pdf and file4.pdf
But when he submit the form only file3.pdf and file4.pdf is uploaded
My question is how to remove the files which will not be uploaded from the list.
OR a way to upload all the files in the list.
Thanks in advance.
What is happening is that the input is emptied when selecting more files, hence not uploading the previously displayed files.
SOLUTION 1: To combat this you could create a new input in the change event handler, although this could get quite messy.
You would have to get all files from all the inputs on upload. You have not shown your actual upload code, so I cannot give an example in context:
filesUpload.on("change", function () {
traverseFiles(this.files); //Add initial files to list
create_new_input();
}
function create_new_input() {
var new_input = $('<input type="file" />'); //create file selector
new_input.on("change", function() {traverseFiles($(this).get(0).files);}); //
$('body').append(new_input); //Add this input to your page
}, false);
You will have to add all files that you receive in the traverseFilesto the xhr. This example uses jQuery, and I would recommend that you use it all the time!
SOLUTION 2:
Other wise you can empty the file list box on input changed:
filesUpload.addEventListener("change", function () {
document.getElementById('file-list').innerHTML = "";
traverseFiles(this.files);
}, false);
Good luck!
Your Problem is that you manipulate the value of input multiple times. The second time someone selects a file using the html file input, the originally selected files are "overwritten" from the inputs value attribute.
You could hook into your forms submit and add the files you already stored in your html.
Another way to do it would be to work with several file input elements.
So every time someone selects files and you add them to your html, hide the old file input and add a new one like this ...
adjust your html code like this:
<div class="fileUpload myButton">
<span>Upload</span>
<input type="file" class="imageUrlInput" name="imageURL[0]" id="imageURL" multiple="" class="file" />
</div>
<div id="file-list">
</div>
Adjust your Javascript like this:
function uploadFile (file) {
var li = document.createElement("li"),
div = document.createElement("div"),
reader,
xhr,
fileInfo;
li.appendChild(div);
// now here we receive the HTML input element for the files.
var currentInput = $('#imageURL');
var imageUrlInputsCount = $('.imageUrlInput').length;
// now we change the 'id' attribute of said element because id's should be unique right?
currentInput.attr('id','imageUrl_'+imageUrlInputsCount);
// now, we append a new input element with an incremented array key defined by the length of already existing input elements
currentInput.append('<input type="file" name="imageURL['+imageUrlInputsCount+']" id="imageURL" multiple="" class="file" />');
// and finally we hide the old element
currentInput.hide();
// Present file info and append it to the list of files
fileInfo = "<div class=\"neutral\">File: <strong>" + file.name + "</strong> with the size <strong>" + parseInt(file.size / 1024, 10) + "</strong> kb is in queue.</div>";
div.innerHTML = fileInfo;
fileList.appendChild(div);
}
Now make sure that in your retrieving server code (php/jsp/asp,node.js or whatever you are using) you change checking for imageURL, you iterate over imageURL since now you have several sets of imageURLs. i.e. your imageURL parameter could look like this:
imageURL = array (
0 => array(
'foo1.pdf',
'foo2.pdf',
'foo3.pdf',
),
1 => array(
'foo4.pdf',
'foo5.pdf',
'foo6.pdf',
)
3 => array(
'foo7.pdf',
'foo8.pdf',
'foo9.pdf',
)
)