Click here to Skip to main content
Click here to Skip to main content

Droptiles - Metro style Live Tiles powered Web Dashboard

By , 18 Jul 2012
 

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:

    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:

    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:
    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:

    <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!

    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:

    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)

About the Author

Omar Al Zabir
Architect BT, UK (ex British Telecom)
United Kingdom United Kingdom
Member

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5membermark merrens14 Sep '12 - 10:28 
Frighteningly consistent. Smile | :)
GeneralNeed info regarding the usage of Bootstrap & Underscore js librarymemberTridip Bhattacharjee4 Sep '12 - 21:08 
you really develop a nice application.you said you use Bootstrap & Underscore js library. i am not advance developer so i did not hard about these js library. you said you use Bootstrap for generating cross browser css. it would be nice if you come with a in-depth tutorial for the use of Bootstrap library. how Bootstrap library can be use to generate cross browser css.
 
it would be also nice if you talk briefly about the usage of Underscore library also. so looking for new article on Underscore & Bootstrap.
 
thanks
Tridip
tbhattacharjee

Questionwhether can I remove the frame?membercjx775821 Aug '12 - 20:16 
Nice job! But when clicking the tile on the desktop ,it turns into frame automatically.
 
I dont want this effect at all. So how can I remove it?
 
Thks
AnswerRe: whether can I remove the frame?memberOmar Al Zabir21 Aug '12 - 21:39 
Don't set any AppUrl. See the dynamic Tile definition in Tile.js. That does not become a full screen app when clicked.
(regards) => "Omar AL Zabir"
+ "C#, ASP.NET MVP"
+ "http://omaralzabir.com";

GeneralRe: whether can I remove the frame?membercjx775821 Aug '12 - 22:01 
Thks ,it works.
But I still have some questions. I want to make the index aspx's content dynamic.
for example,If I update some information into the DB,it seems that I should update the JS file in order to make the index aspx always new.It's a problem confusing me now.
QuestionUFrame vs IFramememberDewey15 Aug '12 - 22:04 
I also noticed that you're using IFrames, and not your UFrame.
 
Is there a reason why?
AnswerRe: UFrame vs IFramememberOmar Al Zabir15 Aug '12 - 23:23 
That's for the YouTube one. can't embed Youtube inside UFrame. UFrame only works for same domain.
(regards) => "Omar AL Zabir"
+ "C#, ASP.NET MVP"
+ "http://omaralzabir.com";

GeneralRe: UFrame vs IFramememberDewey16 Aug '12 - 14:30 
Thanks!
QuestionBEWARE, this is not Open, but this is...memberDewey14 Aug '12 - 13:21 
A friend just told me that this solution costs $500 per server!
 
That's not a problem if you know it, but it's also not mentioned in the article.
 
You can get essentially the same thing here(Demo) - Windows 8 Start Page[^]
 
The source code is here - Metro-UI-CSS[^]
 
It has the basic framework, and you'll just have to add on the app launching, etc.
AnswerRe: BEWARE, this is not Open, but this is... [modified]memberOmar Al Zabir15 Aug '12 - 4:10 
It is indeed Open Source, free for personal and educational use, but not free for commercial distribution.
 
"Open Source != Free for Commericial" always my friend.
 
You are most welcome to use Metro-UI-CSS and add the features that I have made. By the time you will get to the same feature set as Droptiles and professionally QA'd product, you would have burnt more time (= money) than $500 per server.
(regards) => "Omar AL Zabir"
+ "C#, ASP.NET MVP"
+ "http://omaralzabir.com";


modified 15 Aug '12 - 10:19.

GeneralRe: BEWARE, this is not Open, but this is...memberDewey15 Aug '12 - 22:00 
I didn't equate open source = Free for commercial!
 
I merly pointed out that you told half of the story, not the full story, and when you do that, it leaves open the possibility that someone will expend energy on your project, only later to find out that it costs for their customers.
 
That's not fair, and that was the reason I thought a warning was appropriate.
 
BTW, our analysis, while partially correct, leaves out a few factors.
 
1. It's only $500 if you only envision one server.
2. If we add the features, we get two things. First a code base we can use in other places, and secondly, we obtain a learning experience.
3. We may not need all of your features, and finally,
4. We may need features you haven't implemented.
 
Don't get me wrong, I think you've done a GREAT job!
 
