Click here to Skip to main content
15,860,861 members
Articles / Web Development / HTML

Droptiles - Metro style Live Tiles powered Web Dashboard

Rate me:
Please Sign up or sign in to vote.
4.99/5 (55 votes)
18 Jul 2012CPOL5 min read 470.8K   120   86
Droptiles mimics the experience of Windows 8 Start screen using HTML, Javascript and CSS. It offers a framework to build Dashboards comprised of Tiles. Tiles are mini-Apps built using Javascript. They launch a full screen app when clicked. Apps can be any regular website to custom built applications

Introduction

Droptiles is a Windows 8 Start like Metro style Web 2.0 Dashboard. It builds the experience using Tiles . Tiles are mini apps that can fetch data from external sources. Clicking on a tile launches the full app. Apps can be from any existing website to customized website specifically built to fit the Dashboard experience. Droptiles is built almost entirely of HTML, Javascript and CSS and thus highly portable to any platform. The sample project is built using ASP.NET to show some server side integration, like Signup, Login and getting dynamic data from server. But with very little change you can port it to PHP, Ruby, JSP or any other platform. Droptiles is the sequel of my Dropthings, which is the first Open Source Web 2.0 Dashboard. 

See it live!, go to Droptiles.com

Get the code from: 

https://github.com/oazabir/Droptiles

Features   

  • Metro style user interface. CSS framework to build metro style websites, inspired by metroui.org.ua. 
  • Drag & Drop tiles to personalize the experience.
  • Client side object model and data binding for easy MVVM implementation.
  • Server side platform neutral implementation. Can be ported to PHP, JSP easily.
  • Live tiles. Tiles are mini-apps, loading data from variety of sources.

It even has its own App Store! 

How can you use Droptiles 

  • Enterprise Dashboard  aggregating data from various systems and offering a launch pad for intranet/internet applications. 
  • Web 2.0 Portal offering portlets in the form of tiles. Aggregating data from various services and as a launch pad for different services.
  • Touch enabled Kiosk front-end. Great for Hotels, Restaurants, Banks front-desk self service. 
  • Content aggregator for News and Research purpose.

Main parts

There are three main parts in Droptiles:

  • Dashboard
  • App Store
  • Login, Signup, Settings.

Dashboard is the home page, that shows the tiles.

App Store shows a collection of apps available for users to add on the Dashboard.

Login, Signup, Settings areas are built using ASP.NET and uses ASP.NET Membership provider.

The Dashboard

Dashboard comprises of Sections. Each section contains a collection of tiles. Each box you see is a Tile. Tiles are mini apps. A tile can be of the following type:

  • Simple html pages 
  • A dynamic Javascript mini-App  
  • Dynamic page 

Coding a Tile 

Let's look at the Flickr tile. First of all, all the tiles appearance are defined in the Tiles.js file, which contains the meta data for all the tiles. For example, the Flickr tile metadata is defined as following:

JavaScript
flickr: function (uniqueId) {
    return {
        uniqueId: uniqueId,
        name: "flickr",
        iconSrc: "img/Flickr alt 1.png",
        label: "Flickr",
        size: "tile-double tile-double-vertical",
        color: "bg-color-darken",
        appUrl: "http://www.flickr.com/",
        cssSrc: ["tiles/flickr/flickr.css"],
        scriptSrc: ["tiles/flickr/flickr.js"],
        initFunc: "flickr_load"
    };
}

The icon is the default icon shown on the tile while the javascript, css, html are loaded. The horizontal and vertical size of the tile is defined in the size attribute. Then when clicked, what URL to host in the full screen view is defined in appUrl. The additional CSS, Javascripts to load are defined in cssSrc and scriptSrc. Finally the initFunc tells what function to invoke once the javascripts are loaded.

The metadata defines how the tile is displayed on the Dashboard. The behavior to load data from Flickr comes from the Flickr.js file, defined as follows:

JavaScript
function flickr_load(tile, div) {

    var url = "http://api.flickr.com/services/feeds/photos_public.gne?lang=en-us&format=json&tags=nature&jsoncallback=?";

    $.getJSON(url, function (data) {
        var ctr = 0;
        $.each(data.items.reverse(), function (i, item) {
            if (item.tags.length < 150) {
                var sourceSquare = item.media.m;
                var sourceOrig = (item.media.m).replace("_m.jpg", ".jpg");

                var htmlString = '<div class="flickr_item"> <a target="_blank" href="' + sourceOrig +
                    '" class="link" title="' + item.title + '">';
                htmlString += '<img title="' + item.title +
                    '" src="' + sourceSquare + '" ';
                htmlString += 'alt="' + item.title +
                    '" />';
                htmlString += '</a><div class="flickr_title">' + item.title + '</div>' +
                    '</div>';

                tile.slides.push(htmlString);

                ctr = ctr + 1;
            }
        });

        tile.counter(ctr);
    });

}

That's it.

Tiles can be Dynamic aspx pages loaded directly inside the tile box. For example:

