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="" />
Related
In this, I have a give module (wordpress plugin for fundraiser) and I have integrated the file upload
https://www.mamafrica.it/26964-2/
I have add a java script in order to check the file size and file type, but this work only until I not change the payment method.
For example:
After load page, if I load file > 500KB or different from pdf or jpg, error message appears under the file upload area.
If I switch to "Donation by bank transfer" the form change (an information text appears before file upload area and the form fields are cleaning).
Now, if I choose another file > 500KB (or not pdf or jpg) the error message not appears.
The 'change', function in javascript is not invoked.
This is the javascript
<script>
var inputElement = document.getElementById("fileToUpload")
inputElement.addEventListener('change', function(){
alert("QUI");
var error = 0;
var fileLimit = 500; // In kb
var files = inputElement.files;
var fileSize = files[0].size;
var fileSizeInKB = (fileSize/1024); // this would be in kilobytes defaults to bytes
var fileName = inputElement.value;
idxDot = fileName.lastIndexOf(".") + 1;
extFile = fileName.substr(idxDot, fileName.length).toLowerCase();
document.getElementById("error").innerHTML = "";
document.getElementById("filenamecheck").innerHTML = inputElement.value;
if (extFile=="jpg" || extFile=="pdf"){
console.log("Type ok");
} else {
error = 1;
document.getElementById("error").innerHTML = "Solo file .pdf o .jpg";
document.getElementById("fileToUpload").value = "";
}
if (error == 0) {
if(fileSizeInKB < fileLimit) {
console.log("Size ok");
} else {
console.log("Size not ok");
document.getElementById("error").innerHTML = "Massima grandezza file: " + fileLimit + "KB";
document.getElementById("fileToUpload").value = "";
}
}
})
</script>
This the file upload area
<div class="file-uploader">
<input id="fileToUpload" name="fileToUpload" type="file" accept=".pdf,.jpg"/>
<label for="file-upload" class="custom-file-upload">
<i class="fas fa-cloud-upload-alt"></i>Clicca per scegliere il file
<span name="filenamecheck" id="filenamecheck">test</span>
</label>
<p id="error" style="color: #c00000"></p>
</div>
Someone can help me?
UPDATE: The correct URL is https://www.mamafrica.it/26964-2/
UPDATE SOLVE
I have found a solution for my problem!!
First time, I have insert the javascript code after the end of form tag and the refresh work only on elements inside of form tag.
Using a wordpress hook (in function.php) i have insert the javascrip code immediatly after the input tag, inside of the form tag, in this way, the form refresh, reload also the javascript.
Thank you all!
Regards,
Marco
UPDATE
I have found a solution for my problem!!
First time, I have insert the javascript code after the end of form tag and the refresh work only on elements inside of form tag. Using a wordpress hook (in function.php) i have insert the javascrip code immediatly after the input tag, inside of the form tag, in this way, the form refresh, reload also the javascript.
Thank you all!
Could be that you are using:
inputElement.addEventListener
That might be only triggered once.
You might use something in a form as simple as:
onSubmit="return MyFunctionName"
That is being used in form validation for years.
I hope this helps,
Ramon
I'm looking for a plugin which allows adding multiple images, previewing, removing and submitting with some extra fields without ajax.
i have found some very good plugins like fineUploader and dropzone but they submit with ajax. with these plugins i haven't figured out how to submit without ajax.
I'm looking for a plugin which allows adding multiple images, previewing, removing and submitting with some extra fields without
ajax.
multiple images ----> <input type='file' id="myfiles" multiple="multiple" name="files[]">
previewing ---> Jquery
removing-----> Highly impossible to remove one by one image from file list,as the api is read only,however we can clear the entire file list, when the remove button is clicked.
without ajax ----> Just action the form to the controller/handler.
I don't think there's a way to achieve what you need beside using one of the plugins you have mentioned above.
You have 2 Options that I can think of currently.
use the multiple attribute on the file input type, then u can be able to use jquery to preview the images that are loaded but however we can not remove the image one by one from the filelist we can only remove the image from the preview but the server side still gonna process the image, or we can just clear the entire filelist, as I have mentioned above.
OR
we can add the file field dynamically using jquery, in this way we can be able to add one image add a time, then have an add more images button that will append a new file input to our form, with this we will be able to remove images one by one before processing in the server side.
Option 1
$('document').ready(function() {
var images = function(input, imgPreview) {
if (input.files) {
var filesAmount = input.files.length;
for (i = 0; i < filesAmount; i++) {
var reader = new FileReader();
reader.onload = function(event) {
$($.parseHTML("<img class='pic'>")).attr('src', event.target.result).appendTo(imgPreview);
}
reader.readAsDataURL(input.files[i]);
}
}
};
$('#myimg').on('change', function() {
images(this, '#previews');
});
//clear the file list when image is clicked
$('body').on('click','img',function(){
$('#myimg').val("");
$('#previews').html("");
});
});
img{
cursor: pointer;
}
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<form id="form1" enctype="multipart/form-data" action="server.php" method="post">
<input type='file' id="myimg" multiple="multiple">
<div id="previews"></div>
<p> </p>
<button type="submit">Submit</button>
</form>
Option 2
var abc = 0;
$('#add_more').click(function ()
{
$(this).before($("<div/>",{id: 'filediv'}).fadeIn('slow').append($("<input/>",
{
name: 'file[]',
type: 'file',
id: 'file'
}),
$("<br/><br/>")
));
});
$('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', //the remove icon
alt: 'delete'
}) .click(function ()
{
$(this)
.parent()
.parent()
.remove();
}));
}
});
//image preview
function imageIsLoaded(e)
{
$('#previewimg' + abc)
.attr('src', e.target.result);
};
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<form method="POST" action="server.php" enctype="multipart/form-data">
<div class="col-md-3 col-sm-3 col-xs-3">
<div id="filediv"><input name="file[]" type="file" id="file"/></div>
<input type="button" id="add_more" class="btn btn-primary" value="Add More Files"/><br><br>
<button type="submit" class="btn btn-success">Submit</button>
</form>
I believe this more esp option 2 can do the trick, select image, add more preview delete, then when u are happy hit the submit button then do your processing on the server. You might add styling to the preview images
Goodluck.
You can use DropzoneJS
They have a list of configurable options that you can find here. Dropzone JS Usage.
If you still need more customization then you will have to add your own code to it. Hope this helps you from writing thousand lines of code.
Without AJAX requests:
This may help you. Click here!
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',
)
)
I created a DOJO browse button to upload files to the server . The button works fine . However i would like to be able to restrict my file selection to *.jpg files only . In DOJO dojox.form.FileUploader i could use the Filemask attribute to select / mask files to be uploaded to the server . Example :
var fileMask = ["Images", "*.jpg;*.jpeg;*.gif;*.png"]
var uploader = new dojox.form.FileUploader({
button:dijit.byId("myFakeButton"),
uploadUrl:uploadUrl,
fileMask:fileMask
});
However dojox.form.FileUploader is now deprecated ( soon to be deprecated ) and replaced by dojo.form.uploader . In this i am unable to find any property that can mimic the filemast capability . I read the official Dojo Uploader documenation but it does not mention anything about filemask .
Anyone faced this issue ?
dojox.form.Uploader generated a DOM Element temporarily to deal with file uploading operation. so we could track the DOM generated with dojo.aspect like this:
var uploader = new Uploader({...}, ...);
aspect.after(uploader._inputs, "push", function(method, args) {
args[0].accept = "image/jpg,image/jpeg,image/gif,image/png";
});
You can set the type by the accept attribute and configure it using the mime type.
dojo.require("dojox.form.Uploader");
var tbl = document.getElementById('hola');
var fileInput = document.createElement('input');
fileInput.type = 'file'; //fallback
fileInput.setAttribute("data-dojo-type", "dojox.form.Uploader");
fileInput.setAttribute('accept', 'image/jpeg');
fileInput.setAttribute('data-dojo-props', 'name:"uploadedfile", label:"Select Some Files"');
tbl.appendChild(fileInput);
div {
border: 1px;
border-style: dashed;
}
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<script src="http://amd.egoworx.com/jsfiddle-dojo-require.js"></script>
<link href="http://ajax.googleapis.com/ajax/libs/dojo/1.8/dijit/themes/claro/claro.css" rel="stylesheet" />
<div id="hola"></div>
Or override Uploader._createInput
Just add one line:
accept : ".xls,.xlsx,.xlsm,.csv" // Just add the line
like this
_createInput: function(){
alert("_createInput 1");
if(this._inputs.length){
domStyle.set(this.inputNode, {
top:"500px"
});
this._disconnectButton();
this._nameIndex++;
}
alert("_createInput 2");
var name = this._getFileFieldName();
alert("_createInput 3");
// reset focusNode to the inputNode, so when the button is clicked,
// the focus is properly moved to the input element
alert("_createInput 4");
this.focusNode = this.inputNode = domConstruct.create("input", {type:"file", name:name, "aria-labelledby":this.id+"_label",
accept : ".xls,.xlsx,.xlsm,.csv" // Just add the line
}, this.domNode, "first");
alert("_createInput 5");
if(this.supports("multiple") && this.multiple){
domAttr.set(this.inputNode, "multiple", true);
}
alert("_createInput 6");
this._inputs.push(this.inputNode);
alert("_createInput 7");
domStyle.set(this.inputNode, {
position:"absolute",
fontSize:this.inputNodeFontSize+"em",
top:"-3px",
right:"-3px",
opacity:0
});
alert("_createInput 8");
this._connectButton();
alert("_createInput 9");
},
I have a form stored in a javascript variable below:
var $fileImage = $("<form action='imageupload.php' method='post' enctype='multipart/form-data' target='upload_target' onsubmit='startImageUpload(this);' class='imageuploadform' >" +
"<label> Image File: <input name='fileImage' type='file' class='fileImage' /></label><br/>" +
"<input type='submit' name='submitImageBtn' class='sbtnimage' value='Upload' /></label></form>
Now as you can see when the user clicks on the submit button, it submits to the 'startImageUpload' function which is below:
function startImageUpload(imageuploadform){
$(imageuploadform).find('.imagef1_upload_process').css('visibility','visible');
$(imageuploadform).find('.imagef1_upload_form').css('visibility','hidden');
sourceImageForm = imageuploadform;
return true;
}
What it does is that when the user clicks on submit, it displays a loading bar and uploads the form.
Now what my question is that I want to perform a simple javascript validation where when the user clicks on the submit button in the form, it will check if the file either a 'png' or 'gif' file type. If it is correct file type, then display the loading bar and upload the form. If the file type is incorrect, then show a n alert stating file type is incorrect but don't show the loading bar and do not upload the form.
Does anyone know how this can be coded. It is so I can use the example from one of your answers to then expand on it and use the javascript to validate on more file types and also file size so it will be very helpful if somebody can please help me.
Thank You
function startImageUpload(imageuploadform){
var form = $(imageuploadform)
, value = form.find('.fileImage').val()
form.find('.imagef1_upload_process').css('visibility','visible')
form.find('.imagef1_upload_form').css('visibility','hidden')
if (!/\.(png|gif)$/.test(value)){
return false
}
return true
}
The HTML specification also evolved to include an accept attribute:
<input type="file" accept="image/png,image/gif" />
(supported in Chrome, Firefox and Opera - IE10, Safari 6 in the near future)
You can check like so...
var validExtensions = ['png', 'gif'],
validExtensionSupplied = $.inArray(
($('.fileImage').val().match(/\.(.*?)]\s*$/) || [])[1],
validExtensions) != -1;
Alternatively, you can validate by MIME type by checking the $('.fileImage').prop('files')[0].type.
Try this:
$("#pic").change(function() {
var val = $(this).val();
switch(val.substring(val.lastIndexOf('.') + 1).toLowerCase()){
case 'gif': case 'jpg': case 'png':
alert("an image");
break;
default:
$(this).val('');
// error message here
alert("not an image");
break;
}
});
This is my Solution, it is quite Easy and Fast
var accept = $(event.target).attr('accept');
//<input name='fileImage' accept='.png,.jpg,.jpeg' type='file' class='fileImage' />
value = $(event.target).val(), ext = value.substring(value.lastIndexOf('.'));
if(ext && accept.indexOf(ext) == -1){
console.log('No');
}