I try to preview a image before upload, I want to dispaly a small one, and on click to be full size, but till now it didn't work. I am using vue-upload-component, file.thumb from them also didn't work.
data() {
return {
url:null,
}
}
watch: {
files: {
handler: function(){
this.files.forEach((file,index) =>{
const file = e.target.file[0];
this.url = URL.createObjectURL(file);
console.log('Files:',this.files);
})
},
}
}
//First try found on stack
<div id="preview">
<img v-if="url" :src="url" />
</div>
//This is from them , but is not working.
<img v-if="file.thumb" :src="file.thumb" width="40" height="auto" />
<span v-else>No Image</span>
UPDATE
Now the small image it works, I just need to add some things form that library.
Now I just need to preview full size img hen click.
<img v-if="file.thumb" :src="file.thumb" width="40" height="auto" />
You are using the this from the forEach scope, try initializing the global ViewModel to be able to access the data params, like this :
watch: {
files: {
handler: function(){
let vm = this;
this.files.forEach((file,index) =>{
const file = e.target.file[0];
vm.url = URL.createObjectURL(file);
console.log('Files:',vm.files);
})
},
}
}
Can you try this?
handler: function(){
this.files.forEach((file,index) =>{
const file = event.target.files[0];
if (file) {
let reader = new FileReader();
reader.onload = (e: any) => {
this.url = e.target.result; //Base64 string
}
}
})
}
Related
I am trying to update the user profile data in my database, but I am stuck at the user profile image. I can't use the v-model for binding, and with v-on:change it doesn't work. This is my code so far, it is working properly, the only issue being the binding.
<template>
-----
<div v-if="!image">
<h2>Select an image</h2>
<input type="file" #change="onFileChange" /> ---->here I would like to use the v-model but can't use it on input type="file"
</div>
<div v-else>
<img :src="image" />
<button #click="removeImage">Remove image</button>
</div>
<input
type="text"
placeholder="Userame"
v-model="user.username"
required
/>
<button
type="button"
class="btn btn-outline-warning waves-effect"
aria-label="Left Align"
#click.prevent="updateProfile(user)"
>
Update profile
</button>
---
</template>
<script>
export default {
data: function () {
return {
user: {},
image: ''
};
},
methods: {
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
console.log(file.name);
},
removeImage: function (e) {
this.image = '';
},
updateProfile() {
store
.dispatch("updateProfile", {
username: this.user.username,
email: this.user.email,
profileImage: this.file ------>I need it for the binding here
</script>
You forgot to bind the file to this.file. Update your onFileChange method to this 👇🏻, it will work.
Note: v-model only works with input which use value binding, where input type file doesn't use input value, it makes no sense to use input type file with v-model
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length) return;
this.file = files[0]
this.createImage(this.file);
},
I wrote a function that saves an image as blob:
render() {
...
return (
...
<input
accept="image/*"
onChange={this.handleUploadImage.bind(this)}
id="contained-button-file"
multiple
type="file"
/>
)}
and this is the function called in onChange:
handleUploadImage(event) {
const that = this;
const file = event.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
that.setState({
image: URL.createObjectURL(file),
userImage: reader.result,
});
};
}
I think this works fine because it saves in DB because the document has a field called image which looks like this: blob:http://localhost:3000/80953c91-68fe-4d2a-8f5e-d9dd437c1f94
this object can be accessed like this.props.product, to access the image it is this.props.product.image
The problem is when I want to show the image, I don't know how to do this.
I tried to put it in render like:
{
this.props.product.image ? (
<img alt="" src={this.props.product.image} />
) : (
null
);
}
it throws this error:
and the header:
any suggestions?
You should try URL.createObjectURL(blob)
https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
myImage.src = URL.createObjectURL(blob);
I know this has a simple answer but I appear to be stuck. I have an upload image input in a form. Following several tutorials, I have successfully created the upload method. My issue is once the image is uploaded to Firestore storage I use this.$emit('imgurl', downloadURL)
My problem is I do not know how to get that value so when the user submits the form the url gets added to the database.
Parts of the code:
HTML:
<div class="field avatar">
<label for="avatar">Avatar</label>
<input type="file" name="imgurl" accept="image/*" #change="detectFiles($event.target.files)">
<div class="progress-bar green" :style="{ width: progressUpload + '%'}">{{ progressUpload }}%</div>
<img class="avatar" v-bind:src="this.downloadURL">
</div>
Methods:
detectFiles (fileList) {
Array.from(Array(fileList.length).keys()).map( x => {
this.upload(fileList[x])
})
},
upload (file) {
var storage = firebase.storage();
this.uploadTask = storage.ref('avatars/'+file.name).put(file);
}
Watch:
watch: {
uploadTask: function() {
this.uploadTask.on('state_changed', sp => {
this.progressUpload = Math.floor(sp.bytesTransferred / sp.totalBytes * 100)
},
null,
() => {
this.uploadTask.snapshot.ref.getDownloadURL().then(downloadURL => {
this.downloadURL = downloadURL
this.$emit('imgurl', downloadURL)
})
})
}
}
Add to the database:
db.collection('teams').add({
team_name: this.team_name,
team_id: this.team_id,
bio: this.bio,
url: this.imgurl,
}).then(() => {
this.$router.push({ name: 'Admin' })
}).catch(err => {
console.log(err)
})
You can pass a function as a prop to a child component, then call this function passing your downloadURL as argument.
Parent Component
HTML
<child passURL="getDownloadURL">
JS
data: {
return {
downloadURL: null
}
},
methods: {
getDownloadURL: function(url) {
this.downloadURL = url
}
}
Child Component
JS
props: ['passURL'],
Inside your watcher, you can call
this.passURL(downloadURL)
Instead of $emit.
I found the answer. I added a hidden input field
<input type="hidden" name="imgurl" v-model="imgurl">
and replaced the emit with this.imgurl = downloadURL
I am using Symfony2.8 With aviaryeditor Image Editor. The Scene is that I have from with one file upload field. I wanted to allow user to upload images and do some editing with images (cropping, resizing, effects) then upload it to the server. And on the backend i get the file. Do some checks and validation and upload it on my local file system of s3.
What i have done so far is, I allow user to upload the image from the user and dislay the uploaded image in the form. On image click the editors pops up and after editing the gives the new url (s3 url of avairy api).
$builder
->add('media', 'file', array(
'data_class' => null,
'label' => ucfirst('Choose Domicile File'),
'attr' => array('class' => 'form-control')
)
)
<div class = "form-group col-xs-5">
<label class="control-label">{{ form_label(domicileForm.media) }}</label>
<div class="text-center">
{{form_widget (domicileForm.media, {'attr': {'class': 'form-control'}})}}
</div>
<img id="blah" src="#" alt="your image"
class="img-responsive img-thunmbail"
onclick="return launchEditor(this.id, this.src);" />
</div>
and with js
<script>
$(document).ready(function() {
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#blah').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#pncmisdashboard_bundle_dimicile_type_media").change(function(){
readURL(this);
});
});
</script>
<script type="text/javascript" src="http://feather.aviary.com/js/feather.js"></script>
<!-- Instantiate Feather -->
<script type='text/javascript'>
var featherEditor = new Aviary.Feather({
apiKey: '43232',
apiVersion: 3,
theme: 'light', // Check out our new 'light' and 'dark' themes!
tools:'crop,resize,color,sharpness,text',
appendTo: '',
onSave: function(imageID, newURL) {
var img = document.getElementById(imageID);
$(imageID).attr('src', newURL);
// //copy the url to the hidden form field
// $('#pncmisdashboard_bundle_dimicile_type_media').val(newURL);
$('#pncmisdashboard_bundle_dimicile_type_media').attr('value', newURL);
img.src = newURL;
alert(imageID);
alert(newURL);
alert(imageID);
},
onError: function(errorObj) {
alert(errorObj.message);
}
});
function launchEditor(id, src) {
featherEditor.launch({
image: id,
url: src
});
return false;
}
</script>
and after the api successfully return the url of new image, I am setting this url to media (file type) field. But it's not happening. it saves the orignal image that was first upload not the new one.
Using one of the comments/answers I fixed the photo viewing, however it does not load sometimes if the image is too big. It would be great to see an example of code to turn an image into a thumbnail.
<template name="photos">
<form>
<input id="file" type="file">
<input id="addFile" type="submit">
</form>
{{#each images}}
<div>
<img src="{{this.url store='images' uploading='/images/uploading.jpg' storing='/images/storing.jpg'}}" alt="" class="thumbnail" />
</div>
{{/each}}
</template>
Javascript:
if (Meteor.isServer) {
// Create server database for listings
var Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images", {path: "~/uploads"})]
});
Template.photos.events({
'click #addFile' : function(e, t){
var file = t.find('#file').files[0];
var ticket = this._id;
var newFile = new FS.File(file);
newFile.metadata = {
ticketId: ticket
};
Images.insert(newFile, function (err, fileObj) {
if (!err) {
console.log(fileObj);
}
});
}
});
Template.photos.helpers({
images: function () {
return Images.find(); // Where Images is an FS.Collection instance
}
});
}