I just wish you had been clearer right up front on the costs, but that's just me.
GeneralRe: BEWARE, this is not Open, but this is...memberOmar Al Zabir15 Aug '12 - 23:25 
Thanks. It is now $299 per server by the way if you want to license it commercially.
(regards) => "Omar AL Zabir"
+ "C#, ASP.NET MVP"
+ "http://omaralzabir.com";

GeneralRe: BEWARE, this is not Open, but this is...memberDewey16 Aug '12 - 14:34 
For guys like me(that have their own servers), that at least makes me think about make or build, but for guys that host in the cloud, or host on shared servers, I'm not sure how they can deal with that.
 
Anyway, I truly support you getting paid for your work, and I'm really a fan of anybody that pushes the causes that you push people to contribute to.
 
You're obviously as good a person as you are a programmer.
GeneralRe: BEWARE, this is not Open, but this is...memberOmar Al Zabir16 Aug '12 - 14:37 
Thank you my friend. Sincerely appreciate your comments.
 
By the way, you can also donate the same money to charity and I will give you the license.
(regards) => "Omar AL Zabir"
+ "C#, ASP.NET MVP"
+ "http://omaralzabir.com";

QuestionHave a 5, but I only have one question...memberDewey14 Aug '12 - 11:55 
Do you EVER sleep, LOL!
 
You're producing some really good stuff... keep it up!
QuestionMixing DropTiles and MVC?memberDror Saddan8 Aug '12 - 0:08 
Is it possible to mix DropTiles and MVC together?
 
What I have in mind is this:
 
DropTiles as the default page.
 
Tiles leading into MVC pages. For examle, a Tile called Stidents that when clicked opens a student managment page built on MVC,
 
a second Tile called Instructors - leading to an Instructor managment page, etc.
 
Dror
AnswerRe: Mixing DropTiles and MVC?memberOmar Al Zabir8 Aug '12 - 3:20 
Sure just set the AppUrl of the tile to the MVC page. it will open as an app. see how Flickr and Rss Reader apps work. They are independent pages.
(regards) => "Omar AL Zabir"
+ "C#, ASP.NET MVP"
+ "http://omaralzabir.com";

Questionhttp://www.clothes8.orgmemberfkjgjhjhjnj26 Jul '12 - 4:03 
====== http://www.clothes8.org ======
 
Cheap Nike air Jordan shoes33$,Air Force 1 33$, Nike dunks SB shoe,Nike Shox shoe. Wholesale Cheap Nike shoes with discount jersey, High quality T-shirts,ED Hardy hoodies,ED hardy shoes,ED hardy Jeans,Evisu shoes,GUCCI shoes,LV Handbag,Chanel Handbag……welcome to
==== ====
 
Nike shox(R4,NZ,OZ,TL1,TL2,TL3) $30
 
Handbags(Coach lv fendi d&g) $38
 
Tshirts (Polo ,ed hardy,lacoste) $14
 
Jean(True Religion,ed hardy,coogi) $30
 
Sunglasses(Oakey,coach,gucci,Armaini) $12
 
New era cap NY $9
 
Bikini (Ed hardy,polo) $18
 
New era cap $9
 
free shipping
 
====== http://www.clothes8.org ======
 
====== http://www.salesmonsterbeats.com ======
 
====== http://www.3shopping.us ========
fgjfgjkfgj

GeneralMy vote of 5memberAamer Alduais23 Jul '12 - 22:02 
Great article Bro!
Good Job!
GeneralMy vote of 5memberprelate23 Jul '12 - 16:28 
good job
GeneralMy vote of 5memberFarhan Ghumra23 Jul '12 - 3:05 
Excellent
GeneralMy vote of 5memberMr_T17 Jul '12 - 22:35 
Great look and feel
GeneralMy vote of 5memberrspercy6517 Jul '12 - 13:55 
AWESOME!!!
QuestionGreat onemvpSacha Barber17 Jul '12 - 2:35 
I like this, what I would have liked to see even more was a bit more discussion about the tile section algorithm and the view model code.
 
Also I would love you to talk about child/parent vms if you used them. Did you?
 
Seems knockout is not that suited to doing parent/child/nested viewmodels. Or am I wrong on this one. I am also doing knockout right now.
Sacha Barber
  • Microsoft Visual C# MVP 2008-2012
  • Codeproject MVP 2008-2012
Open Source Projects
Cinch SL/WPF MVVM

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue
 
My Blog : sachabarber.net

GeneralMy vote of 5memberMonjurul Habib16 Jul '12 - 21:12 
nice one Thumbs Up | :thumbsup:

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 18 Jul 2012
Article Copyright 2012 by Omar Al Zabir
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid