How do I download JavaScript string as a file - javascript

Application requests KML data through AJAX from server. This data is stored in javascript variables, and displayed in Google Earth plugin.
In javascript, how do I provide a link to download the KML data stored in javascript variable (as a string) without requiring a request back to server?
This link:
http://forum.mootools.net/viewtopic.php?id=9728
suggests the use of data URI, but that probably won't work across enough browsers for my needs. Probably simplest just to go back to server to get data again for download, but curious if anyone has pulled this off with javascript.

This will work! It works for me.
enter link description here
`function download(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
// Start file download.
download('hello.txt','This is the content of my file ');
`

Short answer: you can't and still be platform independent. Most browsers just don't allow javascript to manipulate the filesystem.
That said, you might be able to get away with some very platform-specific hacks. For example, IE offers the execCommand function, which you could use to call SaveAs. If you did that within an IFrame that had the data you wanted to save, you might get it working -- but only on IE. Other options (again, I'm going Microsoft specific here) include this Silverlight hack, or ActiveX controls.
I think for full platform compatibility, you're just going to have to suck it up and provide a server-side download option.
[Edit]
Whoops! I didn't do enough due diligence when I went link-hunting. It turns out the Silverlight hack I linked to has a server-side component. Looks like you're pretty SOL.
[Edit2]
I found a nice summary of browser compatibility for execCommand here. Although it lists question marks for the "saveas" command, maybe that might be a good route for you after all. Worth a try, perhaps?
[Edit3]
Well, I decided to do a proof of concept of the approach I suggested, and I got something fairly simple working in IE. Unfortunately, I proved in the process that this approach will not work for Firefox and doesn't appear to work in Chrome/Safari, either. So it's very platform dependent. But it works! Here's a complete working page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Javascript File Saver</title>
<script type="text/javascript">
function PageLoad() {
var fdoc = window.frames["Frame"].document;
fdoc.body.appendChild(fdoc.createTextNode("foo,bar,baz"));
}
function Save() {
var fdoc = window.frames["Frame"].document;
fdoc.execCommand("SaveAs", true);
}
</script>
</head>
<body onload="PageLoad();">
<h2>Javascript File Saver</h2>
<iframe id="Frame" style="width: 400px;">Noframe</iframe><br />
<button onclick="Save();">Save</button>
</body>
</html>

Yeah, I'm afraid you have to pass it back to the server. Make a generic "echo" script that spits out whatever parameters are fed to it.
At least you can force a download with the right MIME type:
"content-disposition","attachment; filename=data.xml"

You might want to check this out: it's called Downloadify. It uses a mix of Javascript and Flash, and can save a string in pretty much any format. Try out the demo and see for yourself!

Check out http://regany.com/blog/2014/05/30/convert-a-string-to-a-download-file-in-javascript/
Enable popups and use the following code:
var str = "the string you wan't to download";
window.open('data:text/plain,' + encodeURIComponent(str));

Probably it would be usefull (JSP variant):
private void printSaveStringButton(String fileName, String content) throws Exception {
//add new invisible container with write / save functions
out.println("<iframe id=\"xmlContentId\" style=\"display:none;\"></iframe>");
//save string in js variable
String jScript = "\n" +
"var SaveHelper = {\n" +
" content : null,\n" +
" saveContent : function(filename, text) {\n" +
" text=(SaveHelper.content!=null)?SaveHelper.content:text;\n" +
" var doc = document.getElementById('xmlContentId').contentWindow.document;\n" +
" doc.write(text);\n" +
" doc.execCommand(\"saveAs\",true,filename);\n" +
" doc.close();\n" +
" }\n" +
"};\n" +
"SaveHelper.content = '" + org.apache.commons.lang.StringEscapeUtils.escapeJavaScript(content) + "';\n";
out.println("<script type=\"text/javascript\">" + jScript + "</script>");
//add button that writes content into iframe container and show save dialog.
out.println("<button type=\"button\" onclick=\"SaveHelper.saveContent('"+fileName+"' )\">Save as...</button>");
}

You could probably use the parseKml function to parse the kml data in the javascript variable rather than trying to store it in a file and modifying it from javascript (which I dont think is possible due to security reasons)
https://developers.google.com/earth/documentation/kml

Frankly, I don't think this is possible. It was never intended that this could be done in javascript.

Related

Create HTML table from text file using Javascript?

I don't even know if my project is possible. After looking around for a few hours and reading up on other Stack Overflow questions, my hopes are slowly diminishing, but it will not stop me from asking!
My Project: To create a simple HTML table categorizing our Sales Team phone activity for my superior. Currently I need something to pull data values from a file and use those values inside the table.
My Problem: Can Javascript even do this? I know it reads cookies on the client side computer, but can it read a file in the same directory as the webpage? (If the webpage is on the company server?)
My Progress: I will update as I find more information.
Update: Many of you are curious about how the file is stored. It is a static webpage (table.html) on our fileserver. The text file (data.txt) will be in the same directory.
I've recently completed a project where i had almost the exact conditions as yourself (the only difference is that users exclusively use IE).
I ended up using JQuery's $.ajax() function, and pulled the data from an XML file.
This solution does require the use of either Microsoft Access or Excel. I used as early as the 2003 version, but later releases work just fine.
My data is held in a table on Access (on Excel i used a list). Once you've created your table in Access; it's honestly as simple as hitting 'Export', saving as XML and then playing around with your 'ajax()' function (http://api.jquery.com/jQuery.ajax/) to manipulate the data which you want to be output, and then CSS/HTML for the layout of your page.
I'd recommend Access as there's less hastle in getting it to export XML in the right manner, though Excel does it just fine with a little more tinkering.
Here's the steps with ms-access:
Create table in access & export as XML
The XML generated will look like:
<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Calls.xsd" generated="2013-08-12T19:35:13">
<Calls>
<CallID>1</CallID>
<Advisor>Jenna</Advisor>
<AHT>125</AHT>
<Wrap>13</Wrap>
<Idle>6</Idle>
</Calls>
<Calls>
<CallID>3</CallID>
<Advisor>Edward</Advisor>
<AHT>90</AHT>
<Wrap>2</Wrap>
<Idle>4</Idle>
</Calls>
<Calls>
<CallID>2</CallID>
<Advisor>Matt</Advisor>
<AHT>246</AHT>
<Wrap>11</Wrap>
<Idle>5</Idle>
</Calls>
Example HTML
<table id="doclib">
<tr><th>Name</th><th>AHT</th><th>Wrap</th><th>Idle</th></tr>
</table>
jQuery:
$(document).ready(function(){
$.ajax({
type: "GET",
url: "Calls.xml",
dataType: "xml",
success: function(xml) {
$(xml).find('Calls').each(function(){
var advisor = $(this).find('Advisor').text(),
aht = $(this).find('AHT').text(),
wrap = $(this).find('Wrap').text(),
idle = $(this).find('Idle').text(),
td = "<td>",
tdc = "</td>";
$('#doclib').append("<tr>" +
td + advisor + tdc + td + aht + tdc + td + wrap + tdc + td + idle + tdc + "</tr>")
});
}
});
});
JavaScript cannot automatically read files due to security reasons.
You have two options:
If you can rely on IE being used, you could use some fancy ActiveX stuff.
Use a backend which either constantly pushs data to the JS client or provides the data on pull requests.
This could work if you had a server like build with Node.js, PHP, ...etc.
JavaScript can read files with the Ajax protocol, but this mean that you need a server.
Otherwise your requests will go through the file:// protocol which doesn't support Ajax.
You can try looking into FileReader:
https://developer.mozilla.org/en-US/docs/Web/API/FileReader
The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer
I've never personally gotten it to work properly, but it's supposed to be able to allow this sort of thing.
Try with XMLHttpRequest or ActiveXObject in IE 5 or IE 6.
Here you can find an explanation:
http://www.w3schools.com/xml/xml_http.asp
Or try this example:
http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_first
It sounds like you just want to get the contents of a static file from your server; is that right? If that's what you need to do, you're in luck. That's very easy.
load('textTable.txt', function(err, text) {
buildTable(text);
});
function load(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState < 4) return;
if (xhr.status !== 200) {
return callback('HTTP Status ' + xhr.status);
}
if (xhr.readyState === 4) {
callback(null, xhr.responseText);
}
};
xhr.open('GET', url, true);
xhr.send('');
}
If you go with qwest, it'll look something like this:
qwest.get('textTable.txt').success(function(text) {
buildTable(text);
});
With jQuery:
jQuery.get('textTable.txt', function(text) {
buildTable(text);
});

