How To Create methods(functions) in jQuery Plugins - javascript

I want to create a plugin, which will be looking for a img file on PC, and after load this image file, the user can choose some methods to apply in this. For example, in a call plugin:
$('#test').myPlugin({
legend: true
});
And my code for plugin upload a file is this:
(function( $ ){
var handleFileSelect = function (evt) {
var files = evt.target.files;
for(var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="responsive-img thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
};
$.fn.upload = function(options) {
var settings = $.extend( {}, options );
return this.each(function() {
document.getElementById('files').addEventListener('change', handleFileSelect, false);
});
};
})( jQuery );
This code works fine on upload img, but I don´t have idea, how I can add methods in this plugin. Someone help me?
Thanks!

how i can add methods in this plugin
The same way that you already do. Notice how you're adding a plugin function here:
$.fn.upload = function(options) {
//...
}
So if you want to add a function by a different name, simply add a function by a different name:
$.fn.myPlugin = function(options) {
//...
}

Related

Can not preview multiple uploading files in form

In a multipart form, I can preview a single uploading image using:
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = `${e.target.result}`;
image.className = "img-thumbnail"
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$('#images-to-upload').append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#imgInput").change(function () {
readURL(this);
});
But I'd like to preview ALL uploading images, so I made this adjustment to the code above by adding a for loop:
function readURL(input) {
if (input.files && input.files[0]) {
let files = input.files;
for (var i = 0; i < input.files.length; i++) {
var reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = `${e.target.result[i]}`;
image.className = "img-thumbnail"
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$('#images-to-upload').append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
}
};
reader.readAsDataURL(input.files[i]); // error here
}
}
But now I get this error:
143 Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'
How can I fix this?
It's because the reader.readAsDataURL(input.files[i]); is outside the loop. But this is not how you do this. The FileReader can process only one file at the time. This means you have to create an instance of the FileReader for each image in the input.
I would suggest to split it into 2 functions for readability.
function previewImage(file) {
const reader = new FileReader();
reader.onload = function (e) {
let image = new Image();
image.src = e.target.result;
image.className = "img-thumbnail";
let closeBtn = `<button type="button" class="close"></button>`;
let wrapper = $('<div class="image-wrapper" />');
$("#images-to-upload").append(wrapper);
$(wrapper).append(image);
$(wrapper).append(closeBtn);
};
reader.readAsDataURL(file);
}
function readURL(input) {
if (input.files.length) {
Array.from(input.files).forEach((file) => previewImage(file));
}
}
I made some changes:
if (input.files.length) { - the file input always have files FileList object so no need to check if it exists, and you just check if it has a length, meaning at least one file is present
Array.from(input.files) - transforms FileList into a regular array fo you can use array functions, like forEach
The rest is pretty much the same. In image.src = e.target.result;, there's no need to make it string as it is already a string. Also the result set on the FileReader class cannot be array.

HTMLImageElement onclick

I am trying to add an onclick event that calls a function selectMain(name). When I run my project it doesn't seem to generate the onclick attribute from the image.
function previewFiles() {
var preview = document.querySelector('#preview');
var files = document.querySelector('input[type=file]').files;
function readAndPreview(file) {
if (/\.(jpe?g|png)$/i.test(file.name)) {
var reader = new FileReader();
reader.addEventListener("load", function() {
var image = new Image();
image.height = 100;
image.title = file.name;
image.src = this.result;
image.onclick = selectMain(file.name);
preview.appendChild(image);
}, false);
reader.readAsDataURL(file);
}
}
if (files) {
[].forEach.call(files, readAndPreview);
}
}
function selectMain(name) {
var files = document.querySelector('input[type=file]').files;
Array.from(files).forEach(file => {
if (file.name == name) {
document.getElementById("primaryPhoto").value = file;
}
});
}
Try thisimage.onclick = function(){ selectMain(file.name); };
In addition to what Gagik answered (the early selectMain call is definitiely an issue even if it doesn't fix the whole thing), what is
document.getElementById("primaryPhoto").value = file;
supposed to do? If primaryPhoto is a input[type=file] element, then that won't work due to security limitations
You cannot set the value of a file picker from a script
Source.
(/\.(jpeg?g|png)$/i.test(file.name))
In the existing code, function get invoked on the time of render on dom.
here is the correct way to bind event.
var image = new Image();
image.height = 100;
image.title = file.name;
image.src = this.result;
image.onclick =()=>{selectMain(file.name)};

View and Hide Image Using Jquery

I am displaying images before upload using jquery, when i upload some new files i want to remove or hide the previous upload files here's my jquery code:
$(function()
{
// Multiple images preview in browser
var imagesPreview = function(input, placeToInsertImagePreview)
{
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="p-3" width="350px" height="250px">')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
}
reader.readAsDataURL(input.files[i]);
}
}
}
$('#file_input').on('change', function()
{
imagesPreview(this, 'div#viewUploadItems');
});
});
And my HTML Code:
<input type="file" name="images[]" id="file_input" class="deletable" multiple />
<div id="viewUploadItems"></div>
I try this code but this won't display any image.
$("#file_input").on("click",function()
{
$('input.deletable').val('');
$('#viewUploadItems').remove();
});
Perhaps you could take the following approach, where in your imagePreview() function you:
first call empty() on the preview selector to clear any prior image contents
then proceed to read and display any selected images, by using the FileReader API as you currently are (see below for revised approach)
Also, consider checking the type of the file object, to ensure that it is an image before attempting to display it via the following:
if (file.type.match("image.*")) {
/* file is image type, so attempt to preview it */
}
Bringing these ideas together, you could revise your code as follows:
$(function() {
function imagesPreview(input, targetSelector) {
/* Empty the target area where previews are shown */
$(targetSelector).empty();
/* Iterate each file via forEach in own closure */
Array.from(input.files).forEach(function(file) {
/* If file is image type proceed to preview */
if (file.type.match("image.*")) {
/* Create filereader and set it up for reading */
var reader = new FileReader();
reader.onload = function(event) {
/* Append a new image element, prepopulated with
required attrbutes, and assigned with p-3 class */
$(targetSelector).append($('<img>', {
width: '350px',
height: '250px',
src : reader.result
}).addClass('p-3'))
}
reader.readAsDataURL(file);
}
})
}
$('#file_input').on('change', function() {
imagesPreview(this, 'div#viewUploadItems');
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<input type="file" name="images[]" id="file_input" class="deletable" multiple />
<div id="viewUploadItems"></div>
Easier to clear the div before display : $(placeToInsertImagePreview).html("");
$(function()
{
// Multiple images preview in browser
var imagesPreview = function(input, placeToInsertImagePreview)
{
if (input.files)
{
$(placeToInsertImagePreview).html("");
var filesAmount = input.files.length;
for (i = 0; i < filesAmount; i++)
{
var reader = new FileReader();
reader.onload = function(event)
{
$($.parseHTML('<img class="p-3" width="350px" height="250px">')).attr('src', event.target.result).appendTo(placeToInsertImagePreview);
}
reader.readAsDataURL(input.files[i]);
}
}
}
$('#file_input').on('change', function()
{
imagesPreview(this, 'div#viewUploadItems');
});
});

Dynamically populate listview in jQuery mobile based on if file exists on phone

This is the start of my code. It simply populates an unordered list from a JSON file. I tried using the Cordova FileReader without any luck.
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
alert("Got deviceready");
var reader = new FileReader();
var fileSource = cordova.file.externalDataDirectory;
$.getJSON( "links.json", function( data ) {
$.each( data, function( key, val ) {
var $li = $("<li><a href='#'>"+val.title+"</a></li>");
reader.onloadend = function(evt) {
if(evt.target.result == null) {
$li.find("a").on("click", function(){ downloadPdf(val.title,val.url); });
} else {
$li.find("a").on("click", function(){ openPdf(val.title); });
}
};
// We are going to check if the file exists
reader.readAsDataURL(fileSource + val.title + ".pdf");
$("#linkList").append($li);
$("#linkList").listview('refresh');
});
});
}
As you can see, this example adds list items with the downloadPdf(title, url) function. If it do exists, I want the list item to call the function openPdf(title) instead. The files are saved in cordova.file.externalDataDirectory + title + ".pdf".
This code doesn't add any items to my list.
You can use the file plugin to check if a file exists
var reader = new FileReader();
var fileSource = <here is your file path>
reader.onloadend = function(evt) {
if(evt.target.result == null) {
// If you receive a null value the file doesn't exists
} else {
// Otherwise the file exists
}
};
// We are going to check if the file exists
reader.readAsDataURL(fileSource);

click event not firing in IE11

I have this js file:
function fireClick(node){
if ( document.createEvent ) {
var evt = document.createEvent('MouseEvents');
evt.initEvent('click', true, false);
node.dispatchEvent(evt);
} else if( document.createEventObject ) {
node.fireEvent('onclick') ;
} else if (typeof node.onclick == 'function' ) {
node.onclick();
}
}
function selectAvatar()
{
var fileSelector = document.createElement('input');
fileSelector.setAttribute('type', 'file');
fileSelector.setAttribute('accept', "image/gif, image/jpeg");
fileSelector.onchange = function(event) {
var fileList = fileSelector.files;
//alert(fileList.length);
if (fileList.length==0) return;
reader.readAsDataURL(fileList[0]);
}
var reader = new FileReader();
reader.onload = function(e) {
var dataURL = reader.result;
//alert(dataURL);
var container = document.getElementById("avatart-container-div");
var backgroundIMgString = 'url("'+dataURL+'")';
container.style.backgroundImage=backgroundIMgString;
}
fireClick(fileSelector);
}
which is supposed to open programatically a file picker to select an imgae. While this works on FF and chrome, this does NOT work on IE (11 is my version). The picker itself doesn't show up. Tried debugging line by line but everything seems fine (no errors or exceptions). Any have an idea what might be the problem?
Taken from the comments:
You are actually only creating the element, without adding it to the DOM. You can add it to the DOM with: document.body.appendChild(fileSelector);
And in the selectAvatar function:
function selectAvatar()
{
var fileSelector = document.createElement('input');
fileSelector.setAttribute('type', 'file');
fileSelector.setAttribute('accept', "image/gif, image/jpeg");
document.body.appendChild(fileSelector);
// do stuff
}
Also здрасти

Categories

Resources