Filemask using new dojo Uploader - javascript

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");
},

Related

Delete uploaded image using Dropify

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="" />

Error on javascript queryselector

I'm trying to input an URL Parameter into a form input. When I'm trying to do it via the inspect console, everything seems fine. But when I load the page I got an error: Uncaught TypeError: Cannot set property 'value' of null.
Here the main javascript
function getParameterByName(name)
{
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if(results == null)
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
my input looks like this... There is a part of the ID that randomly changes on reload, only satisfaction_case_number stay the same.
<input id="satisfaction_case_number-da4e00e8-dcf6-4efa-9f92-d9564432f979_2621" class="hs-input" type="text" name="satisfaction_case_number" value="" placeholder="" data-reactid=".hbspt-forms-0.0:$0.$satisfaction_case_number.0">
I tried 2 functions call.
document.getElementByName("satisfaction_case_number").value = getParameterByName("case")
and
document.querySelector('[id^="satisfaction_case_number"]').value = getParameterByName("case")
I have to say I'm kinda blind here. Any flag would be appreciated.
Here is the URL of my page : http://info.techo-bloc.com/customer-service-0?case=CAS-00745-Z0G5F8.
I'm trying to get : CAS-00745-Z0G5F8 into the input.
Thanks
Wait till the window has loaded then execute it;
window.onload = function () {
document.getElementsByName("satisfaction_case_number")[0].value = getParameterByName('case');
}
The form is being dynamically generated after the rest of your content has loaded, It's unreliable to rely on timing as connection speeds can vary, using
window.onload will ensure the page is fully loaded before executing.
I tested this by throttling my browser connection to "Slow 3G" and it still worked, Your original piece of code that selected the element by name wasn't selecting the first entry in the NodeList, to do this you need to add [0] before the .value
You can try document.querySelector('input[id *= satisfaction_case_number]').value = 'example'
setTimeout(function () {
var input = document.querySelector('[id^="satisfaction_case_number"]');
input.value = getParameterByName('case');
input.dispatchEvent(new Event('change'));
}, 1000);
or try to modify the code that creates HubSpot form:
hbspt.forms.create({
// ...
onFormReady: function () {
var input = document.querySelector('[id^="satisfaction_case_number"]');
input.value = getParameterByName('case');
input.dispatchEvent(new Event('change'));
}
});

add more button dont work in wordpress dashboard

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).

Dimensions validation for image client side

The website that I'm working on has an option to upload images, but I must validate the image's dimensions (width, height) before uploading to the server side or before submitting.
For example the image must be 250x250, otherwise an alert occurs and the user can't upload the image, here's a part of my code:
<form action="upload_file.php" method="post" enctype="multipart/form-data" name = "upload" id="insertBook" onSubmit="return validateImage();">
<input type="file" name="image" value="upload" id = "myImg">
<input type="submit" name = "submit">
</form>
validateImage function now just checks for the extensions, I want it also to check for the dimensions.
Here's the code so far:
function validateImage(){
var allowedExtension = ["jpg","jpeg","gif","png","bmp"];
var fileExtension = document.getElementById('myImg').value.split('.').pop().toLowerCase();
var isValidFile = false;
for(var index in allowedExtension) {
if(fileExtension === allowedExtension[index]) {
isValidFile = true;
break;
}
}
if(!isValidFile) {
alert('Allowed Extensions are : *.' + allowedExtension.join(', *.'));
}
return isValidFile;
}
Thank you! :)
function validateImage(){
var isValidFile = false;
var image = document.getElementById('myImg');
var allowedExtension = ["jpg","jpeg","gif","png","bmp"];
var srcChunks = image.src.split( '.' );
var fileExtension = srcChunks[ srcChunks.length - 1 ].toLowerCase();
if ( image.width !== image.height !== 250 ) {
console.log( 'Size check failed' );
return false;
}
for(var index in allowedExtension) {
if(fileExtension === allowedExtension[index]) {
isValidFile = true;
break;
}
}
if(!isValidFile) {
alert('Allowed Extensions are : *.' + allowedExtension.join(', *.'));
}
return isValidFile;
}
Related to this topic
As I said in my comment, you can check for the size on the client-side but it's unsafe as the javascript may be bypassed, and your validation would serve no purpose. If someone really wants to upload a file that is 5Go, he just have to redefine your check function.
A server side validation isn't accessible by the client. Moreover depending on your backend and your image handling (Are you handling it like a simple file ? Or do you have some lib to work with images ?), you may find some methods to help you with image dimensions. For example in python I use PIL (Pillow for 3.x version) to check for image information, size, dimension, content, check if it's a real file or not... Actually it's really easy to upload a corrupted file that contains some php code in it (for example) so you should be really careful when you let users upload content to your server.

List selected files from file input

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',
)
)

Categories

Resources