JQuery .getJson wont load local file plus how to convert to JavaScript object.

Hey guys I am trying to learn how to use JSON files. I understand the basics but I am trying to grasp loading them into an HTML file and I am having a couple of difficulties.
The first difficulty I am having is that if I put in the full file extension to load the file I get an error 'expected hexadecimal digit'. I did some research on it and I think it is because in the file extension it is \u so it is expecting a hexadecimal but I am not sure how to work around it.
The second problem I am having is that if I just use the file extension users.json it works in my editor but not in a browser. It is not loading the file at all, the code is fine (I believe). I think it is just not loading the file because of the file extenion.
Suggestions on how to fix my problems? Thanks in advance.
<body>
for output
<div id="forOutput"></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
var output;
$(document).ready(function(){
alert("JQuery loaded");
});
$.getJSON('C:\Users\Spencer\Desktop\JSJqueryTesting\JSONTesting\users.json', function(data) {
output = data;
for (var i in data.users) {
alert(data.users[i].firstName + " " + data.users[i].lastName+ " " + data.users[i].joined.month);
}
});
$("#forOutput").html("User 1 lastname: " + output.users[1].lastName);
</script>
The file extension is perfect (.json), however, you can't load local files (because of security reasons). If what you are trying to do, were possible, that would mean any website could access all your local files. Now that's really not such a good idea, and therefore (by default) only files that share the same domain(e.g. stackoverflow.com/*) are allowed. This is called Same Origin Policy.

How to retrieve information about mp3 using javascript?

I've done some research on the subject, but can't get a clear answer with how to go about doing this. I have tried the following method:
<script type="text/javascript" src="../binaryajax/binaryajax.js" ></script>
<script type="text/javascript" src="id3.js" ></script>
var file = "mymusicfile.mp3";
// define your own callback function
function mycallback() {
// either call ID3.getAllTags([file]) function to return object holding all the tags
alert(
"All tags in this file: " + ID3.getAllTags(file).toSource()
);
// or call ID3.getTag([file], [tag]) to get a specific tag
alert(
"Title: " + ID3.getTag(file, "title") + " by artist: " + ID3.getTag(file, "artist")
);
}
ID3.loadTags(file, mycallback);
The first method, (getAllTags) doesn't allow my script to run, and the second method returns null for both title and artist on all of my mp3's.
Source of Info: http://blog.nihilogic.dk/2008/08/reading-id3-tags-with-javascript.html
I know these methods are using ID3(v1), so that may be the problem. Either that, or I suppose it's possible by mp3's don't contain ID3 information. But if anyone could provide some insight into how to do this, or how to identify if my mp3's contain ID3 info and whether it's v1 or v2 would be great.
Edit: I should say, I'm accessing the files via Blob URL's because the app that I'm developing let's the user select a directory on their computer and then queries the files for media files. In doing this, you can't access the absolute path of the file, but you still can access the file information and use the file.
For others to use: this worked quite well for me :)
github.com/aadsm/JavaScript-ID3-Reader/tree/master/src use the project repository

create .ics file on the fly using javascript or jquery?

Can someone tell me if there is any jquery plugin to dynamically create .ics file with values coming from the page div values like there would be
<div class="start-time">9:30am</div>
<div class="end-time">10:30am</div>
<div class="Location">California</div>
or javascript way to dynamically create an .ics file? I basically need to create .ics file and pull these values using javascript or jquery? and link that created ics file to "ADD TO CALENDAR" link so it gets added to outlook?
you will need to make it in ICS format. also you will need to convert the date and time zone; E.G. 20120315T170000Z or yyyymmddThhmmssZ
msgData1 = $('.start-time').text();
msgData2 = $('.end-time').text();
msgData3 = $('.Location').text();
var icsMSG = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//Our Company//NONSGML v1.0//EN\nBEGIN:VEVENT\nUID:me#google.com\nDTSTAMP:20120315T170000Z\nATTENDEE;CN=My Self ;RSVP=TRUE:MAILTO:me#gmail.com\nORGANIZER;CN=Me:MAILTO::me#gmail.com\nDTSTART:" + msgData1 +"\nDTEND:" + msgData2 +"\nLOCATION:" + msgData3 + "\nSUMMARY:Our Meeting Office\nEND:VEVENT\nEND:VCALENDAR";
$('.test').click(function(){
window.open( "data:text/calendar;charset=utf8," + escape(icsMSG));
});
the above sample will create a ics file for download. the user will have to open it and outlock, iCal, or google calendar will do the rest.
This is an old question, but I have some ideas that could get you started (or anyone else who needs to do a similar task).
And the JavaScript to create the file content, and open the file:
var filedata = $('.start-time, .end-time, .Location').text();
window.open( "data:text/calendar;charset=utf8," + escape( filedata ) );
Presumably you'd want to add that code to the onclick event of a form button.
I don't have Outlook handy, so I'm not sure if it will automatically recognize the filetype, but it might.
Hope this helps.
From what I have found online and on this site, it is not possible to get this to work in IE as you need to include certain headers to let IE know to download this file.
The window.open method works for Chrome and Firefox but not IE so you may need to restructure your code to use a server-side language to generate and download the ICS file.
More can be found in this question
While this is an older question, I have been looking for a front-end solution as well. I recently stumbled across the
ICS.js library which looks like the answer you're looking for.
This approach worked fine however with IE8 the browser couldn't recognize the file type and refused to open as a calendar item. To get around this i had to create the code on the server side (and exposed via RESTful service) and then set the response headers as follows;
#GET
#Path("generateCalendar/{alias}/{start}/{end}")
#Produces({ "text/v-calendar" })
public Response generateCalendar(
#QueryParam("alias") final String argAlias,
#QueryParam("start") final String argStart,
#QueryParam("end") final String argEnd) {
ResponseBuilder builder = Response.ok();
builder.header("content-disposition", "attachment;filename=calendar.ics");
builder.entity("BEGIN:VCALENDAR\n<........insert meeting details here......>:VCALENDAR");
return builder.build();
}
This can be served up by calling window.location on the service URL and works on Chrome, Firefox and IE8.
Hope this helps.

URL validation/connectivity using javascript

I want to verify if an external url valid/exists/responsive using javascript. For example, "www.google.com" should return true and "www.google123.com" should return false.
I thought to use AJAX for this purpose by testing : if (xmlhttp.readyState == 4 && xmlhttp.status == 200) but it seems that this doesn't work for remote servers(external urls). As my server uses a proxy, i planned to use browser side script so that it automatically uses user's browser proxy if present.
Please tell me do I have to use "AJAX Cross Domain"? How to achieve this, as i simply want to validate a url.
Any way other than using AJAX?
I'm pretty sure this is not possible. Any AJAX that allowed you to call a random page on another domain in the user's context would open up all sorts or security holes.
You will have to use a server-side solution.
The usual way to avoid cross-domain issues is to inject a tag. Tags like image or script kan load their content from any domain. You could inject, say a script tag with type "text/x-unknown" or something, and listen to the tags load-event. When the load event triggers, you can remove the script tag from the page again.
Of course, if the files you are looking for happens to be images, then you could new Image() instead. That way you don't have to pollute the page by injecting tags, because images load when they are created (this can be used to preload images). Again, just wait for the load event on the image.
UPDATE
Okay, it seems I am jumping to conclusions here. There is some differences between browsers on how this can be supported. The following is a complete example, of how to use the script tag for validating urls in IE9 and recent versions of Firefox, Chrome and Safari.
It does not work in older versions of IE (IE8 at least) because apparently they don't provide load/error events for script-tags.
Firefox refuses to load anything if the contenttype for the script-tag is not empty or set to 'text/javascript'. This means that it may be somewhat dangerous to use this approach to check for scriptfiles. It seems like the script tag is deleted before any code is executed in my tests, but I don't for sure...
Anyways, here is the code:
<!doctype html>
<html>
<head>
<script>
function checkResource(url, callback) {
var tag = document.createElement('script');
tag.src = url;
//tag.type = 'application/x-unknown';
tag.async = true;
tag.onload = function (e) {
document.getElementsByTagName('head')[0].removeChild(tag);
callback(url, true);
}
tag.onerror = function (e) {
document.getElementsByTagName('head')[0].removeChild(tag);
callback(url, false);
}
document.getElementsByTagName('head')[0].appendChild(tag);
}
</script>
</head>
<body>
<h1>Testing something</h1>
<p>Here is some text. Something. Something else.</p>
<script>
checkResource("http://google.com", function (url, state) { alert(url + ' - ' + state) });
checkResource("http://www.google.com/this-does-not-exists", function (url, state) { alert(url + ' - ' + state) });
checkResource("www.asdaweltiukljlkjlkjlkjlwew.com/does-not-exists", function (url, state) { alert(url + ' - ' + state) });
</script>
</body>
</html>

Categories