The way Dashboard works is:

  • First get the list of Sections and the tiles in each section.
  • Create Tile boxes as per the definition stored in Tiles.js file. 
  • For each Tile, see if the Tile has any external Javascript, CSS and html files to load. If yes, then load them.
  • Execute the function defined in the initFunc. Pass the tile object, the Tile div reference and the initParams to it. 

Default tiles to show on Dashboard 

The default tiles shown on Dashboard are defined in the same Tiles.js file as following:
JavaScript
window.DefaultTiles = [
    {
        name :"Section1",
        tiles: [
           { id: "flickr1", name:"flickr" },
           { id: "amazon1", name:"amazon" },
           { id: "news1", name: "news" },
           { id: "weather1", name: "weather" },
           { id: "calendar1", name: "calendar" },
           { id: "feature1", name: "feature" },
           { id: "facebook1", name: "facebook" }
        ]
    },
    {
        name: "Section2",
        tiles: [
           { id: "wikipedia1", name: "wikipedia" },
           { id: "email1", name: "email" },
           { id: "maps1", name: "maps" },
           { id: "angrybirds1", name: "angrybirds" },
           { id: "cuttherope1", name: "cutTheRope" },
           { id: "dynamicTile1", name: "dynamicTile" },
           { id: "buy1", name: "buy" }]
    },
    {
        name: "Section3", tiles: [
           { id: "youtube1", name: "youtube" },
           { id: "ie1", name: "ie" },

        ]
    }
];

Tiles are shown in the exact order they are fined. The name has to be the same name used to define the Tile metadata.

HTML markup for tiles

There are various parts of a tile:

The following HTML defines the tile design:

HTML
<div class="metro-sections" data-bind="foreach: sections">
    <div class="metro-section" data-bind="attr: {id : uniqueId}, foreach: sortedTiles">
        <div data-bind="attr: { id: uniqueId, 'class': tileClasses }">
            <!-- ko if: tileImage -->
            <div class="tile-image">
                <img data-bind="attr: { src: tileImage }" src="img/Internet%20Explorer.png" />
            </div>
            <!-- /ko -->
            <!-- ko if: iconSrc -->
            <!-- ko if: slides().length == 0 -->
            <div data-bind="attr: { 'class': iconClasses }">
                <img data-bind="attr: { src: iconSrc }" src="img/Internet%20Explorer.png" />
            </div>
            <!-- /ko -->
            <!-- /ko -->
            <div data-bind="foreach: slides">
                <div class="tile-content-main">
                    <div data-bind="html: $data">
                    </div>
                </div>
            </div>
            <!-- ko if: label -->
            <span class="tile-label" data-bind="html: label">Label</span>
            <!-- /ko -->
            <!-- ko if: counter -->
            <span class="tile-counter" data-bind="html: counter">10</span>
            <!-- /ko -->
            <!-- ko if: subContent -->
            <div data-bind="attr: { 'class': subContentClasses }, html: subContent">
                subContent
            </div>
            <!-- /ko -->
        </div>
    </div>
</div>

The markup is full of KnockoutJS markups which is used to bind the Tile object model to the html markup.

Dashboard Execution 

Here's a sequence diagram that shows how the Dashboard loads:

The code in Dashboard.js is very straightforward and it does all the magic!

JavaScript
var viewModel = new DashboardModel("Start", [], window.currentUser, ui, TileBuilders);

