Accessing files on local machine in Windows 8 Metro Style Apps using JavaScript and HTML5

This article is written on pre-release version of the software and is subject to change in future release.

Here I’ll be reading a list of files from the client machine and displaying it on the page.

I created a new blank JavaScript Metro Style App project.

image

I’ll be using jQuery to update the content on to the file, so I’ll run the below command in the Package Manager Console.

   1:  Install-Package jQuery

This creates a Scripts folder in my project with the latest version of jQuery (at the time of writing).

image

After a little bit of modifying, this is what my html page looks like.

image

You can see I’ve added a reference to the jQuery API (just above the closing body tag). I have also created a program.js file where I’ll be writing all my code and a reference for the same has been added to the html page as well.

Now let’s get to the JavaScript side. The initial lines of code in my program.js look as below.

   1:  (function () {
   2:      "use strict";
   3:   
   4:  })();

The phrase, ‘use strict’ is not a Metro Style App declaration. It has been with JavaScript for quite some time. Read more about this from John Resig himself.

   1:  function initialize() {
   2:      var openpicker = new Windows.Storage.Pickers.FileOpenPicker();
   3:      openpicker.fileTypeFilter.replaceAll([".txt", ".rtf"]);
   4:      openpicker.pickMultipleFilesAsync().then(function (files) {
   5:          var fileNames = '';
   6:          files.forEach(function (file) {
   7:          fileNames += file.displayName + '<br/>';
   8:          });
   9:          $('#contentDiv').html(fileNames);
  10:      });
  11:  }

Here’s what the above method is doing. I create an instance of the FileOpenPicker and add a couple of file type filters to it.

Based on what the user selects, I read each of the files async and once that is done, the anonymous function passes a collection of these files. The ‘then’ part of the expression kicks in once the files are picked up (in async mode) is complete.

I’m reading the display name of each of these files to finally show them in the Div element. Well, I could’ve done the ‘display it on the page’ through good ol’ JavaScript as well, but just wanted to show how seamless both jQuery and WInJS are.

As a last step, I need to wire up this event so that it gets called when the page loads.

   1:  document.addEventListener("DOMContentLoaded", initialize, false);

This basically says, once the DOMContentLoaded event fires, the initialize function is called. Again, the addEventListener is a JavaScript function that Metro Style Apps are reusing – details here and here.

Time for some screenshots.

imageimage

I click on the open button at the bottom and the page gets rendered as below.

image

This what the ‘My Documents’ folder looks like in Windows Explorer.

image 

Here’s something interesting I want to tell you. There is a ‘file’ variable declared in the above snippet. This is not just a string variable or some custom object (I’ve not declared any such object in the project) of JavaScript creates. THIS IS THE ACTUAL FILE FROM THE FILE SYSTEM ITSELF. Here’s the proof:

image image

Properties ‘dateCreated’, ‘displayName’, ‘fileType’ and methods ‘copy’, ‘delete’ ‘move’ (async versions of course) make that evident.

There is a second method of doing what I’ve done above. The benefit of this second method is that it reads the files directly without user having to select a list of files. But on the downside, in order to use this method, you need to add application capability to access the document library folder and provide a file type association. Read the suggestions on MSDN here and here before you implement it this way.

Below is the implementation of reading the documents library folder.

   1:  function initialize() {
   2:          Windows.Storage.KnownFolders.documentsLibrary.getFilesAsync().then(function (files) {
   3:              var fileNames = '';
   4:              files.forEach(function (file) {
   5:                  fileNames += file.displayName + '<br/>';
   6:              });
   7:              $('#contentDiv').html(fileNames);
   8:          });
   9:  }

So I’m getting all the files in the documentsLibrary folder (which maps to the My Documents folder). The rest of the code is the same as the one used above. If I run the app without adding the capabilities, I get an error message:

image

The details below state: ‘Access to the specified location (DocumentsLibrary) requires a capability to be declared in the manifest’. In order to provide capability to the documents library, just select the checkbox in the package.appxmanifest file.

image

Running the app now gives me the error saying ‘Access to the specified location (DocumentsLibrary) requires a file type association to be declared in the application manifest’.

image

In order to register file type associations on behalf of the app:

image

When I run the app now, things work fine and I see the below getting rendered on the page.

image

Since I did not associate the .rtf file type in my declaration, the RichTextDocument does not get listed.

So these are the two methods I wanted to detail about in this article.

My encounters with Metro Style Apps are becoming interesting by the day!

2 Comments

  • Well think about it this way.

    Say you are a UI developer for web applications, doing HTML, Javascript and CSS stuff. Wouldn't it be limiting for Microsoft to say, "you'll still have to learn C# / C++ to be able to create Metro Apps"?

    Allowing users to create apps in Javascript, would mean users can just import all their skills and start developing right away. Also, these UI devs may already have a working model of their 'idea' for a web app, they can Ctrl+C, Ctrl+V most part of their code and be done with it.

  • it worked for me at begining i am facing issue , and after i checked while giving .xml i have given as xml alone in filetype , but i finally figured out thanks a lot

Comments have been disabled for this content.