contenteditable to textfile in azure storage in javascript - javascript

i am trying to convert the content of an editable div to a text file and store it in azure. It's actually a css file (format) but i guess that text will have the same output. This is what i got so far:\
var sasKey = "xxxxxxxxxxxxxxx";
var blobUri = xxxxx.blob.core.windows.net";
var blobService = AzureStorage.Blob.createBlobServiceWithSas(blobUri, sasKey);
function Save() {
var blobData = document.getElementById("CONTENT").innerText;
var myBlob = new Blob(blobData, "plain/text");
blobService.createBlockBlobFromBrowserFile('style',
"test.txt",
myBlob,
(error, result) => {
if (error) {
// Handle blob error
} else {
console.log('Upload is successful');
}
});
}
HTML:
<div id="CONTENT" contenteditable="true" spellcheck="false">so here we have text</div>
<input type="button" value="save" onclick="Save()"/>
i get the following error:
Uncaught TypeError: Failed to construct 'Blob': The provided value cannot be converted to a sequence.

The Blobobject takes a list as its first parameter.
Try this instead:
var myBlob = new Blob([blobData], { type: "plain/text" });
https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob

to be complete this is what i used to upload a text (txt) file
<script>azure-storage.blob.min.js</script>
JS
var sasKey = "xxxxxxxxxxxxxxx";
var blobUri = xxxxx.blob.core.windows.net";
var blobService = AzureStorage.Blob.createBlobServiceWithSas(blobUri, sasKey);
function Save() {
var blobData = document.getElementById("CONTENT").innerText;
blobService.createContainerIfNotExists('container', (error, container) => {
if (error) {
// Handle create container error
} else {
console.log(container.name);
}
});
blobService.createBlockBlobFromText('container', "test.txt", blobData,
(error, result) => {
if (error) {
// Handle blob error
} else {
console.log('Upload is successful');
}
});
}
HTML
<div id="CONTENT" contenteditable="true" spellcheck="false">so here we have text</div>
<input type="button" value="save" onclick="Save()"/>

Related

AngularJS + ASP.NET $http.post returning 401

