How to Save As using Node-Webkit - javascript

Using Node-Webkit, The following page,
https://github.com/rogerwang/node-webkit/wiki/File-dialogs
Describes that you can use
[input type="file" nwsaveas="filename.txt" /]
to open a File Save dialog.
However it does not explain how would you write the data to the filesystem.
I expected/imagined something simple like,
var directory = FileOpen();
fs.writeFile(directory+"myfile.png", buffer);
Is there any explanation for this?

You are right, after you trigger the Save As dialog, you will be prompted a dialog, specify the name, and you could receive the file path by doing this.
Sample Code (using jQuery):
$("#save").trigger("click");
$("#save").on("change", function () {
var filePath = $(this).val();
if (filePath !== "") {
var fs = require("fs");
fs.writeFile(filePath, "Hello World", function (err) {
if (err)
alert("Unable to save file");
else
console.log("saved. ");
});
}
else {
// User cancelled
}
});

Related

Redirecting after onclick()-event with a-tag

I am programming an app with elecrtonjs and got stuck.
So on my page there is this HTML:
<a href="./step1.html" id="next"><span onclick="writeToFile();return false">Next ></span></a`>
And in the javasriptfile I am saving stuff to a file in the directory:
var fs = require('fs');
function writeToFile() {
//alert(document.getElementsByTagName("input").length);
var text = "";
// Change the content of the file as you want
// or either set fileContent to null to create an empty file
for (var i = document.getElementsByTagName("input").length - 1; i >= 0; i--) {
text += document.getElementsByTagName("input")[i].getAttribute("name")+":\n";
text += document.getElementsByTagName("input")[i].value+"\n";
}
// The absolute path of the new file with its name
var filepath = "mynewfile.txt";
fs.appendFile(filepath, text, (err) => {
if (err) throw err;
console.log("The file was succesfully saved!");
});
}
The code redirects properly but does not append the user-input in to the specified file.
Am I timing the stuff wrong? I tried
onbeforeunload
Thanks for the help.
As Chris Li already stated, you should use
window.location.href = "./step1.html"
and remove the href field of your link.

Pass file path to javascript input android

I understand that providing a physical file path to javascript is not possible due to security reasons. However, when I look at Mozilla's pdf.js and mupdf android pdf viewer I see this is very much possible. There is a mechanism by which I can pass a file path to javascript. I explored into PDF.js but it seemed little difficult to make use of when I needed a simple solution.
I want to pass android internal storage file location onto the following code instead of using input id="files" type="file" which requires me to browse and select file. In my case I want to just pass file location from sdcard.
The following code actually loads ms word (docx) file as html which I then will show in webview in my project. In the case of pdf.js we were using it to display pdf in the similar way.
<script>
$(document).ready(function(){
//Input File
var $files = $('#files');
//File Change Event
$files.on('change', function (e) {
//File Object Information
var files = e.target.files;
//Create DocxJS
var docxJS = new DocxJS();
//File Parsing
docxJS.parse(
files[0],
function () {
//After Rendering
docxJS.render($('#loaded-layout')[0], function (result) {
if (result.isError) {
console.log(result.msg);
} else {
console.log("Success Render");
}
});
}, function (e) {
console.log("Error!", e);
}
);
});
});
</script>
<input id="files" type="file" name="files[]" multiple="false" />
<div id="loaded-layout" style="width:100%;height:800px;">
</div>
You can check code of PDF.JS based pdfviewer in android here.
What I found on the PDF.js code which was used to input file :
In pdffile.js included in index.html file, url variable was mentioned pointing to real location of the file i.e. in assets folder which then was used in pdf.js but at that point the usage seems confusing. Is there any way by which I can use real path of file or pass real path somehow in android for my purpose of viewing docx?
UPDATE :
I find that PDF.js by Mozilla actually treats file location as a url and so the file in the url is converted to javascript file object or blob. Hence I create a blob of the url from server using Ajax :
var myObject;
var xhr = new XMLHttpRequest();
xhr.open("GET","10143.docx",true); // adding true will make it work asynchronously
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200){
//do some stuff
myObject = this.response;
}
};
xhr.send();
$(document).ready(function(){
//Input File
var $files = $('#files');
//File Change Event
$files.on('change', function (e) {
//File Object Information
var files = myObject.files;
//Create DocxJS
var docxJS = new DocxJS();
//File Parsing
docxJS.parse(
blobToFile(myObject, "10143.docx"),
function () {
//After Rendering
docxJS.render($('#loaded-layout')[0], function (result) {
if (result.isError) {
console.log(result.msg);
} else {
console.log("Success Render");
}
});
}, function (e) {
console.log("Error!", e);
}
);
});
});
function blobToFile(theBlob, fileName){
//A Blob() is almost a File() - it's just missing the two properties below which we will add
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
}
However now that I do that I get Parsing error from DocxJS like : {isError: true, msg: "Parse Error."}

NodeJS Streaming for Audio/Video with Client Side Control

i am building a simple streaming server to stream audio/video. below code gets the job done but when i click on time line on video nothing happens as i cannot fetch from that time. also need to send event regarding clikc to nodejs streaming and stream from where i clicked.
I had been able to come up with this. i send the file using the URL sendFile="some file" and then the node checks for that file. if successful i start getting the stream on my client side and i put it directly into video src. But i need morecontrol over this. such as when user click on certain timeline so that i can directly start strweaming from there.
app.get is used to get the location of the folder where i store the files.
used just express and nodejs
function FolderReaderMerger(path,pathToMerge,cb)
{
log("Reading File/Folder To Combine : ");
fs.readdir(path, function(err, audio)
{
fs.readdir(pathToMerge, function(err, audioText)
{
var obj ={};
global.list.audio =audio;
global.list.audioText =audioText;
obj.audio = audio;
obj.audioText = audioText;
cb(obj);
});
});
}
app.get("/audio",function(req,resp)
{
log("App Audio File Serv : ");
var playFile = req.param("playFile");
var filePath = {};
filePath.status =false;
if(playFile!=undefined)
{
log("Params File : "+playFile);
/* log("Requested URL : "+req.url);
log("Total Audio Files : "+global.list.audio.length);*/
var i =0;
while(i!=global.list.audio.length)
{
if(playFile==global.list.audio[i])
{
log("File Found : "+playFile);
//get files location
log(app.get("audioPath")+playFile);
filePath.status = true;
var filePath = app.get("audioPath")+playFile;
log("FILE PATH : "+filePath);
var stat = fs.statSync(filePath);
log(stat);
log(stat.size);
resp.writeHead(200, {
'Content-Type': 'audio/mpeg',
'Content-Length': stat.size
});
var readStream = fs.createReadStream(filePath);
// We replaced all the event handlers with a simple call to readStream.pipe()
log("Streaming.......");
readStream.pipe(resp);
}
else
{
log("Requested Resource Not Found");
}
i+=1;
}
//readStream = fs.createReadStream(app.get("audioPath"));
}
else
{
log("Requested Params Not Found");
resp.send(filePath);
}
});
http.listen(app.get("PORT"),function()
{
consolelog("--------------------------------------------------------");
console.log("Server Started On PORT: "+app.get("PORT"));
console.log("All NPM Initialized");
console.log("Please Wait Checking Connection Status...");
console.log("--------------------------------------------------------");
});
<video src="http://localhost:3000/audio?playFile='some media file"></video>
ANy help would be appreciated.This works on click side
But also need more control regarding click and events.

get a file as a string using javascript

I have a HTML form to upload a file.
My goal is to submit the form, check that the file has XML extension and get the file as a String into a JavaScript variable.
Then, I want to send a POST request to the server using this String.
Any idea how I can do that?
My goal is to submit the form, check that the file has XML extension and get the file as a String into a JavaScript variable.
I don't think you really mean you want to submit the form (as in, send it to the server) at this stage.
Then, I want to send a POST request to the server using this String.
You can do that on browsers that support the File API, which is most modern ones but not IE8 or IE9. There's an example in this answer.
Basically, you get the File instance from your <input type="file"> element's files list, check its name, read it, and then post it:
Complete Example (source) (other than the POST bit, which I assume you know how to do):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
<input type="file">
<button>Go</button>
<script>
(function() {
"use strict";
// Get our input element and our button; in this example there's
// just one of each, you'd narrow down these selectors of course
var inputElement = document.querySelector("input[type=file]"),
button = document.querySelector("button");
if (typeof FileReader !== 'function') {
alert("The file API isn't supported on this browser.");
inputElement.style.display = button.style.display = "none";
return;
}
if (!inputElement.files) {
alert("Odd, this browser has FileReader but no `files` property on the input element.");
inputElement.style.display = button.style.display = "none";
return;
}
button.addEventListener("click", function() {
var file, filename, reader, filedata;
// Does it have any files?
if (inputElement.files.length === 0) {
alert("No file chosen");
return;
}
// Get its first file
file = inputElement.files[0];
// Get its name in lower case
filename = file.name.toLowerCase();
// XML extension?
if (filename.substr(-4) !== ".xml") {
alert("Please only choose .xml files");
}
else {
// Yes, read it
reader = new FileReader();
reader.onload = function() {
// Get the file data, note that this happens asynchronously
filedata = reader.result;
// Send your POST with the data; here, we'll just dump it out
// as text
displayXml(filedata);
};
reader.readAsText(file); // or you can use readAsBinaryString
}
}, false);
function displayXml(xmlText) {
var pre = document.createElement('pre');
pre.innerHTML = xmlText.replace(/&/g, "&").replace(/</g, "<");
document.body.appendChild(pre);
}
})();
</script>
</body>
</html>

How to upload base64 image resource with dropzone?

I'm trying to upload generated client side documents (images for the moment) with Dropzone.js.
// .../init.js
var myDropzone = new Dropzone("form.dropzone", {
autoProcessQueue: true
});
Once the client have finished his job, he just have to click a save button which call the save function :
// .../save.js
function save(myDocument) {
var file = {
name: 'Test',
src: myDocument,
};
console.log(myDocument);
myDropzone.addFile(file);
}
The console.log() correctly return me the content of my document
data:image/png;base64,iVBORw0KGgoAAAANS...
At this point, we can see the progress bar uploading the document in the drop zone but the upload failed.
Here is my (standart dropzone) HTML form :
<form action="/upload" enctype="multipart/form-data" method="post" class="dropzone">
<div class="dz-default dz-message"><span>Drop files here to upload</span></div>
<div class="fallback">
<input name="file" type="file" />
</div>
</form>
I got a Symfony2 controller who receive the post request.
// Get request
$request = $this->get('request');
// Get files
$files = $request->files;
// Upload
$do = $service->upload($files);
Uploading from the dropzone (by drag and drop or click) is working and the uploads are successfull but using the myDropzone.addFile() function return me an empty object in my controller :
var_dump($files);
return
object(Symfony\Component\HttpFoundation\FileBag)#11 (1) {
["parameters":protected]=>
array(0) {
}
}
I think i don't setup correctly my var file in the save function.
I tryied to create JS image (var img = new Image() ...) but without any success.
Thanks for your help !
Finally i found a working solution without creating canvas :
function dataURItoBlob(dataURI) {
'use strict'
var byteString,
mimestring
if(dataURI.split(',')[0].indexOf('base64') !== -1 ) {
byteString = atob(dataURI.split(',')[1])
} else {
byteString = decodeURI(dataURI.split(',')[1])
}
mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0]
var content = new Array();
for (var i = 0; i < byteString.length; i++) {
content[i] = byteString.charCodeAt(i)
}
return new Blob([new Uint8Array(content)], {type: mimestring});
}
And the save function :
function save(dataURI) {
var blob = dataURItoBlob(dataURI);
myDropzone.addFile(blob);
}
The file appears correctly in dropzone and is successfully uploaded.
I still have to work on the filename (my document is named "blob").
The dataURItoBlob function have been found here : Convert Data URI to File then append to FormData
[EDIT] : I finally wrote the function in dropzone to do this job. You can check it here : https://github.com/CasperArGh/dropzone
And you can use it like this :
var dataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAmAAAAKwCAYAAA...';
myDropzone.addBlob(dataURI, 'test.png');
I can't comment currently and wanted to send this to you.
I know you found your answer, but I had some trouble using your Git code and reshaped it a little for my needs, but I am about 100% positive this will work for EVERY possible need to add a file or a blob or anything and be able to apply a name to it.
Dropzone.prototype.addFileName = function(file, name) {
file.name = name;
file.upload = {
progress: 0,
total: file.size,
bytesSent: 0
};
this.files.push(file);
file.status = Dropzone.ADDED;
this.emit("addedfile", file);
this._enqueueThumbnail(file);
return this.accept(file, (function(_this) {
return function(error) {
if (error) {
file.accepted = false;
_this._errorProcessing([file], error);
} else {
file.accepted = true;
if (_this.options.autoQueue) {
_this.enqueueFile(file);
}
}
return _this._updateMaxFilesReachedClass();
};
})(this));
};
If this is added to dropzone.js (I did just below the line with Dropzone.prototype.addFile = function(file) { potentially line 1110.
Works like a charm and used just the same as any other. myDropzone.addFileName(file,name)!
Hopefully someone finds this useful and doesn't need to recreate it!
1) You say that: "Once the client have finished his job, he just have to click a save button which call the save function:"
This implies that you set autoProcessQueue: false and intercept the button click, to execute the saveFile() function.
$("#submitButton").click(function(e) {
// let the event not bubble up
e.preventDefault();
e.stopPropagation();
// process the uploads
myDropzone.processQueue();
});
2) check form action
Check that your form action="/upload" is routed correctly to your SF controller & action.
3) Example Code
You may find a full example over at the official Wiki
4) Ok, thanks to your comments, i understood the question better:
"How can i save my base64 image resource with dropzone?"
You need to embedd the image content as value
// base64 data
var dataURL = canvas.toDataURL();
// insert the data into the form
document.getElementById('image').value = canvas.toDataURL('image/png');
//or jQ: $('#img').val(canvas.toDataURL("image/png"));
// trigger submit of the form
document.forms["form1"].submit();
You might run into trouble doing this and might need to set the "origin-clean" flag to "true". see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#security-with-canvas-elements
how to save html5 canvas to server

Categories

Resources