Fine uploader, idiomatic way to add download button to each file uploaded - javascript

I've successfully implemented fine uploader into my project. I'm using the addInitialFiles method to populate it with previously uploaded files.
What I would like to do is add a download button to each file preview rendered, both as a user add's files and 'on load' when prepopulated using addInitialFiles. Adding the button to the mark up template is pretty trival, but I'm stuck on what the most idiomatic way would be to:
Listen for the click event on the download button I've added to the markup (e.g. use a fine uploader API method, or my own listener?)
How I can associate the necessary information with each button/thumbnail to envoke a file download.
I'm storing the files download url in a mongo collection that that im returning and populating the addInitial files method with.
In case it comes up: I'm not looking to have fine uploader 'handle' the download, I'm simply trying to weave the download functionality into it's UI :)
Appreciate any/all advice/pointers!

Add an anchor link to your template somewhere inside the <li>.
Listen for qq.status.UPLOAD_SUCCESS status changes.
On success, update the anchor link to point to the appropriate download endpoint. You can find the anchor link for a specific file using getItemByFileId.
You'll need to be sure your server returns the proper Content-Disposition header when responding to a download GET request.

May this help to someone to add a custom download button to each uploaded file.
I have tested for FineUploader version 5.16.2.
Used ref links - callback events & initial file list
Code for file uploader is as (used two events for the download button):
var defaultParams = {};
$('#fine-uploader-gallery').fineUploader({
template: 'qq-template-gallery',
thumbnails: {
placeholders: {
waitingPath: 'waiting-generic.png',
notAvailablePath: 'not_available-generic.png'
}
},
validation: {
itemLimit: 10,
// acceptFiles: 'image/*',
// allowedExtensions: ['mp4','jpeg', 'jpg', 'gif', 'png']
},
session: { /** initial file list **/
endpoint: '/uploaded_files',
params: defaultParams
},
request: { /** new upload file request **/
endpoint: '/upload_files'
},
callbacks: {
/** Event to initial files with download link
array(
array('id' => xxx, 'name' => xxx, 'size' => xxx, 'thumbnailUrl' => xxx, 'uuid' => xxx, 'url' => fileUrl),
array('id' => xxx, 'name' => xxx, 'size' => xxx, 'thumbnailUrl' => xxx, 'uuid' => xxx, 'url' => fileUrl2),
...
}
**/
onSessionRequestComplete: function(id, name, responseJSON){
id.forEach((item, index) => {
var serverPathToFile = item.url,
$fileItem = this.getItemByFileId(index);
if (responseJSON.status == 200) {
$($fileItem).find(".qq-download-option") /** Custom Anchor tag added to Template **/
.attr("href", serverPathToFile)
.removeClass("hide");
}
});
},
/** Event to newly uploaded file with download link
responseJSON : array('success' => 'true', 'filename' => xxx, 'unique_id' => xxx, 'url' => fileurl)
**/
onComplete: function(id, name, responseJSON, xhr){
var serverPathToFile = responseJSON.url,
$fileItem = this.getItemByFileId(id);
if (responseJSON.success) {
$($fileItem).find(".qq-download-option") /** Custom Anchor tag added to Template **/
.attr("href", serverPathToFile)
.removeClass("hide");
}
}
},
deleteFile: {
enabled: true,
forceConfirm: true,
method: 'DELETE',
endpoint: '/delete_files',
customHeaders: {},
params:defaultParams
}
});

Related

How to share a document automatically with mail in React native mail linking?

I have a share button. On press of this button I called a function. That function basically creates a screen view pdf, and now I am storing that pdf in my state (means that pdf path). After that I am calling mail linking function. And by pressing share option I want to share that pdf file to that mail. It means, I want to append that pdf automatically in mail body.
Here's what I have tried, but this just adds a file path in mail body (not an actual file):
Linking.openURL(
`mailto:support#example.com?subject=SendMail&body=${this.state.pdf}`
);
You can't add an attachment using a mailto link. Sorry.
You could put a link to the file in the mail body.
I couldn't find anything in the react native Linking.However I've found react-native-mail helpful
I've tested this on android and iOS react-native version 0.63.2
Sample Code
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React, { Component } from 'react';
import { View, Alert, Button } from 'react-native';
import Mailer from 'react-native-mail';
export default class App extends Component {
handleEmail = () => {
Mailer.mail({
subject: 'need help',
recipients: ['support#example.com'],
ccRecipients: ['supportCC#example.com'],
bccRecipients: ['supportBCC#example.com'],
body: '<b>A Bold Body</b>',
customChooserTitle: 'This is my new title', // Android only (defaults to "Send Mail")
isHTML: true,
attachments: [{
// Specify either `path` or `uri` to indicate where to find the file data.
// The API used to create or locate the file will usually indicate which it returns.
// An absolute path will look like: /cacheDir/photos/some image.jpg
// A URI starts with a protocol and looks like: content://appname/cacheDir/photos/some%20image.jpg
path: '', // The absolute path of the file from which to read data.
uri: '', // The uri of the file from which to read the data.
// Specify either `type` or `mimeType` to indicate the type of data.
type: '', // Mime Type: jpg, png, doc, ppt, html, pdf, csv
mimeType: '', // - use only if you want to use custom type
name: '', // Optional: Custom filename for attachment
}]
}, (error, event) => {
Alert.alert(
error,
event,
[
{text: 'Ok', onPress: () => console.log('OK: Email Error Response')},
{text: 'Cancel', onPress: () => console.log('CANCEL: Email Error Response')}
],
{ cancelable: true }
)
});
}
render() {
return (
<View style={styles.container}>
<Button
onPress={this.handleEmail}
title="Email Me"
color="#841584"
accessabilityLabel="Purple Email Me Button"
/>
</View>
);
}
}