I am trying to add a new Stop to my database. But I get a 401 error in asp.net.
.js file:
(function () {
"use strict";
angular.module("app-trips")
.controller("tripEditorController", tripEditorController);
function tripEditorController($routeParams, $http) {
var vm = this;
vm.tripName = $routeParams.tripName;
vm.stops = [];
vm.newStop = {};
vm.addStop = function () {
alert(vm.newStop.name);
$http.post("/api/trips/" + vm.tripName + "/stops", vm.newStop)
.then(function (response) {
vm.stops.push(vm.newStop);
};
}
}
.html file (input form):
<form novalidate name="newStopForm" ng-submit="vm.addStop()">
<div class="form-group">
<label for="">Date</label>
<input class="form-control" id="arrival" name="arrival" ng-model="vm.newStop.arrival" required />
</div>
<div class="form-group">
<label>Location</label>
<input class="form-control" id="name" name="name" ng-model="vm.newStop.name" required ng-minlength="3" />
</div>
<div>
<input type="submit" value="Add" class="btn btn-success" ng-disabled="newStopForm.$invalid" />
</div>
</form>
C# Post code:
[HttpPost("/api/trips/{tripName}/stops")]
public async Task<IActionResult> Post(string tripName, [FromBody]StopViewModel vm)
{
try
{
if (ModelState.IsValid)
{
var newStop = Mapper.Map<Stop>(vm);
var result =await _coordsService.GetCoordsAsync(newStop.Name);
if (!result.Succes)
{
_logger.LogError(result.Message);
}
else
{
newStop.Latitude = result.Latitude;
newStop.Longitude = result.Longitude;
}
_repository.AddStop(tripName, newStop, User.Identity.Name);
if (await _repository.SaveChangesAsync())
{
return Created($"/api/trips/{tripName}/stops/{newStop.Name}",
Mapper.Map<StopViewModel>(newStop));
}
}
}
catch (Exception ex)
{
_logger.LogError("Failed to save new Stop: {0}", ex);
}
return BadRequest("Failed to save new stop");
}
GeoCoordsService.cs:
public async Task<GeoCoordsResult> GetCoordsAsync(string name)
{
var result = new GeoCoordsResult()
{
Succes = false,
Message = "Failed to get coordinates"
};
var apiKey = _config["Keys:BingKey"];
var encodedName = WebUtility.UrlEncode(name);
var url = $"http://dev.virtualearth.net/REST/v1/Locations?q={encodedName}&key={apiKey}";
var client = new HttpClient();
var json = await client.GetStringAsync(url);
var results = JObject.Parse(json);
var resources = results["resourceSets"][0]["resources"];
if (!resources.HasValues)
{
result.Message = $"Could not find '{name}' as a location";
}
else
{
var confidence = (string)resources[0]["confidence"];
if (confidence != "High")
{
result.Message = $"Could not find a confident match for '{name}' as a location";
}
else
{
var coords = resources[0]["geocodePoints"][0]["coordinates"];
result.Latitude = (double)coords[0];
result.Longitude = (double)coords[1];
result.Succes = true;
result.Message = "Success";
}
}
return result;
}
I have read, that this is probably caused because the data is not in the right format, does anyone know what would be the right format, my webpage returns error 400, but deeper in my C# I can see that function var json = await client.GetStringAsync(url);is returning an error 401 (Unotharized). I guess I should also add username somewhere, but I don't know where.
You're getting a 400 because the request you sent isn't what the server is expecting. Find out the object the server is expecting on that endpoint. Then form your request body to match that object.

Uploading a JSON file and using it

How can I upload a JSON file on some click on a button on my web page say "import", and use it to store in a variable to use and update it using JavaScript.
I have gone through the other posts but could not find any answer.
I am saving the JSON variable using this function:
function save(filename, data){
if(!data) {
alert('error : No data')
return;
}
if(typeof data === "object"){
data = JSON.stringify(data, undefined, 4)
}
var blob = new Blob([data], {type: 'text/json'}),
e = document.createEvent('MouseEvents'),
a = document.createElement('a')
a.download = filename
a.href = window.URL.createObjectURL(blob)
a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')
e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
a.dispatchEvent(e)
}
This is working fine and it downloads the file on clicking another button say "export".
How upload this file back and make a JSON variable of this file data?
Without server side code, your best approach may be to provide a textarea element for the user to copy/paste the JSON into, and then parse it using JSON.parse.
You could even go as far as to use something like Ace Editor to provide syntax highlighting for JSON - you can see it in action on the Ace Editor Kitchen Sink Demo - select JSON from the dropdown list in the top left.
Edit:
Turns out I was wrong. Here is a fiddle demonstrating the FileReader in use, which is exactly what you need:
https://jsfiddle.net/Ln37kqc0/
Here is the code:
Javascript:
document.getElementById('import').onclick = function() {
var files = document.getElementById('selectFiles').files;
console.log(files);
if (files.length <= 0) {
return false;
}
var fr = new FileReader();
fr.onload = function(e) {
console.log(e);
var result = JSON.parse(e.target.result);
var formatted = JSON.stringify(result, null, 2);
document.getElementById('result').value = formatted;
}
fr.readAsText(files.item(0));
};
HTML:
<input type="file" id="selectFiles" value="Import" /><br />
<button id="import">Import</button>
<textarea id="result"></textarea>
I have got a way to use the uploaded json file, here is the way i found.
$("#inputFile").change(function(e) {
onChange(e);
});
function onChange(event) {
var reader = new FileReader();
reader.onload = onReaderLoad;
reader.readAsText(event.target.files[0]);
}
function onReaderLoad(event){
//alert(event.target.result);
var obj = JSON.parse(event.target.result);
alert(obj);
}
Basic upload File:
<input id="contentFile" type="file" accept="application/json" />
document.getElementById('contentFile').onchange = function(evt) {
try {
let files = evt.target.files;
if (!files.length) {
alert('No file selected!');
return;
}
let file = files[0];
let reader = new FileReader();
const self = this;
reader.onload = (event) => {
console.log('FILE CONTENT', event.target.result);
};
reader.readAsText(file);
} catch (err) {
console.error(err);
}
}
[2021] Promise based approach
As mentioned here, you can make use of the newer blob api to easily get the file's value via:
await blob.text()
const getJsonUpload = () =>
new Promise(resolve => {
const inputFileElement = document.createElement('input')
inputFileElement.setAttribute('type', 'file')
inputFileElement.setAttribute('multiple', 'true')
inputFileElement.setAttribute('accept', '.json')
inputFileElement.addEventListener(
'change',
async (event) => {
const { files } = event.target
if (!files) {
return
}
const filePromises = [...files].map(file => file.text())
resolve(await Promise.all(filePromises))
},
false,
)
inputFileElement.click()
})
document.getElementById('upload-button').onclick = async () => {
const jsonFiles = await getJsonUpload()
console.log({jsonFiles})
}
<button id="upload-button">
Upload
</button>
Try this, works perfect
handleUploadFile = async(doc) => {
let file = doc.target.files[0]
let reader = new FileReader(file)
// await reader.readAsDataURL(file)
reader.readAsText(file)
reader.onload = async(e) => {
let aaa = e.target.result
let content = await JSON.parse(aaa)
console.log(content)
}
}
With the newer Blob API, the current top answer can be simplified by skipping the FileReader:
document.getElementById('import').onclick = function() {
var files = document.getElementById('selectFiles').files;
console.log(files);
if (files.length <= 0) {
return false;
}
files[0].text().then(function(text) {
console.log(text);
var result = JSON.parse(text);
var formatted = JSON.stringify(result, null, 2);
document.getElementById('result').value = formatted;
})
};
To explain the code a little: files[0] itself is a File object, which inherits from Blob, so files[0].text() is an asynchronous function that reads the content of the file into a string.
You may want to add the draggable option
Firs create your HTML
<div class="drag" id="drag_area">
<input class="box_file disabled" type="file" name="files[]" id="file" data-multiple-caption="{count} files selected" multiple />
<label for="file"><strong>Choose save file</strong><span class="box__dragndrop"> or drag it here</span>.</label>
</div>
Than write out your JS
$("#drag_area").on('drag dragstart dragend dragover dragenter dragleave drop', function (e) {
e.preventDefault();
e.stopPropagation();
})
.on('dragover dragenter', function () {
$("#drag_area").addClass('dr_active');
// this is needed if you wish to style your drag area on drag events
})
.on('dragleave dragend drop', function () {
$("#drag_area").removeClass('dr_active');
// this is needed if you wish to style your drag area on drag events
})
.on('drop', function (e) {
let droppedFiles = e.originalEvent.dataTransfer.files;
let reader = new FileReader()
reader.readAsDataURL(droppedFiles[0])
reader.onloadend = function () {
$.ajax({
url: reader.result,
success: function (data) {
console.log(JSON.parse(data)); // This is your JSON
},
error: function (request, error) {
cliLog(2, "Upload", "Cant upload save file")
}
});
}
}),
I'd made a more general approach with support to customize upload button title and callback when load is done:
function uploadJson(id, callback) {
document.getElementById(id).onchange = function(evt) {
try {
let files = evt.target.files;
if (!files.length) {
alert('No file selected!');
return;
}
let file = files[0];
let reader = new FileReader();
const self = this;
reader.onload = (event) => {
callback(event.target.result);
};
reader.readAsText(file);
} catch (err) {
console.error(err);
}
}
}
uploadJson('importJson', function (json) {
console.log(json);
});
<button onclick="document.getElementById('importJson').click()">import json</button>
<input id="importJson" value="import json" type="file" accept="application/json" style="display:none" />

Parse + Jquery uploading images

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 });

How to zip a pdf or ppt file using jszip?

I want zip a pdf or some other format like excel, ppt etc using jszip.
How to zip this format in jszip?
My code is as below
<BODY>
<a id ='file' href="data/some.pdf" type="application/pdf; length=432628">Some.pdf</a>
<input id="button" type="button" onclick="create_zip()" value="Create Zip"></input>
</BODY>
<SCRIPT>
function create_zip() {
var data = document.getElementById('file');
var zip = new JSZip();
zip.add(data, {base64: true});
content = zip.generate();
location.href = "data:application/zip;base64," + content;
}
</SCRIPT>
What I want is that I will get the path of the file from the a element in the html. I want to zip the pdf using jszip
jsfiddle
JSZipUtils may be useful for you. This is the example for the documentation:
JSZipUtils.getBinaryContent("path/to/picture.png", function (err, data) {
if(err) {
throw err; // or handle the error
}
var zip = new JSZip();
zip.file("picture.png", data, {binary:true});
}
Which can be easily adapted to your case:
function create_zip() {
var url = document.getElementById('file').href;
JSZipUtils.getBinaryContent(url, function (err, data) {
if(err) {
throw err; // or handle the error
}
var zip = new JSZip();
zip.file("Some.pdf", data, {binary:true});
content = zip.generate();
}
}

Uploading a photo from a form using node.js

I'm quite new to node and need some guidance and help. Before I go any further, I'm trying to do this without any other frameworks like Express. The situation is the following:
I've have a form where a user can upload a photo to a server running in node. The form has the following properties
<form action="/newImages/" method="post" enctype="multipart/form-data">
File goes : <input type="file" name="fileName"><br>
<input type="submit" value="Submit">
</form>
The form input is handled by this code
if (req.method == 'POST' && req.url == '/newImages/') {
console.log("Inside Post method");
var body = ''
req.on('data', function(data) {
body += data
})
req.on('end', function() {
var note = querystring.parse(body)
console.log(note)
fs.writeFile("./test.jpg",body, function(err){
if(err)
{
console.log(err);
}
else
{
console.log("The Picture was saved");
}
})
res.writeHead(302, {
'Content-Type':'text/plain',
'location':'/index.html'});
res.end('Found!');
})
}
However, something tells me I need to parse the data differently, as the output of this is unreadable. It looks like :
"\n\r\n����\u0000\u0010JFIF\u0000\u0001\u0001\u0001\u0000\u0000\u0000\u0000��\u0000C\u0000\b\u0006\u0006\u0007\u0006\u0005\b\u0007\u0007\u0007\t\t\b\n\f\u0014\r\f\u000b\u000b"
Any ideas on how to get this to work? I should also note that I upload .jpg's only.
Thanks
I think that you are wrong when you save your picture. You don't need to use fs.writeFile() but fs.rename.
This cose works in my app.js:
app.post('/upload', function (req, res) {
var tempPath = req.files.file.path,
name = '',
targetPath = '';
fileExist = true;
fileNumber = 0;
var fileType = path.extname(req.files.file.name);
var fileName = path.basename(req.files.file.name,fileType);
while (fileExist) {
fileNumber_str = fileNumber.toString();
var current = fileName + "_" +fileNumber_str + fileType;
console.log("Controllo per "+current);
if (fs.existsSync(__dirname + "/images/orig/" + current)) {
console.log("--> Esiste");
fileNumber++;
} else {
var newPath = __dirname + "/images/orig/" + current;
console.log("nuovo nome : "+newPath);
fs.rename(tempPath, newPath, function(err) {
if (err) throw err;
//Ora creo il thumb
console.log("Upload completed!");
});
break;
}
}
res.redirect("/");
res.end();
});
Take a look.
M.
It seems that you cannot parse multipart data with querystring.parse.
You have to write your own parser or use third-party module, like node-multiparty.
With multiparty module the code will be like this:
if (req.method == 'POST' && req.url == '/newImages/') {
var form = new multiparty.Form();
form.parse(req, function(err, fields, files) {
var tmp = files.fileName[0].path;
fs.rename(tmp, '/your/dir/img.jpg', function(err) {
if (err) throw err;
console.log('success');
});
res.end('Found!');
});
}

Categories

Resources