how to get data length inside Files ? i need data length to make alert maximize file
I want to limit the maximum upload of image files by adding alerts to the following code
the alert is alert("You Have Reached The MAXIMUM Upload Limit"); so when I add one by one upload image to the specified limit, an alert will appear
i want to get data length after click upload one by one but the data length is always 0 why ?
html
<div class="files col-sm-4" id="files1">
<input type="file" name="files1" id="imageten" multiple />
<br />Selected files:
<ol class="fileList"></ol>
</div>
script
$.fn.fileUploader = function (filesToUpload) {
this.closest(".files").change(function (evt) {
for (var i = 0; i < evt.target.files.length; i++) {
filesToUpload.push(evt.target.files[i]);
};
var output = [];
for (var i = 0, f; f = evt.target.files[i]; i++) {
var removeLink = "<i class=\"fa fa-times fa-close removeFile\" href=\"#\" data-fileid=\"" + i + "\"></i>";
output.push("<li><strong>", escape(f.name), "</strong> ", removeLink, " </li> ");
}
$(this).children(".fileList").append(output.join(""));
console.log(evt.target.files);
});
};
var filesToUpload = [];
$(document).on("click",".removeFile", function(e){
e.preventDefault();
var fileName = $(this).parent().children("strong").text();
for(i = 0; i < filesToUpload.length; ++ i){
if(filesToUpload[i].name == fileName){
filesToUpload.splice(i, 1);
console.log(filesToUpload);
}
}
$(this).parent().remove();
});
There is no variable named data in your code. I did not understood where you are returning 0. But, if my guess is correct, add this line inside $(document).on("click",".removeFile", function(e){
$(this).children(".fileList").append(output.join(""));
console.log(evt.target.files);
alert(evt.target.files.length); // add this line
$("#fileinput")[0].files.length will give the number of files.
if($("#fileinput")[0].files.length > 2) {
alert("You can select only 2 files");
}
Let me know if this is helpful.
How to limit the maximum files chosen when using multiple file input - There are already questions like this on stackoverflow.
Related
I'm trying to upload multiple pdf files using php, but the following code is allowing to upload only img, png....I have added application/pdf but only one PDF file is being uploaded, not multiple. I want to upload multiple PDF files same as this code is uploading accepted files, selecting one by one and all at once.
Can you please help me to upload multiple pdf files and upload in sql?
Thank you.
<div>
<label style="font-size: 14px;">
<span style='color:navy;font-weight:bold'>Attachment Instructions :</span>
</label>
<ul>
<li>
Allowed only files with extension (jpg, png, gif)
</li>
<li>
Maximum number of allowed files 10 with 300 KB for each
</li>
<li>
you can select files from different folders
</li>
</ul>
<!--To give the control a modern look, I have applied a stylesheet in the parent span.-->
<span class="btn btn-success fileinput-button">
<span>Select Attachment</span>
<input type="file" name="files[]" id="files" multiple accept="image/jpeg, image/png, image/gif,"><br />
</span>
<output id="Filelist"></output>
</div>
document.addEventListener("DOMContentLoaded", init, false);
//To save an array of attachments
var AttachmentArray = [];
//counter for attachment array
var arrCounter = 0;
//to make sure the error message for number of files will be shown only one time.
var filesCounterAlertStatus = false;
//un ordered list to keep attachments thumbnails
var ul = document.createElement("ul");
ul.className = "thumb-Images";
ul.id = "imgList";
function init() {
//add javascript handlers for the file upload event
document
.querySelector("#files")
.addEventListener("change", handleFileSelect, false);
}
//the handler for file upload event
function handleFileSelect(e) {
//to make sure the user select file/files
if (!e.target.files) return;
//To obtaine a File reference
var files = e.target.files;
// Loop through the FileList and then to render image files as thumbnails.
for (var i = 0, f; (f = files[i]); i++) {
//instantiate a FileReader object to read its contents into memory
var fileReader = new FileReader();
// Closure to capture the file information and apply validation.
fileReader.onload = (function(readerEvt) {
return function(e) {
//Apply the validation rules for attachments upload
ApplyFileValidationRules(readerEvt);
//Render attachments thumbnails.
RenderThumbnail(e, readerEvt);
//Fill the array of attachment
FillAttachmentArray(e, readerEvt);
};
})(f);
// Read in the image file as a data URL.
// readAsDataURL: The result property will contain the file/blob's data encoded as a data URL.
// More info about Data URI scheme https://en.wikipedia.org/wiki/Data_URI_scheme
fileReader.readAsDataURL(f);
}
document
.getElementById("files")
.addEventListener("change", handleFileSelect, false);
}
//To remove attachment once user click on x button
jQuery(function($) {
$("div").on("click", ".img-wrap .close", function() {
var id = $(this)
.closest(".img-wrap")
.find("img")
.data("id");
//to remove the deleted item from array
var elementPos = AttachmentArray.map(function(x) {
return x.FileName;
}).indexOf(id);
if (elementPos !== -1) {
AttachmentArray.splice(elementPos, 1);
}
//to remove image tag
$(this)
.parent()
.find("img")
.not()
.remove();
//to remove div tag that contain the image
$(this)
.parent()
.find("div")
.not()
.remove();
//to remove div tag that contain caption name
$(this)
.parent()
.parent()
.find("div")
.not()
.remove();
//to remove li tag
var lis = document.querySelectorAll("#imgList li");
for (var i = 0; (li = lis[i]); i++) {
if (li.innerHTML == "") {
li.parentNode.removeChild(li);
}
}
});
});
//Apply the validation rules for attachments upload
function ApplyFileValidationRules(readerEvt) {
//To check file type according to upload conditions
if (CheckFileType(readerEvt.type) == false) {
alert(
"The file (" +
readerEvt.name +
") does not match the upload conditions, You can only upload jpg/png/gif files"
);
e.preventDefault();
return;
}
//To check file Size according to upload conditions
if (CheckFileSize(readerEvt.size) == false) {
alert(
"The file (" +
readerEvt.name +
") does not match the upload conditions, The maximum file size for uploads should not exceed 300 KB"
);
e.preventDefault();
return;
}
//To check files count according to upload conditions
if (CheckFilesCount(AttachmentArray) == false) {
if (!filesCounterAlertStatus) {
filesCounterAlertStatus = true;
alert(
"You have added more than 10 files. According to upload conditions you can upload 10 files maximum"
);
}
e.preventDefault();
return;
}
}
//To check file type according to upload conditions
function CheckFileType(fileType) {
if (fileType == "image/jpeg") {
return true;
} else if (fileType == "image/png") {
return true;
} else if (fileType == "image/gif") {
return true;
} else {
return false;
}
return true;
}
//To check file Size according to upload conditions
function CheckFileSize(fileSize) {
if (fileSize < 300000) {
return true;
} else {
return false;
}
return true;
}
//To check files count according to upload conditions
function CheckFilesCount(AttachmentArray) {
//Since AttachmentArray.length return the next available index in the array,
//I have used the loop to get the real length
var len = 0;
for (var i = 0; i < AttachmentArray.length; i++) {
if (AttachmentArray[i] !== undefined) {
len++;
}
}
//To check the length does not exceed 10 files maximum
if (len > 9) {
return false;
} else {
return true;
}
}
//Render attachments thumbnails.
function RenderThumbnail(e, readerEvt) {
var li = document.createElement("li");
ul.appendChild(li);
li.innerHTML = [
'<div class="img-wrap"> <span class="close">×</span>' +
'<img class="thumb" src="',
e.target.result,
'" title="',
escape(readerEvt.name),
'" data-id="',
readerEvt.name,
'"/>' + "</div>"
].join("");
var div = document.createElement("div");
div.className = "FileNameCaptionStyle";
li.appendChild(div);
div.innerHTML = [readerEvt.name].join("");
document.getElementById("Filelist").insertBefore(ul, null);
}
//Fill the array of attachment
function FillAttachmentArray(e, readerEvt) {
AttachmentArray[arrCounter] = {
AttachmentType: 1,
ObjectType: 1,
FileName: readerEvt.name,
FileDescription: "Attachment",
NoteText: "",
MimeType: readerEvt.type,
Content: e.target.result.split("base64,")[1],
FileSizeInBytes: readerEvt.size
};
arrCounter = arrCounter + 1;
}
I have a multi-upload for image files, and the problem that I used to face was that the images are appearing in a different sequence as the user's input. For example, user selects Img1, Img2, Img3, Img4. The sequence that it appears might be Img2, Img4, Img3, Img1.
This causes a problem as I have to link them to a text field (image description), and each text field has to match the right image. I did some digging and found out that i can use this code here to make sure that it is being uploaded in the same sequence:
html
<input id="uploadfiles" multiple="multiple" name="photos" type="file">
javascript
$("#uploadfiles").change(function(){
imgpreview(document.getElementById('uploadfiles').files);
});
function imgpreview(files) {
var count = 0;
for (var i = 0, f; f = files[i]; i++) {
(function () {
var div = $("<div></div>");
var reader = new FileReader();
$(".display").append(div);
reader.onload = function(e) {
div.append("<img id='photocount" + count + "' src='" + e.target.result + "' style='height:40px;width:auto;'></img>");
count++;
};
reader.readAsDataURL(f);
}());
}
}
It is also available in fiddle here: https://jsfiddle.net/L3d1L9t3/1/
This javascript code here ensures that the images are appearing in sequence. However, the id for the images are still not in order. For example, if 4 images are uploaded, the ids should be photocount0, photocount1, photocount2, photocount3 respectively. But this is not the case when i inspect element on each of the images.
How do i ensure that the "count" is in sequence as well? This is important since i need to match the count to the text field (image description) as well ["image 1" is paired with "image description 1", "image 2" is paired with "image description 2" and so on]
Use URL.createObjectURL(file) instead it's both faster and easier since it's sync - you don't have to encode/decode back and fort to/from base64 then
$("#uploadfiles").change(function() {
// imgpreview(document.getElementById('uploadfiles').files); <-- not needed
imgpreview(this.files)
})
function imgpreview(files) {
var url, div, len = files.length
var $display = $(".display")
for (var i = 0; i < len; i++) {
url = URL.createObjectURL(files[i])
div = $('<div>')
$display.append(div)
div.append("<img id='photocount" + i + "' src=" + url + " style='height:40px;width:auto'>")
}
}
I'm trying to create a form where I can have multiple file upload sections, where the user can upload multiple files.
That part, is reasonably straight forward. My problem comes from allowing the user to 'remove' a file from the upload list, before it's uploaded.
I've created a fiddle to illustrate
http://jsfiddle.net/alexjamesbrown/o62srbew/
I've got a simple row, that holds the <input type="file"
<div class="row files" id="files1">
<h2>Files 1</h2>
<span class="btn btn-default btn-file">
Browse <input type="file" name="files1" multiple />
</span>
<br />
<ul class="fileList"></ul>
</div>
then, so far, I've created a jquery plugin so it's re-usable:
$.fn.fileUploader = function (filesToUpload) {
this.closest(".files").change(function (evt) {
for (var i = 0; i < evt.target.files.length; i++) {
filesToUpload.push(evt.target.files[i]);
};
var output = [];
for (var i = 0, f; f = evt.target.files[i]; i++) {
var removeLink = "Remove";
output.push("<li><strong>", escape(f.name), "</strong> - ",
f.size, " bytes. ", removeLink, "</li> ");
}
$(this).children(".fileList")
.append(output.join(""));
});
};
I'm then initialising my very basic plugin like this:
var filesToUpload = [];
$("#files1").fileUploader(filesToUpload);
$("#files2").fileUploader(filesToUpload);
$("#uploadBtn").click(function (e) {
e.preventDefault();
});
As in this JSFiddle, I've added a class name .removeFile to the dynamically generated remove link; then use this class as a selector to pick up the one which is clicked and remove the parent li.
Updated:
JS:
// add .removeFile class to the li's element to pick them by this selector
var removeLink = "<a class=\"removeFile\" href=\"#\" data-fileid=\"" + i + "\">Remove</a>";
output.push("<li><strong>", escape(f.name), "</strong> - ",
f.size, " bytes. ", removeLink, "</li> ");
}
$(this).children(".fileList")
.append(output.join(""));
});
};
var filesToUpload = [];
$(document).on("click",".removeFile", function(e){
e.preventDefault();
var fileName = $(this).parent().children("strong").text();
// loop through the files array and check if the name of that file matches FileName
// and get the index of the match
for(i = 0; i < filesToUpload.length; ++ i){
if(filesToUpload[i].name == fileName){
//console.log("match at: " + i);
// remove the one element at the index where we get a match
filesToUpload.splice(i, 1);
}
}
//console.log(filesToUpload);
// remove the <li> element of the removed file from the page DOM
$(this).parent().remove();
});
You can un-comment the console.log() statements to see the result
In my adventure to create a To-Do list application, I've run into another problem. In my code, every time a user clicks New Category a new div will appear with their custom name and number of forms.
However, when another div is created, its' forms are given to the previous div. Here's that code:
<script src="http://code.jquery.com/jquery-2.0.0.js"></script>
<script type='text/javascript' src="script.js"></script>
<script>
$(function() {
$("#new").click(function() {
var canContinue = true;
var newCategory = prompt("Enter the name you want for your category:");
if(newCategory.length === 0){
confirm("A new category can not be created - nothing was entered in the text area.");
canContinue = false;
}
if(canContinue){
var categorySections = prompt("Enter the number of sections needed for this category:");
$("body").append("<div id = \"newDiv\"><p>" + newCategory + "</p></div>");
}
for(var i = 0; i < categorySections; i++){
$("#newDiv").append("<form> Thing to do: <input type = \"text\"></form><br>");
}
});
});
</script>
So, I tried creating a separate function using the this keyword where the forms were created after the div was ready, but now no forms are created at all!
Here's that code:
$(function(){
$("#newDiv").ready(function() {
for(var i = 0; i < categorySections; i++){
$(this).append("<form> Thing to do: <input type = \"text\"></form><br>");
}
});
});
So, how do I create forms for each separate div?
You're repeatedly creating divs with the same ID. (a) that's not legal and (b) if you do it anyway, your $(#newDiv) selector will always apply to the first one.
Also, you're appending to #newDiv outside the if (canContinue) check.
Try:
if(canContinue){
var categorySections = prompt("Enter the number of sections needed for this category:");
var newDiv = $("<div>").appendTo($(document.body));
var header = $('<p>').text(newCategory).appendTo(newDiv);
for(var i = 0; i < categorySections; i++){
newDiv.append("<form> Thing to do: <input type = \"text\"></form><br>");
}
}
jsFiddle
You can't use the ID newDiv multiple times, HTML IDs must be unique. Additionally, your flow can be cleaned up a bit, as below.
$(function () {
$("#new").click(function () {
var newCategory = prompt("Enter the name you want for your category:");
if (newCategory.length === 0) {
confirm("A new category can not be created - nothing was entered in the text area.");
return false;
}
var categorySections = prompt("Enter the number of sections needed for this category:");
var $div = $("<div />", {
html: "<p>" + newCategory + "</p>"
});
$("body").append($div);
for (var i = 0; i < categorySections; i++) {
$div.append("<form> Thing to do: <input type='text'/></form><br>");
}
});
});
How can I modify this script to capture the 'alt' attribute for the images a user selects in a slideshow?
This code displays a series of 20 pairs of images and asks users to select their preferences. Each time the user clicks one of the 'Select' buttons, the 'manipulateDOM()' function advances to the next set of items in the the text and image arrays. However, since it's not set up as a typical form field, I'm having difficulty figuring out how to capture the value of each selection so that it can be submitted to the database with the rest of the form values.
I tried creating a function with the click() method to (at the very least) capture the src value, but I can't get the syntax right so that it can run in conjunction with the 'manipulateDOM()' function. I'd also much rather capture the 'alt' attribute, but I couldn't figure out how to do that.
Function I was experimenting with:
$(document).ready(function () {
$("#buttons").click(function () {
var imgvalue = $("#imgtrendy").attr("src");
$("#picval").text(imgvalue);
document.write(imgvalue + ', ');
});
});
Existing Code:
Javascript - manipulateDOM() and manipulateDOM1() functions
var NumberOfImages = 3 - 1; //-1 because array members starts from 0
var trendy = new Array(NumberOfImages);
trendy[0] = "files/set1/A1.jpg";
trendy[1] = "files/set1/B1.jpg";
trendy[2] = "files/set1/C1.jpg";
var imgNumber = 1; //array key of current image
var NumberOfImages = 3 - 1;
var classic = new Array(NumberOfImages);
classic[0] = "files/set1/A2.png";
classic[1] = "files/set1/B2.jpg";
classic[2] = "files/set1/C2.jpg";
var classicNumber = 1;
var text = 3 - 1;
var text = new Array;
text[0] = "Which would you be more likely to wear?"
text[1] = "Which look is more you?"
text[2] = "Which would you rather wear?"
var textNumber = 1;
function manipulateDOM() {
changeObjects();
NextImage();
}
function changeObjects() {
document.getElementById("question").innerHTML = text[textNumber];
}
function NextImage() {
if (imgNumber < NumberOfImages) //Stop moving forward when we are out of images
{
imgNumber++;
document.images["taste"].src = trendy[imgNumber];
document.images["taste1"].src = classic[imgNumber];
textNumber++;
document.getElementById["question"].innerHTML = text[textNumber];
document.getElementById["selectButton"].innerHTML = text[textNumber];
}
}
function manipulateDOM1() {
changeObjects();
NextImage1();
}
function NextImage1() {
if (imgNumber < NumberOfImages)
{
imgNumber++;
document.images["taste"].src = trendy[imgNumber];
document.images["taste1"].src = classic[imgNumber];
textNumber++;
document.getElementById["question"].innerHTML = text[textNumber];
document.getElementById["selectButton"].innerHTML = text[textNumber];
}
}
HTML
<form id="taste" name="taste" method="post" action="taste-exec.php" >
<h2 id="question"> Which would you be more likely to wear?</h2>
<table><tr>
<td><img id="imgtrendy" src="files/set1/A1.jpg" name="taste" value="trendy[1]" /></td>
<td><img id="imgclassic" src="files/set1/A2.png" name="taste1" value="classic[1]" /></td></tr>
<tr id="buttons">
<td><img id="trendyButton" alt"Select" src="files/Select.jpg" onclick="javascript:manipulateDOM()"></td>
<td ><img id="classicButton" alt"Select" src="files/Select.jpg" onclick="javascript:manipulateDOM1()"></td>
</tr><tr>
<td id="picval"></td>
<td><input name="answer" id="answer" type="text" /></td>
</tr></table>
</form>
You get the alt attribute using also the attr method and alt as parameter, just like you are already doing with src. You could try:
function changeObjects() {
document.getElementById("question").innerHTML = text[textNumber];
var imgvalue = $("#imgtrendy").attr("alt");
$("#picval").text(imgvalue);
}
Edit: Example of keeping data in one single array
//to save it
var alt = $("#imgtrendy").attr("alt");
var fileName= 'someValue';//populate accordingly
var myArray[index] = alt + '|' + fileName;
//to retrieve it
var bothValues = myArray[index].split('|'); //gives you an array
alt = bothValues[0] //contains alt at index 0
fileName = bothValues[1] //contains fileName at index 1