I'm creating my first website and I'm trying to create a user system. I've managed to upload images as files to parse, now I want to take it to the next level and let users crop the image before upload.
The problem is that you can't custom your input fields because of security issues. So I'd need a way to convert an image src to the "input:file" value to be able to submit it to parse. The following code is a snippet of my full code, however this is what is highlighted for this issue.
PS I am using cropit.( http://scottcheng.github.io/cropit/ )
HTML
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<label style="color:white; display:block;">Profile Picture:</label>
<img id="target" src="#" style="float:left; display:none;">
<div class="image-editor">
<input type="file" id="imageSubmit" class="cropit-image-input">
<div class="cropit-image-preview"></div>
<div class="image-size-label">
Resize image
</div>
<input type="range" class="cropit-image-zoom-input">
<button class="export" style="color:black">Export</button>
</div>
</div>
</div>
JS
$(function() {
$('.image-editor').cropit({
imageState: {
src: '',
},
});
$('.export').click(function() {
var imageData = $('.image-editor').cropit('export');
$('#target').toggle();
$('#target').attr('src', imageData);
$('.image-editor').toggle();
});
});
SIGNUP CODE
$scope.signUp = function(form){
// Upload image
var fileUploadControl = $("#imageSubmit")[0];
if (fileUploadControl.files.length > 0) {
var file = fileUploadControl.files[0];
var name = "displayPhoto.jpg";
var parseFile = new Parse.File(name, file);
}
parseFile.save().then(function() {
alert('success');
}, function(error) {
alert('fail');
});
var user = new Parse.User();
user.set("email", form.email);
user.set("username", form.username);
user.set("password", form.password);
user.set("picture", parseFile);
user.signUp(null, {
success: function(user){
$scope.scenario = '';
$scope.currentUser = user;
$scope.clearFields();
$scope.$apply();
},
error: function(user, error) {
$scope.displayError(true, error.message, error.code);
}
});
};
So I'd need the src from #target to be copied into the #imageSubmit input to be able to upload my file. I just can't find a way to do this.
Here's a fiddle for the whole experiment. (This opens the SRC in a new window, I've redirect it to an img tag, it's the image that pops up in a new window that I do want to save into parse)
https://jsfiddle.net/lilput/hfa6t6nj/2/
Very thankful for answers!! Cheers :)
SOLVED!!!! Thanks to Aaron Saunders
For anyone who has the same problem. All I did was to remove this whole chunk of code in my signup function:
// Upload image
var fileUploadControl = $("#imageSubmit")[0];
if (fileUploadControl.files.length > 0) {
var file = fileUploadControl.files[0];
var name = "displayPhoto.jpg";
var parseFile = new Parse.File(name, file);
}
parseFile.save().then(function() {
alert('success');
}, function(error) {
alert('fail');
});
And replaced it with this:
// Upload image
var file = new Parse.File("placeholder.txt", { base64: imageData });
file.save().then(function() {
alert('success');
}, function(error) {
alert('fail');
});
Upload the base64 image, I believe that is what you get back from the cropit plugin.
var file = new Parse.File("myfile.txt", { base64: imageData });
Related
What I am trying to do : I have a cloud page where the user can upload CSV file. When user clicks on the “upload” button the a function called getBase64() is called (please refer the below code). The getBase64() function will encode the uploaded file and post it to a second cloud page.The second cloud page then takes the posted data.
Note: I am trying to adapt this solution to my need (csv file) by referring to this article partially https://sfmarketing.cloud/2020/02/29/create-a-cloudpages-form-with-an-image-file-upload-option/
What’s the problem : When I try to click the the “upload” button the page is not taking me to the second CloudPage. Please could anyone let me know what I am doing wrong here ?
Here is the code:
CloudPage 1
<input id="file" type="file" accept=".csv">
<br>
<button id="button">Upload</button>
<script runat="client">
document.getElementById("button")
.addEventListener("click", function() {
var files = document.getElementById("file").files;
if (files.length > 0) {
getBase64(files[0]);
}
});
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
//prepare data to pass to processing page
var fileEncoded = reader.result;
var base64enc = fileEncoded.split(";base64,")[1];
var fullFileName = document.getElementById("file").files[0].name;
var fileName = fullFileName.split(".")[0];
var assetName = fullFileName.split(".")[1];
fetch("https://cloud.link.example.com/PAGE2", { //provide URL of the processing page
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
base64enc: base64enc,
fileName: fileName,
assetName: assetName
})
})
.then(function(res) {
window.alert("Success!");
})
.catch(function(err) {
window.alert("Error!");
});
};
reader.onerror = function(error) {
console.log('Error: ', error);
};
}
</script>
CloudPage 2
<script runat="server">
var jsonData = Platform.Request.GetPostData();
var obj = Platform.Function.ParseJSON(jsonData);
</script>
I do not see any errors in the code and when I click on the upload button I get a success message but it does not take me to the second page. Please can anyone guide me how to retrieve this posted data in second page as I am not able to get the encoded data in page 2?
How can take the byte array data of selected file? from select event i can get e.files[0].rawFile but i cannot find where is stored the byte[]. i want this data on client side
I found the documentation pretty poor on this matter as well. The documentation is geared at using a REST endpoint to do server side processing of the file. Most of the examples of client side processing are just for showing the file names, which isn't super useful if you want to do any meaningful client-side validation of the content of the file. In my case, I have CSV files I want to do some pre-processing on the client side. The trick is you need to use the HTML5 a FileReader. Here is an example in AngularJS where $ctrl.fileContent will have the content of a CSV file.
controller: ['$scope', function ($scope) {
var $ctrl = this;
// function called by kendo upload component
$ctrl.onSelect = function(e) {
var message = e.files.map(function(file) {
return $ctrl.readFile(file);
}).join(', ');
// log file names being uploaded
console.log('event :: files select (' + message + ')');
};
// read file and do basic validation
$ctrl.readFile = function(file) {
var reader = new FileReader();
reader.onload = function(e) {
var text = reader.result;
console.log('File contents :: ' + text);
$ctrl.fileContent = text;
};
reader.readAsText(file.rawFile);
// return file name
return file.name;
};
// function called by kendo upload component
$ctrl.onUpload = function(e) {
// todo
console.log('Uploading file');
console.log($ctrl.fileContent);
};
}]
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="content-panel">
<div class="row">
<div class="form-group col-lg-3 col-md-3 col-sm-6 col-xs-12">
<h4>Upload CSV files</h4>
<input name="files"
type="file"
kendo-upload
k-async="{ saveUrl: '$ctrl.save', removeUrl: 'remove', autoUpload: false }"
k-select="$ctrl.onSelect"
k-validation="{ allowedExtensions: ['csv']}"
k-upload="$ctrl.onUpload"
/>
</div>
</div>
</div>
try something like this:
function(data) {
data = btoa(data);
var bytesArr = [];
for(var i = 0; i < data.length; i++) {
bytesArr.push(data.charCodeAt(i));
}
return new Uint8Array(bytesArr);
}
I wanna add new Object that containing an Image in one of its columns , but it dose not save My Pic , Is there any mistake in my code ? specially part of saving Image !!
My JavaScript where the problem appeared:
It never upload my pic in parse !!
<script type="text/javascript">
Parse.initialize("key", "key");
var products = Parse.Object.extend("products");
var fileUploadControl = $("#profilePhotoFileUpload")[0];
if (fileUploadControl.files.length > 0) {
var file = fileUploadControl.files[0];
var name = "photo.png";
var parseFile = new Parse.File(name, file);
}
parseFile.save().then(function() {
//The file has been saved to Parse.
}, function(error) {
// The file either could not be read, or could not be saved to Parse.
});
</script>
Here I added html line to upload file:
<input type="file" id="profilePhotoFileUpload">
I got the answer I am sharing it with you maybe someone get benefit
The THML line to upload file is:
<input type="file" id="pic">
The code in <script> to get and save image in parse is :
var fileUploadControl = $("#pic")[0];
if (fileUploadControl.files.length > 0) {
var file = fileUploadControl.files[0];
var name = "photo.png";
var parseFile = new Parse.File(name, file);
//put this inside if {
parseFile.save().then(function() {
// The file has been saved to Parse.
}, function(error) {
// The file either could not be read, or could not be saved to Parse.
});
// Be sure of ur parameters name
// prod is extend of my class in parse from this: var prod = new products();
prod.set("picture", parseFile);
prod.save();
}
Check the documentation here (at the end of that section, just before the one about retrieving files). Basically the issue is that like any other Parse object you need to save it first, then after the save is complete you can use it.
Create the file, save it, and in the save success handler you can then save the object with the reference to the file.
UPDATE: here's how your code above could be fixed:
Parse.initialize("key", "key");
var products = Parse.Object.extend("products");
var base64 = "V29ya2luZyBhdCBQYXJzZSBpcyBncmVhdCE=";
var file = new Parse.File("mypic.png", { base64: base64 });
file.save({
success: function(file) {
alert('File saved, now saving product with file reference...');
var prod = new products();
// to fill the columns
prod.set("productID", 1337);
prod.set("price", 10);
//I guess it need some fixing here
prod.set("picture", file);
prod.set("productName", "shampoo");
prod.set("productDescribe", "200 ml");
prod.save(null, {
success: function(prod) {
// Execute any logic that should take place after the object is saved.
alert('New object created with objectId: ' + prod.id);
},
error: function(error) {
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and description.
alert('Failed to create new object, with error code: ' + error.description);
}
});
},
error: function(error) {
alert('Failed to save file: ' + error.description);
}
});
I'm trying to get image as Object of javascript on the client side to send it using jQuery
<html>
<body>
<script language="JavaScript">
function checkSize()
{
im = new Image();
im.src = document.Upload.submitfile.value;
if(!im.src)
im.src = document.getElementById('submitfile').value;
alert(im.src);
alert(im.width);
alert(im.height);
alert(im.fileSize);
}
</script>
<form name="Upload" action="#" enctype="multipart/form-data" method="post">
<p>Filename: <input type="file" name="submitfile" id="submitfile" />
<input type="button" value="Send" onClick="checkSize();" />
</form>
</body>
</html>
But in this code only alert(im.src) is displaying src of file but alert(im.width),alert(im.height),alert(im.filesize) are not working properly and alerting 0, 0, undefined respectively. Kindly tell me how I can access image object using javascript?
The reason that im.fileSize is only working in IE is because ".fileSize" is only an IE property. Since you have code that works in IE, I would do a check for the browser and render your current code for IE and try something like this for other browsers.
var imgFile = document.getElementById('submitfile');
if (imgFile.files && imgFile.files[0]) {
var width;
var height;
var fileSize;
var reader = new FileReader();
reader.onload = function(event) {
var dataUri = event.target.result,
img = document.createElement("img");
img.src = dataUri;
width = img.width;
height = img.height;
fileSize = imgFile.files[0].size;
alert(width);
alert(height);
alert(fileSize);
};
reader.onerror = function(event) {
console.error("File could not be read! Code " + event.target.error.code);
};
reader.readAsDataURL(imgFile.files[0]);
}
I haven't tested this code but it should work as long as I don't have some typo. For a better understanding of what I am doing here check out this link.
This is what I use and it works great for me. I save the image as a blob in mysql. When clicked, the file upload dialog appears, that is why i set the file input visibility to hidden and set its type to upload image files. Once the image is selected, it replaces the existing one, then I use the jquery post method to update the image in the database.
<div>
<div><img id="logo" class="img-polaroid" alt="Logo" src="' . $row['logo'] . '" title="Click to change the logo" width="128">
<input style="visibility:hidden;" id="logoupload" type="file" accept="image/* ">
</div>
$('img#logo').click(function(){
$('#logoupload').trigger('click');
$('#logoupload').change(function(e){
var reader = new FileReader(),
files = e.dataTransfer ? e.dataTransfer.files : e.target.files,
i = 0;
reader.onload = onFileLoad;
while (files[i]) reader.readAsDataURL(files[i++]);
});
function onFileLoad(e) {
var data = e.target.result;
$('img#logo').attr("src",data);
//Upload the image to the database
//Save data on keydown
$.post('test.php',{data:$('img#logo').attr("src")},function(){
});
}
});
$('#imagess').change(function(){
var total_images=$('#total_images').val();
var candidateimage=document.getElementById('imagess').value;
formdata = false;
var demo=document.getElementById("imagess").files;
if (window.FormData) {
formdata = new FormData();
}
var i = 0, len = demo.length, img, reader, file;
for ( ; i < len; i++ ) {
file = demo[i];
if (file.type.match(/image.*/)) {
if (formdata) {
formdata.append("images", file);
}
}
}
$('#preview').html('Uploading...');
var url=SITEURL+"users/image_upload/"+total_images;
$.ajax({
url: url,
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
$('#preview').html('');
if (res == "maxlimit") {
alert("You can't upload more than 4 images");
}
else if (res == "error") {
alert("Image can't upload please try again.")
}
else {
$('#user_images').append(res);
}
}
});
});
I'm using Parse.com to build a JavaScript app, and I need to upload photos. I have a form which allows users to select the image on their filesystem, but what do I do with it next? I can't find any documentation for this on the Parse site (not for the JavaScript SDK, anyway).
Here's a quick example on how to upload an image:
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.2.15.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// ***************************************************
// NOTE: Replace the following your own keys
// ***************************************************
Parse.initialize("YOUR_APPLICATION_ID", "YOUR_CLIENT_ID");
function saveJobApp(objParseFile)
{
var jobApplication = new Parse.Object("JobApplication");
jobApplication.set("applicantName", "Joe Smith");
jobApplication.set("profileImg", objParseFile);
jobApplication.save(null,
{
success: function(gameScore) {
// Execute any logic that should take place after the object is saved.
var photo = gameScore.get("profileImg");
$("#profileImg")[0].src = photo.url();
},
error: function(gameScore, error) {
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and description.
alert('Failed to create new object, with error code: ' + error.description);
}
});
}
$('#profilePhotoFileUpload').bind("change", function(e) {
var fileUploadControl = $("#profilePhotoFileUpload")[0];
var file = fileUploadControl.files[0];
var name = file.name; //This does *NOT* need to be a unique name
var parseFile = new Parse.File(name, file);
parseFile.save().then
(
function()
{
saveJobApp(parseFile);
},
function(error)
{
alert("error");
}
);
});
});
</script>
<body>
<input type="file" id="profilePhotoFileUpload">
<img id="profileImg"/>
</body>