How to upload a file along with text using fetch in react native?

I'm trying to upload a file to the server using react-native-document-picker. The problem I'm facing is I don't know how to upload the file along with a text.In my app there is a portion for file upload also there is an area for writing some text.Then it will get uploaded to the server.So I've done the following.But I'm getting this error after submitting to server
unhandled promise rejection unsupported BodyInit type
updated portion of code
filepick = () => {
DocumentPicker.show({
filetype: [DocumentPickerUtil.images()],
}, (error, res) => {
if (error == null) {
console.log(
res.uri,
res.type, // mime type
res.fileName,
res.fileSize
);
this.setState({
img_uri: res.uri,
img_type: res.type,
img_name: res.fileName
})
} else {
Alert.alert('Message', 'File uploaded failed');
}
});
};
onPressSubmit() {
const data = new FormData();
data.append('file', { uri: this.state.img_uri, type:
this.state.img_type, name: this.state.img_name })
data.append('comment', { text: this.state.text });
AsyncStorage.getItem("userdetail").then(value => {
fetch(GLOBAL.ASSN_URL +`${this.props.id}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization': value
},
body: data
}).then((response) => {
return response.text()
}).then((responseJson) => {
var result = responseJson;
console.log(result);
});
})
}
The function filepick() is called after choosing a file from your device.Please help me to find a solution.How do I upload this to server also how to send text without stringifying it?
body: ({
file: this.state.file,
comment: this.state.text
})
Why are you wrapping body in brackets? Removing them might fix it.
Also see this, https://github.com/facebook/react-native/issues/6025 you might want to stringify the body object, since your content type is not application/json
body: JSON.stringify({
file: this.state.file,
comment: this.state.text
})
Edit
From comments we now know the following
1) You are uploading a file separately.
2) The upload response contains information about the file
3) You are saving the entity in separate server call
4) You need to save file with that entity
The solution below assumes that you have full control over server and you are also handling the file uploading endpoint. Here is the solution
You basically do not need to upload the whole file again with your entity since it is already uploaded on server, all you need to do is to save the reference of the file with entity. Their are two ways to save the reference
1) Just save either the fileName or fileUrl in your entity table and then store the name or url with entity so it will look like this
{
id: 1,
name: 'Cat',
picture: // url or name of picture
}
2) Save the uploaded file in different table, then save the id of the file with your entity, and when you fetch entities get the related file. However if the relationship between entity and file is one to many as in one entity can have many files then you will first need to save the entity and then upload the files with reference of entity. This way your entity will look like this
{
id: 1,
name: 'Cat',
pictures: [{fileName: 'cat1'}, {fileName: 'cat2'}]
}

Meteor Files Storing a image url in Mongo collection

I'm really lost when it comes to file uploading in meteor and manage the data between client and server.
I'm using Meteor Files from Veliov Group to upload multiple images on the client side. They're getting stored in a FilesCollection called Images and I have my Mongo.Collection called Adverts.
collections.js:
Adverts = new Mongo.Collection('adverts');
Images = new FilesCollection({
collectionName: 'Images',
storagePath: () => {
return `~/public/uploads/`;
},
allowClientCode: true, // Required to let you remove uploaded file
onBeforeUpload(file) {
// Allow upload files under 10MB, and only in png/jpg/jpeg formats
if (file.size <= 10485760 && /png|jpg|jpeg/i.test(file.ext)) {
return true;
} else {
return 'Limit 10mb';
}
}
});
// if client subscribe images
if (Meteor.isClient) {
Meteor.subscribe('files.images.all');
};
// if server publish images
if (Meteor.isServer) {
Images.allowClient();
Meteor.publish('files.images.all', () => {
return Images.collection.find();
});
};
What I'm trying to achieve is, when I upload the images, I wanna store the URLs on the document in Adverts that I'm working with (I'm using iron:router to access those documents _id).
I managed to get the URL but only for the first image uploaded, my code for what I saw on the docs:
Template.imageUpload.helpers({
imageFile: function () {
return Images.collection.findOne();
},
myImage: () => {
console.log(Images.findOne({}).link())
}
})
Template.imageUpload.events({
'change #fileInput': function (e, template) {
if (e.currentTarget.files) {
_.each(e.currentTarget.files, function (file) {
Images.insert({
file: file
});
});
}
}
})
I was using a Meteor.Call to send the URL to the server, but I couldn't manage to update the document with a new property pic and the value url of the image
server.js:
imageUpload: (actDoc, imgURL) => { // actDoc is the document id that I'm working on the client
Adverts.update({'reference': actDoc}, {$set: {'pic': imgURL}})
},
This is probably a dumb question and everything might in the docs, but I've readed those docs back and forth and I can't manage to understand what I need to do.
The answer for my problem was to do it server side
main.js server
FSCollection.on('afterUpload'), function (fileRef) {
var url = 'http://localhost:3000/cdn/storage/images/' + fileRef._id + '/original/' + fileRef._id + fileRef.extensionWithDot;
}
MongoCollection.update({'_id': docId}, { $set: {url: imgUrl }}})

Uploading file to PouchDB/CouchDB

I'm building a mobile app with Cordova. I am using PouchDB for local storage so the app works without internet. PouchDB syncs with a CouchDB server so you can access your data everywere.
Now, i've got to the point where I need to add a function to upload (multiple) files to a document. (files like .png .jpg .mp3 .mp4 all the possible file types).
My original code without the file upload:
locallp = new PouchDB('hbdblplocal-'+loggedHex);
function addItem() {
//get info
var itemTitle = document.getElementById('itemTitle').value;
var itemDesc = document.getElementById('itemDesc').value;
var itemDate = document.getElementById('itemDate').value;
var itemTime = document.getElementById('itemTime').value;
//get correct database
console.log(loggedHex);
console.log(loggedInUsername);
//add item to database
var additem = {
_id: new Date().toISOString(),
title: itemTitle,
description: itemDesc,
date: itemDate,
time: itemTime
};
locallp.put(additem).then(function (result){
console.log("Added to the database");
location.href = "listfunction.html";
}).catch(function (err){
console.log("someting bad happened!");
console.log(err);
});
}
I'll add a link to a JSfiddle where I show my attempt to add the file upload. i've also included the html part.
link to jsfiddle: click here
I've noticed an error in the console about there not being a content-type.
Is there someone who can help me?
I think you're not setting the content_type of your attachment right. Try changing type to content_type like so:
var additem = {
_id: new Date().toISOString(),
title: itemTitle,
description: itemDesc,
date: itemDate,
time: itemTime,
_attachments: {
"file": {
content_type: getFile.type,
data: getFile
}
}
};
Also see the docs for working with attachments.

Add a file description when uploading file Yii 1

Hello I'm using EAjaxUpload extension to upload files and its working perfectly and files are uploaded I want to add a description to each file. I used the onComplete to have the function here's my code :
$uploadfile = $this->widget('ext.EAjaxUpload.EAjaxUpload',
array(
'id' => 'uploadFile',
'config' => array(
'action' => Yii::app()->createUrl('objective/upload'),
'allowedExtensions' => array("docx", "pdf", "pptx"),//array("jpg","jpeg","gif","exe","mov" and etc...
'sizeLimit' => 5 * 1024 * 1024,// maximum file size in bytes
//'minSizeLimit'=>10*1024*1024,// minimum file size in bytes
'onComplete' => "js:function(id, fileName, responseJSON){
console.log(responseJSON);
var filedescription= prompt('file description');
if (filedescription != null) {
document.getElementById('demo').innerHTML =
filedescription;
return filedescription;
}
}",
//'messages'=>array(
// 'typeError'=>"{file} has invalid extension. Only {extensions} are allowed.",
// 'sizeError'=>"{file} is too large, maximum file size is {sizeLimit}.",
// 'minSizeError'=>"{file} is too small, minimum file size is {minSizeLimit}.",
// 'emptyError'=>"{file} is empty, please select files again without it.",
// 'onLeave'=>"The files are being uploaded, if you leave now the upload will be cancelled."
// ),
'showMessage' => "js:function(message){ alert(message); }"
)
));
Now I want to return var filedescription to upload action in controller. How can I do that?
Thanks,
1.onComplete is called after your upload request is already processed by "objective/upload" action. So you have possibility to ask and set description as parameter BEFORE request:
'onSubmit' => "js:function(id, fileName){
// add filedescriton to post parameters:
this.params.filedescription = 'some file description';
}"
In controller "objective/upload" action you can access it as $_POST['filedescription'].
2.Other possibility is to create separate action for saving description (and additional file processing...) and call it from onComplete:
In onComplete:
$.post( 'saveUploadedFileDescription', { filedescription: 'some file description', fileName: fileName } );
In controller:
actionSaveUploadedFileDescription($filedescription,$filename) {
// ....
}

Categories

Resources