I'm new to Ember.js and I'm stuck with a problem I need to save the uploaded image in db but I dont know how to do that I wrote code for upload the image but i'm stuck with passing it to the server my current code is given below
App.js
App = Ember.Application.create();
App.PreviewImageView = Ember.View.extend({
attributeBindings: ['name', 'width', 'height', 'src'],
tagName: 'img',
viewName: 'previewImageView',
printme: function () {
console.log('in previewImageView');
}
});
App.FileField= Ember.TextField.extend({
type: 'file',
attributeBindings: ['name'],
change: function (evt) {
var input = evt.target;
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
this.$().parent(':eq(0)').children('img:eq(0)').attr('src', e.target.result);
var view = that.getPath('parentView.previewImageView');
view.set('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
});
html
<script type="text/x-handlebars">
{{view App.FileField name="logo_image" contentBinding="content"}}
{{view App.PreviewImageView width="200" height="100" }}
</script>
I think you can mix some traditional MVC methods to solve your problem. from your current code I can assume that showing a preview of the image is completed so to get that file in server side just use the following code in your html
#using (Html.BeginForm("FileUpload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" {{view Wizard.FileField contentBinding="content"}} />
<input type="submit" id="btnUpload" value="Upload" />
}
and In you controller method you can access the file like this
public ActionResult FileUpload(HttpPostedFileBase file)
{
// Do what you want
}
To save the image in db you have to convert it into bytes (sql server 2008 support image now but db like postgresql still need image as bytes) to do that use the following method
MemoryStream target = new MemoryStream();
file.InputStream.CopyTo(target);
byte[] bytes= target.ToArray();
return View();
Assuming you are using ember-data, you can create a model to represent the image and then create/save from the reader's onload callback. For example:
App.LogoImage = DS.Model.extend({
id: DS.attr('number'),
attachment: DS.attr('string')
});
//in App.FileField...
reader.onload = function (e) {
this.$().parent(':eq(0)').children('img:eq(0)').attr('src', e.target.result);
var view = that.getPath('parentView.previewImageView');
view.set('src', e.target.result);
var file = e.srcElement.result;
var logo = App.LogoImage.createRecord({ attachment: file });
logo.save();
}
Related
I'm having a hard time getting anything to work with this the way I need it, but I have a working dropzone instance in my Vue project.
I can upload the image and call functions within the dropzone code, however, I need to call a function directly from the form in the html in order to send the 'card' object.
All I need to do is call a function when a file is added through the dropzone form, with the filename.
My code:
<div class="uk-width-3-10">
<form v-on:change="imageChange(card)" method="post" action="{{url('product/parts/upload/store')}}" enctype="multipart/form-data"
class="dropzone" v-bind:id="'dropzone-'+i">
</form>
</div>
...
imageChange(Card){
console.log('working');
},
addCard(){
Vue.nextTick(function () {
new Dropzone("#dropzone-"+cardIndex, {
maxFilesize: 12,
renameFile: function (file) {
var dt = new Date();
var time = dt.getTime();
return time + file.name;
},
acceptedFiles: ".jpeg,.jpg,.png,.gif",
addRemoveLinks: true,
timeout: 50000,
removedfile: function (file) {
console.log(file.upload.filename);
var name = file.upload.filename;
var fileRef;
return (fileRef = file.previewElement) != null ?
fileRef.parentNode.removeChild(file.previewElement) : void 0;
},
init: function() {
this.on("addedfile",
function(file) {
instance.imageZoneNames.push({name: file.upload.filename});
console.log(file);
console.log(instance.imageZoneNames);
});
}
});
});
}
Dropzone has many events, You used removedfile() event! there is another event called addedfile() and executes when a file is added to the dropzone list
imageChange(card) {
console.log(card)
},
addCard() {
Vue.nextTick(() => {
new Dropzone('#dropzone-` + cardIndex, {
addedfile(file) {
this.imageChange(file);
}
}
}
}
In #vue/cli 4.1.1 app I use bootstrap-vue and b-form-file conponent for images uploading
https://bootstrap-vue.js.org/docs/components/form-file/#multiple-files
with definition :
<b-form-file
id="upload_ad_image"
v-model="new_upload_ad_image"
:state="Boolean(new_upload_ad_image)"
placeholder="Choose a file or drop it here..."
drop-placeholder="Drop file here..."
accept="image/jpeg, image/png, image/gif"
></b-form-file>
<div ref="uploaded_img_preview" id="uploaded_img_preview" class="m-2" >Uploaded image preview :</div>
I found snippet https://codepen.io/Tenderfeel/pen/rgqWXR
and using it I show selected file on my form for preview.
Next I need to upload it on the server. I have an expierence of uploading image as blog using code like :
fetch(this.taskRow.imageFile.blob).then(function (response) {
if (response.ok) {
return response.blob().then(function (imageBlob) {
let imageUploadData = new FormData()
imageUploadData.append('id', self.taskRow.id)
imageUploadData.append('image', imageBlob)
imageUploadData.append('image_filename', self.taskRow.imageFile.name)
But I need to convert uploading image to blob. I use method when image is selected:
But got error : Error in callback for watcher "new_upload_ad_image": "InvalidStateError: Failed to execute 'readAsDataURL' on 'FileReader': The object is already busy reading Blobs
watch: {
new_upload_ad_image(val) {
if (!val) return;
if (this.previewImg) {
this.previewImg.remove();
}
const img = document.createElement("img");
img.classList.add("obj");
img.file = this.new_upload_ad_image;
console.log('img.file::')
console.log(img.file)
this.previewImg = img;
console.log('this.$refs.uploaded_img_preview::')
console.log(this.$refs.uploaded_img_preview)
console.log('img::')
console.log(img)
this.$refs.uploaded_img_preview.appendChild(img);
const fileReader = new FileReader();
fileReader.onload = (e) => {
this.previewImg.src = e.target.result;
};
fileReader.readAsDataURL(this.new_upload_ad_image);
console.log('fileReader::')
console.log(fileReader)
let blobObj= fileReader.readAsDataURL(img.file) // RAISE ERROR :
console.log('blobObj::')
console.log(blobObj)
}
},
What I see in the console : https://imgur.com/a/2EZxq9C
How to get blob and upload it on server?
MODIFIED BLOCK :
having file input with id="upload_ad_image" defined :
<b-form-file
id="upload_ad_image"
v-model="new_upload_ad_image"
:state="Boolean(new_upload_ad_image)"
placeholder="Choose a file or drop it here..."
drop-placeholder="Drop file here..."
accept="image/jpeg, image/png, image/gif"
></b-form-file>
I run fetch and see that image blob is invalid and file is created, but it is invalid
I have :
var self = this
const upload_ad_image = document.getElementById('upload_ad_image')
console.log('upload_ad_image::')
console.log(upload_ad_image)
console.log('upload_ad_image.files::')
console.log(upload_ad_image.files[0])
if (typeof upload_ad_image.files[0] == 'undefined') {
self.showPopupMessage('Ad image upload', 'Invalid image !', 'warn')
return
}
fetch(upload_ad_image.files[0].blob).then(function (response) {
if (response.ok) {
return response.blob().then(function (imageBlob) {
console.log('imageBlob::')
console.log(imageBlob) // Looks like this var has invalid content(printscreen below)!
let imageUploadData = new FormData()
imageUploadData.append('ad_id', self.editableAd.id)
imageUploadData.append('main', self.new_upload_ad_image_main)
imageUploadData.append('info', self.new_upload_ad_image_info)
imageUploadData.append('image', imageBlob)
imageUploadData.append('image_filename', upload_ad_image.files[0].name)
I see in console : https://imgur.com/a/4ees55C
What is wrong and how it can be fixed ?
"bootstrap-vue": "^2.3.0",
"vue": "^2.6.11",
Thanks!
File objects do inherit from the Blob interface.
All you can do with a Blob, you can also do it with a File, so in your code you can directly append this.new_upload_ad_image to your FormData.
const inp = document.getElementById('inp');
inp.onchange = (evt) => {
const formData = new FormData();
formData.append( 'my-file', inp.files[0], 'file.ext' );
// check it's correctly in the FormData
console.log( [...formData.entries()] );
};
<input type="file" id="inp">
I'm using vue.js & element-ui to upload files and preview files. I want to preview file(.pdf/.docx/.jpg...) before uploaded to server.
<el-upload
ref="uploadFile"
:on-change="onUploadChange"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-remove="beforeRemove"
:file-list="fileList"
:http-request="handleUpload"
:data="extendData"
:auto-upload="false"
class="upload-demo"
drag
action="uploadUrl"
multiple>
<i class="el-icon-upload"/>
<div class="el-upload__text">drag here, or <em>click to upload</em></div>
</el-upload>
Only the on-change function can get the content of the file, while the on-preview function only get the meta message. How to get the file content and preview that before which is uploaded to server?
It's not the meta, it's the file. So you need to use a FileReader on the file:
handlePreview(file) {
const reader = new FileReader()
reader.onload = e => console.log(e.target.result) // here is the result you can work with.
reader.readAsText(file)
}
I am also using Element-UI upload box, the following code allow user to import a JSON file to Vue, and preview its content in a new window when clicking the file name. The file is read and stored as object in data during on-change, then
Vue component:
<el-upload class="upload-box" drag action="" :auto-upload="false" :on-change="handleImport" :on-preview="handlePreview" :limit="1" :on-exceed="handleExceed">
<i class="el-icon-upload"></i>
<div class="el-upload__text">Drop file here or <em>click to upload</em></div>
<div class="el-upload__tip" slot="tip">Single JSON file with size less than 500kb</div>
</el-upload>
Script:
export default {
data() {
return {
uploadFile: null,
fileContent: null,
}
},
methods: {
handleImport(file) {
this.uploadFile = file
let reader = new FileReader()
reader.readAsText(this.uploadFile.raw)
reader.onload = async (e) => {
try {
this.fileContent = JSON.parse(e.target.result)
} catch (err) {
console.log(`Load JSON file error: ${err.message}`)
}
}
},
handlePreview() {
let myWindow = window.open();
myWindow.document.write(JSON.stringify(this.fileContent));
myWindow.document.close();
},
handleExceed(files, fileList) {
this.$message.warning(`The limit is 1, you selected ${files.length + fileList.length} totally, please first remove the unwanted file`);
},
},
}
I have written a functionality where I want to upload a form without using any forms whatsoever, I am calling an ajax event on change event of input type=file with id, I am getting the $_FILES data in ajax file 'upload.php' using POST method using jQuery. The input tag is not inside any form tag. It stands individually. Below is my code:
my plain html input type='file' without form:
<div class="profile_pic">
<img id="upload-button" class="profile-pic img-circle profile_img" src="img/default-image.png" alt="default">
<input class="file-upload" type="file" name="profile_pic" id="profile_pic" />
</div>
My Javascript code is:
var readURL = function(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#upload-button').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$(".file-upload").on('change', function(){
readURL(this);
alert('working');
var file = profile_pic.files[0];
var formData = new FormData();
formData.append('formData', file);
$.ajax({
url: "uploadFile.php",
type: "POST",
processData: false,
contentType: false,
dataType : 'json',
data: formData,
success: function (data) {
alert(data);
}
});
});
$("#upload-button").on('click', function() {
$(".file-upload").click();
});
UploadFile.php code below:
<?php
print_r($_FILES);
?>
the following file data Am getting in alert :
Array
(
[formData] => Array
(
[name]=> Tulips.jpg
[type]=> image/jpeg
[tmp_name]=> chroot/tmp/phpipdF97
[error]=> 0
[size]=> 620888
)
)
how can I access those file data inorder to upload file to a destination folder path using php's move_uploaded_file()? Thanks in advance.
I got the solution. I have accessed the $_FILES values in "uploadFile.php" like below:
$_FILES["formData"]["tmp_name"]
$_FILES["formData"]["name"]
I'd like to hava a Dojo dojox.grid.DataGrid with its data from a servlet.
Problem: The data returned from the servlet does not get displayed, just the message "Sorry, an error has occured".
If I just place the JSON string into the HTML, it works. ARRRRGGH.
Can anyone please help me!
Thanks
Jeff Porter
Servlet code...
public void doGet(HttpServletRequest req, HttpServletResponse resp) {
res.setContentType("json");
PrintWriter pw = new PrintWriter(res.getOutputStream());
if (response != null) pw.println("[{'batchId':'2001','batchRef':'146'}]");
pw.close();
}
HtmL code...
<div id="gridDD" dojoType="dojox.grid.DataGrid"
jsId="gridDD" style="height: 600x; width: 100%;"
store="ddInfo" structure="layoutHtmlTableDDDeltaSets">
</div>
var rawdataDDInfo = ""; // empty at start
ddInfo = new dojo.data.ItemFileWriteStore({
data: {
identifier: 'batchId',
label: 'batchId',
items: rawdataDDInfo
}
});
<script>
function doSelectBatchsAfterDate() {
var xhrArgs = {
url: "../secure/jsonServlet",
handleAs: "json",
preventCache: true,
load: function(data) {
var xx =dojo.toJson(data);
var ddInfoX = new dojo.data.ItemFileWriteStore({data: xx});
dijit.byId('gridDD').setStore(ddInfoX);
},
error: function(error) {
alert("error:" + error);
}
}
//Call the asynchronous xhrGet
var deferred = dojo.xhrGet(xhrArgs);
}
</script>
<img src="go.gif" onclick="doSelectBatchsAfterDate();"/>
When you create the dojo.data.ItemFileWriteStore using the JSON data returned from server. You just provide the items, you still needs to specify the metadata. The correct code should be as below.
var ddInfoX = new dojo.data.ItemFileWriteStore({
data: {
identifier: 'batchId',
label: 'batchId',
items: xx
}
});
And you don't need the dojo.toJson function which converts the JSON object to a JSON string. The dojo.data.ItemFileWriteStore requires a JSON object as the parameter, not a JSON string.