$(document).ready(function () {

    // Hide the body area until it is fully loaded in order to prevent flickrs
    $('#content').css('visibility', 'visible');

    // Initiate KnockoutJS binding which creates all the tiles and binds the whole
    // UI to viewModel.
    ko.applyBindings(viewModel);

    // See if user has a previous session where page setup was stored
    var cookie = readCookie("p");
    if (cookie != null && cookie.length > 0) {
        try {
            viewModel.loadSectionsFromString(cookie);
        } catch (e) {
            // Failed to load saved tiles. Load the default tiles.
            viewModel.loadSectionsFromString(DefaultTiles);
        }
    }
    else {
        // No cookie, load default tiles. Defined in Tiles.js
        viewModel.loadSectionsFromString(DefaultTiles);
    }

First it tries to read the section and tiles setup from the cookie, if it is saved. If not found in cookie, it loads the default definition. Then the framework in TheCore.js kicks in and takes care of creating the tiles and injecting the dynamic behavior inside the tiles.

The code is heavily documented, so you can read the details from there.

App Store 

 

The App Store experience is built the same way as the Dashboard. The App Store shows how reusable the Droptiles framework is. It uses the same TheCore.js to provide the experience. The only difference is instead of Tiles.js which defines the tile metadata and the default tiles, it has its own AppStoreTiles.js that defines the Tile metadata and the default tiles to show on the App Store.

That's all that differs. 

Here's the code in AppStore.js:

JavaScript
var viewModel = new DashboardModel("App Store", [], window.currentUser, ui,
    TileBuilders);

$(document).ready(function () {

    // Hide the body area until it is fully loaded in order to prevent flickrs
    $('#content').css('visibility', 'visible');

    // Initiate KnockoutJS binding which creates all the tiles and binds the whole
    // UI to viewModel.
    ko.applyBindings(viewModel);

    viewModel.switchTheme('theme-white');
    viewModel.loadSectionsFromString(window.AppStoreTiles);

That's it. The loadSectionsFromString function takes care of creating the AppStore Tiles. It takes the section and tile configuration in a string serialized format, like this:

Section1~flickr1,flickr.news1,news|Section2~angrybirds1,angrybirds

This is how it is stored in the cookie as well so that next time you visit the Dashboard, it shows you how you have left it.  

Conclusion

Droptiles is an open source project to show how Windows 8 Start experience can be built using just HTML, Javascript and CSS. It can be adopted to build various web applications, especially touch enabled applications. The modern Metro look & feel makes it very attractive to use as a self-service portal experience or as a content aggregator.  

  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect BT, UK (ex British Telecom)
United Kingdom United Kingdom

Comments and Discussions

 
NewsDrupal Theme Conversion Sandbox Pin
Charlie Love4-Jan-13 9:35
Charlie Love4-Jan-13 9:35 
QuestionUppercase and lowercase broken links. Pin
Member 971671928-Dec-12 17:12
Member 971671928-Dec-12 17:12 
AnswerRe: Uppercase and lowercase broken links. Pin
Omar Al Zabir3-Jan-13 22:50
Omar Al Zabir3-Jan-13 22:50 
QuestionObjects are not being added to Dashboard from App Store Pin
Greg Frazier17-Dec-12 14:03
Greg Frazier17-Dec-12 14:03 
AnswerRe: Objects are not being added to Dashboard from App Store Pin
Omar Al Zabir19-Dec-12 23:12
Omar Al Zabir19-Dec-12 23:12 
GeneralRe: Objects are not being added to Dashboard from App Store Pin
Greg Frazier20-Dec-12 3:13
Greg Frazier20-Dec-12 3:13 
GeneralRe: Objects are not being added to Dashboard from App Store Pin
Omar Al Zabir20-Dec-12 5:52
Omar Al Zabir20-Dec-12 5:52 
QuestionError : Object doesn't support property or method 'attach'" Pin
manoj.more13-Dec-12 0:30
manoj.more13-Dec-12 0:30 
hi Omar,
its an Excellent application. I love it.
i am studying your droptiles application. I have come across an error in the file "TheCore.js" in addTile function.

Error Description is - "Microsoft JScript runtime error: Object doesn't support property or method 'attach'"

this error come when we add tile from appstore to dashboard.
Thanks!
AnswerRe: Error : Object doesn't support property or method 'attach'" Pin
Omar Al Zabir3-Jan-13 22:51
Omar Al Zabir3-Jan-13 22:51 
Questionjscript Runtime Errors Encountered Pin
Greg Frazier11-Dec-12 7:14
Greg Frazier11-Dec-12 7:14 
AnswerRe: jscript Runtime Errors Encountered Pin
Greg Frazier11-Dec-12 7:24
Greg Frazier11-Dec-12 7:24 
GeneralRe: jscript Runtime Errors Encountered Pin
Greg Frazier17-Dec-12 13:54
Greg Frazier17-Dec-12 13:54 
QuestionHow to add a view in Razor as a tile? Pin
FenRunner30-Oct-12 11:59
FenRunner30-Oct-12 11:59 
QuestionHow to create Adding SubMenu item? Pin
shakil4u22-Oct-12 3:51
shakil4u22-Oct-12 3:51 
Questionphp Conversion Pin
Charlie Love17-Oct-12 6:35
Charlie Love17-Oct-12 6:35 
AnswerRe: php Conversion Pin
Charlie Love3-Jan-13 22:45
Charlie Love3-Jan-13 22:45 
GeneralRe: php Conversion Pin
Omar Al Zabir3-Jan-13 22:52
Omar Al Zabir3-Jan-13 22:52 
QuestionHTML5 features Pin
royjavelosa12-Oct-12 17:39
royjavelosa12-Oct-12 17:39 
AnswerRe: HTML5 features Pin
Omar Al Zabir13-Oct-12 0:54
Omar Al Zabir13-Oct-12 0:54 
GeneralRe: HTML5 features Pin
royjavelosa14-Oct-12 3:35
royjavelosa14-Oct-12 3:35 
GeneralRe: HTML5 features Pin
Omar Al Zabir14-Oct-12 5:46
Omar Al Zabir14-Oct-12 5:46 
Questionget only a single section Pin
Karthik Chintala1-Oct-12 19:40
Karthik Chintala1-Oct-12 19:40 
AnswerRe: get only a single tile Pin
Omar Al Zabir1-Oct-12 22:19
Omar Al Zabir1-Oct-12 22:19 
GeneralRe: get only a single section Pin
Karthik Chintala1-Oct-12 22:49
Karthik Chintala1-Oct-12 22:49 
GeneralRe: get only a single section Pin
Omar Al Zabir1-Oct-12 22:55
Omar Al Zabir1-Oct-12 22:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.