What I'm trying to do is to display and modify the images that the car has "in my case", so I used the vue-upload-multiple-image package to save the images and went well, but when I call back these images to the same package I got stuck.
I convert the images that has been stored to base64 now what I want is the list of images go to specific function inside that package, so it will display the images when I try to update the car.
This is the function I want to call:
createImage(file) {
let reader = new FileReader()
let formData = new FormData()
formData.append('file', file)
reader.onload = e => {
let dataURI = e.target.result
if (dataURI) {
if (!this.images.length) {
this.images.push({
name: file.name,
path: dataURI,
highlight: 1,
default: 1,
})
this.currentIndexImage = 0
} else {
this.images.push({
name: file.name,
path: dataURI,
highlight: 0,
default: 0,
})
}
this.$emit(
'upload-success',
formData,
this.images.length - 1,
this.images,
)
}
}
reader.readAsDataURL(file)
},
The Function inside this file
I tried to console.log the function normally it outputs undefined,
I think of props but how it gonna help me.
mounted(){
console.log(this.createImage);
What I want is just to call this function inside my editcar component and sent to it the converter images.
Thank you for helping me and read the this far.
I Found the solution of the problem: in the doc there is dataImages prop. I use it like this:
<div class="form-group m-form__group">
<vue-upload-multiple-image
#upload-success="uploadImageSuccess"
#before-remove="beforeRemove"
#edit-image="editImage"
:dataImages="images"
></vue-upload-multiple-image>
</div>
And it must the images base64 so here is the function the the data.
data() {
return {
images :[],
}
},
mounted() {
this.ConvertImages();
},
This is methods:
methods: {
ConvertImages() {
let images = this.car.images
let image = this.images
for (var i = 0; i < images.length; i++) {
this.toDataURL(images[i].path, function(dataURL) {
image.push({
path: dataURL,
})
})
}
},
toDataURL(url, callback) {
var xhr = new XMLHttpRequest()
xhr.onload = function() {
var reader = new FileReader()
reader.onloadend = function() {
callback(reader.result)
}
reader.readAsDataURL(xhr.response)
}
xhr.open('GET', url)
xhr.responseType = 'blob'
xhr.send()
},
}, //END OF METHODS
Related
I have a vue app with
data: function() {
return {
modules: [],
...
And method:
methods: {
submitted: function(){
...
axios({method: 'get',
url: 'http://' + document.location.host + '/api/execute?commands=' + encodeURI(JSON.stringify(commands)),
responseType: "blob"}).then(response => {
if (response.headers['content-type'] === 'image/jpeg'){
this.modules[current]['results']['image']['visible'] = true
this.modules[current]['results']['text']['visible'] = false
const url = window.URL.createObjectURL(response.data)
this.modules[current]['results']['image']['value'] = url
}
else{
this.modules[current]['results']['image']['visible'] = false
this.modules[current]['results']['text']['visible'] = true
var reader = new FileReader();
reader.onload = function(e) {
// reader.result contains the contents of blob as a typed array
console.log(e)
this.modules[current]['results']['text']['value'] = reader.result
}
reader.readAsArrayBuffer(response.data);
}
...
This should request some data from server and show it as text or image depending on server response.
*v-for module in modules earlier*
<div class="resultText" :visibility=module.results.text.visible>
{{ module.results.text.value }}
</div>
<div class="resultImage" :visibility=module.results.image.visible>
<img :src=module.results.image.value>
</div>
But the method gives js error when text returned: TypeError: this.modules is undefined
The error in this string:
this.modules[current]['results']['text']['value'] = reader.result
With images it works fine.
With self.modules it gives same: TypeError: self.modules is undefined
Solved the problem with:
response.data.text().then(text => {
this.modules[current]['results']['text']['value'] = text
});
I'm trying to upload image using vue.js in Laravel for that i'm using this link
https://jsfiddle.net/b412ruzo/
to upload image using vue.js and when i submit the form i'm getting following image in files array
now issue is that i cannot get this file array in laravel controller
when i print
$request->file('files')
in my controller i am getting null.
and when i print $request->input('files') this is the result, an empty array
Any help regarding this issue is highly appreciated.
Code Snippet :
data() {
return {
rawData: [],
formData: new Form({
files:[],
})
..
const header = {
Authorization: "Bearer " + this.token,
};
this.formData
.post(APP_URL + `/api/post`, { headers: header })
.then((response) => {
}
not sure you can send ajax request via this.formData.post
try this
new Vue({
el: "#app",
data() {
return {
option: {
maxFileCount: 3
},
files:[],
rawData: [],
}
},
methods: {
loaddropfile: function(e) {
e.preventDefault()
e.stopPropagation()
alert('ok')
console.log(e)
},
openinput: function() {
document.getElementById("vue-file-upload-input").click();
},
addImage: function(e) {
const tmpFiles = e.target.files
if (tmpFiles.length === 0) {
return false;
}
const file = tmpFiles[0]
this.files.push(file)
const self = this
const reader = new FileReader()
reader.onload = function(e) {
self.rawData.push(e.target.result)
}
reader.readAsDataURL(file)
},
removeFile: function(index) {
this.files.splice(index, 1)
this.rawData.splice(index, 1)
document.getElementById("vue-file-upload-input").value = null
},
upload: function() {
alert('Check console to see uploads')
console.log(this.files)
axios.post(`${APP_URL}/api/post`,{files:this.files},{ headers: header })
.then((response) => {});
}
},
mounted(){
}
})
it will send your form data to files key so you can get all the files via $request->file('files')
i am using react quill editor for my project and using my backend server to image upload but i need to access props inside the image handler of react quill and i am unable to do so as not able to access this object inside image handler.
here is my editor code.
<ReactQuill
ref={(el) => (this.quillRef = el)}
onChange={this.handleChange}
placeholder={"share your thoughts"}
modules={{
toolbar: {
container: [
[{ header: "1" }, { header: [2, 3, 4, 5, 6] }, { font: [] }],
[{ size: ["small", false, "large", "huge"] }],
["bold", "italic", "underline", "strike", "blockquote"],
[{ list: "ordered" }, { list: "bullet" }],
["link", "image", "video"],
["clean"],
["code-block"],
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
[{ align: [] }],
],
handlers: {
image: this.imageHandler,
},
},
}}
/>;
function imageHandler() {
let self = this;
let image;
let image_extension;
const Cryptr = require("cryptr");
const cryptr = new Cryptr(key);
const users = localStorage.getItem("users")
? JSON.parse(cryptr.decrypt(localStorage.getItem("users")))
: {};
// console.log(users[users.lastLoginId])
let loggedinUser = users[users.lastLoginId];
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.setAttribute("class", "Editor-mage");
input.click();
input.onchange = async () => {
//debugger
const file = input.files[0];
var ValidImageTypes = [
"image/gif",
"image/jpeg",
"image/png",
"image/jpg",
"image/GIF",
"image/JPEG",
"image/PNG",
"image/JPG",
];
let file_type = file.type;
let filename = file.name;
let extension = filename.split(".").pop();
if (ValidImageTypes.indexOf(file_type) >= 0) {
if (true) {
var fileToLoad = file;
loadImage(
fileToLoad,
(canvas) => {
if (canvas) {
// this.setState({
image = canvas.toDataURL();
image_extension = extension;
//});
const res = new Promise(function (resolve, reject) {
axios({
method: "post",
url: API_URL + "api/v1/postblogimage",
headers: {
"x-access-handler": loggedinUser.token,
},
data: {
image: image,
image_extension: image_extension,
userid: loggedinUser.userid,
},
})
//axios.post(API_URL + 'api/v1/postblogimage', formData, config)
.then((response) => {
//debugger
if (
response.data.error == "false" ||
response.data.error == false
) {
if (
response.data.status == 200 &&
response.data.message == "Image uploaded successfully"
) {
//debugger
const range = self.quill.getSelection(true);
// Insert temporary loading placeholder image
// this.quill.insertEmbed(range.index, 'image', `${window.location.origin}/images/loaders/placeholder.gif`);
// Move cursor to right side of image (easier to continue typing)
self.quill.setSelection(range.index + 1);
// Remove placeholder image
self.quill.deleteText(range.index, 1);
// Insert uploaded image
let url = response.data.data[0].imageURL;
self.quill.insertEmbed(range.index, "image", url);
self.quill.pasteHTML(
range.index,
<img
src={url}
class="blog-image-content"
alt="Responsive image"
/>
);
}
}
// }
})
.catch((error) => {
// reject(Error("It broke"));
});
});
}
},
{ orientation: true }
);
} else {
// this.setState({
// image_warning:'File size larger than maximum allowed limit',
image = "";
image_extension = "";
// })
this.fileInput.value = "";
}
} else {
}
};
}
can someone please help me out with this one as i am stuck for long on this.
any help and suggestion will be greatly appreciated.
I read the documentation of Quilljs.
Handler functions will be bound to the toolbar (so using this will refer to the toolbar instance) and passed the value attribute of the input if the corresponding format is inactive, and false otherwise. Adding a custom handler will overwrite the default toolbar and theme behavior.
and found out the imageHandler will be called in the context of the toolbar, so this.props will not work as intended when it is called.
so to achieve the accesss to props , you can do something like this:
handlers: {
image: (val) => this.imageHandler({ val, componentProps: this.props });
}
In the imageHandler you can access it like this:
function imageHandler({ val, componentProps }) {
// componentProps has all your propss, try to print it and see
// rest of your code, instead of this.props.something take componentProps.something
}
Let me know if it helps. Thanks
I think you can use higher order function.
image: this.imageHandler(props)
...
function imageHandler(props) {
return function() {
let self = this;
let image;
...
}
}
so I've been trying to upload multiple image file using Vue JS with Laravel at server side.
My template vue
<input type="file" id = "file" ref="file" v-on:change="onImageChange" multiple />
My Javascript code
<script>
export default {
data(){
return{
product: {},
image: '',
}
},
created() {
let uri = `/api/product/edit/${this.$route.params.id}`;
this.axios.get(uri).then((response) => {
this.product = response.data;
});
},
methods:{
onImageChange(e){
let files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file){
let reader = new FileReader();
let vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
replaceByDefault(e) {
e.target.src = this.src='/uploads/products/default_image.jpg';
},
saveImage(e){
e.preventDefault()
var file = document.getElementById('file').files;
let formData = new FormData;
formData.append('productId', this.product.id)
formData.append('file', file[0])
axios.post('/api/product/image/add', formData, {
headers: {'Content-Type': 'multipart/form-data'}
}).then((response) => {
this.$router.push({name: 'view',params: { id: this.product.id }});
});
}
}
}
</script>
I saw somewhere the internet that in vue you can use looping the formData.append but how do i catch the data in the server side. Here is my ProductController
$saveImage = new Gallery;
$saveImage->product_id = $request->productId;
$file = request()->file('file');
$file_name = time().$file->getClientOriginalName();
$path = $imgUpload = Image::make($file)->save(public_path('/uploads/products/' . $file_name));
$saveImage->path = '/uploads/products/'.$file_name;
$saveImage->status = 1;
$saveImage->save();
return "success";
Thank you very much guys!
you can use request()->file('file') to get files. but you have to add some changes in your vue source when you are trying to send an array of files.
Vue
let formData = new FormData;
formData.append('productId', this.product.id)
// append files
for(let i=0; i<file.length; i++){
formData.append('file[]', file[i])
}
useing file[] instead of file will generate an array of files in request payload.
then in laravel side of code you can use request()->file('file') to get that array of files. but if you want just one of them (for example: first one) you can use request()->file('file.0') to get that file.
I'm trying to retrieve file information from input field of type="file" in my Vuejs application. I'm having a render function which renders the input fields something like this and calls a function on input, code as below:
input: (event) => {
var reader = new FileReader()
reader.readAsDataURL(event.target.files[0])
let baseFile = ''
reader.onload = function () {
baseFile = reader.result
console.log(baseFile)
};
console.log(baseFile)
const docs = {
name: event.target.files[0].name,
size: event.target.files[0].size,
lastModifiedDate: event.target.files[0].lastModifiedDate,
base64: baseFile
}
this.$emit('input', docs)
}
When I run this function console.log inside my reader.onload function gives me converted files but when I do console outside of it, the value is just an empty string. How I can I retrieve and assign to my const docs variable. Help me out with this. Thanks.
I recommend to put the rest of code inside the block of that function after changing it to an arrow function as follows :
input: (event) => {
var reader = new FileReader()
reader.readAsDataURL(event.target.files[0])
let baseFile = ''
reader.onload = () => {// <------ use arrow function
baseFile = reader.result
const docs = {
name: event.target.files[0].name,
size: event.target.files[0].size,
lastModifiedDate: event.target.files[0].lastModifiedDate,
base64: baseFile
}
this.$emit('input', docs)
};
}