Introduction
Communication - exchange of information: the exchange of information between people, e.g. by means of speaking, writing, or using a common system of signs or behavior.
D.O.T.S. is a systematic relationship of simple colored and textured circles (dots) which are used as a common system of signs to help two or more people or systems to communicate anonymously.
DOTS is fundamentally a very simple idea. At the core of the project will be a 3 x 3 grid of circles that can be clear or hold up to three colored and textured patterns. This grid when loaded with a pre-determined pattern can transmit a coded message between two ore more participants as long as all participants are aware of the pattern.
Overview - The Plan
This article is being written as a submission to the 2013 CodeProject Azure Challenge.
DOTS, while simple in idea, holds a larger challenges. There will be many different interfaces that will be available to the final project. I'm hoping to have the website, a mobile app, many types of API's using many technologies such as HTML, JavaScript, Web API, and WCF all hosted and backed by Azure. The plan is that while DOTS will have a base website, it will be able either interactively or read-only to almost any technology that can be linked to the cloud.
There can be endless uses for DOTS as a communication protocol. A website could have an imbedded DOTS map to show a system status; corporate employees could use DOTS to convey messages that they don't want in writing; lovers could whisper sweet nothings as only symbols. The ideas are endless. I'm hoping to demonstrate how the DOTS protocol can be defined to make much larger applications on top of the pre-determined DOTS maps.
First Challenge: Getting Started
This Article
Second Challenge : Building a website
This website will not be hooked to a database so I'm hoping to get the JavaScript, Mobile first responsive design (CSS), and possibly the start of how to use Web API hooked up during this challenge. While the site will be based in HTML5, I am planning on using JavaScript to make sure older browsers have accessibility to the site.
Third Challenge : Using SQL on Azure
In this challenge I will hookup the social network part of DOTS. Users will be able to anonymously register and make a new groups to share their DOTS maps. There will be an easy way for other users to join a DOTS group without registering. Any one in the group will have access to the DOTS map. DOTS will not have access rights by design because of the equal access design it will possess.
Forth Challenge: Virtual Machines
In this challenge I will setup my windows azure services that will clean up the DOTS groups as well as the WCF services which I will use as an API for the Mobile Challenge and as a general access point.
Fifth Challenge: Mobile Access
The mobile app will be aimed at the Windows 8 phone (because that's what I own) but will use JavaScript, Web API, or WCF calls to interact with Azure. My goal here is not to tie it to any one operation system so I will try to keep it as generic HTML5 and JavaScript. This will make it easy to transition to the app to many mobile environments.
I'm new to Mobile Apps so this will be the hardest challenge for me to tackle.
D.O.T.S. Website
Easter Egg
My Easter Egg has Bob spinning for the Dots and Talking. To see him, make a Green letter C with the DOTS filled in with Blue like the image below. The Easter Egg that pops up is NOT a animated PNG. It is done with jQuery Rotate plugin and is all JavaScript. I ran out of time so I didn't expand on how I did it in the article but check out the source code above if you are interested.
Key Principle and Building Style
Source Code
I purposely did this first challenge as a very basic website. I didn't put it into the larger framework so I could show how powerful javascript and css are by themselves. From here on out my source will be within a much larger framework (probably MVC 4).
Domain-driven Design
Domain-driven Design is not a methodology, framework, or design pattern per se. It's more of a way of thinking. It puts the focus on the domain logic and all work is centering around that logic. It's just a way to make sure all design is focused at a central goal.
The DOTS project's main design principle is going to be the extensible model of the protocol based on technology. By doing the front end website first, I needed to make sure there was the ability to wrap it into a larger framework and hook it up to a database and other technology. For this reason, I concentrated heavily on CSS, JavaScript, and the basic way the DOTS mapping will be work.
Frameworks / Extensibility
Wherever possible I will try to use Buy versus Build methods of designing. I try to only use well known 3rd party frameworks most of the time. In this article I will stick to only using open source frameworks except for Microsoft Azure, .NET, and Visual Studio products.
HTML5 Design
HTML5 has given us a bunch of new tools for web developing. Many of these new extensions are in response to new dynamic areas happening in the website world. In the past, we would design a website to be viewed on a computer and computer monitor only. In today's world, we need the website to be available through many types of media viewers such as phones, tablets, hybrids, as well as the desktop. The websites also need to have a much stronger client side presence with the clients (browsers) doing a lot more work than ever in the past.
Article's Assumptions
Because of the contest's time challenges, I can not go into every term and it's meanings so this article will be geared toward the intermediate or advanced web developer. I'm going to assume the reader has basic knowledge HTML, CSS, JavaScript, and maybe jQuery. I will try to show examples and show the frameworks that are used. Mostly it will be an overview and when time permits I will get into some of the cooler coding of some functions. Feel free to contact me in the future, if someone would like me to elaborate on why or how I did something specific.
CSS and Responsive Design
Responsive design is the idea to make sure the web pages have a clean look on any type of media without writing a new website for each device. The CSS styles around responsive design are known as media queries. Before we dive into those, let's discuss a very popular framework that does a lot more then responsive design; Twitter Bootstrap.
Twitter Bootstrap
Twitter Bootstrap is an awesome set of interface elements, CSS layouts, and JavaScript tools packaged together and freely available to use for website design. If anyone is designing a new website, I highly encourage you to take a look at this framework. I'm sure you will find something of use inside it.
Twitter Bootstrap Scaffolding is part of the framework that helps a developer setup responsive design and is the first key technology I used in the website. Scaffolding uses a 12 column grid system that will try to keep sections of your webpage together, defined by specific Bootstrap classes. As a webpage's width becomes smaller, the groupings from the right will fall below the groupings on the left until finally all groups are lined up. This way smaller devices you read the webpage from top to bottom where as on a monitor, group of elements can be read left to right then up and down.
Bootstrap Scaffolding responsive functions also offer predefined CSS/JavaScript classes that will hide or show sections of code based on if they are intended for certain types of media. This is very cool for easily defining to show and hide based on the device you are designing for. I didn't use these classes that much on the initial website only because I want to demonstrate different ideas of how to use media queries.
Twitter Bootstrap
Degradation vs. Mobile First CSS
Both Mobile First and Degradation responsive design is the idea to use CSS3 Media Tags to change the design look and feel based on the width of the page. The idea of degradation is to first code the Default Layout for larger media like a desktop, and then use the media queries to adjust the layout in smaller widths. Mobile first design on the other hand typically progresses further in design in each media query as the browser grows larger. Think of Mobile First as progressive enhancement of the CSS where with Degradation, you are starting with the full CSS and gracefully taking away the styles you do not need in smaller widths. Both of these design patterns are useful and should be considered based on the need of the project.
The main reason I chose degradation over mobile first is because older browsers such as IE 6-8 do not recognize media queries so the user will see the full site rather then mobile version of it. There are JavaScript libraries that will give these older browsers the ability to use media queries but I just choose not to use them unless needed.
Below shows how the media queries work in the CSS file. The default website CSS goes on top and then each change for Table, Wide Mobile, and Non-smart phones will go underneath.
@media only screen and (min-width: 768px) and (max-width: 991px) {
}
@media only screen and (min-width: 480px) and (max-width: 767px) {
<span class="code-none"><span class="code-none">}
@media only screen and (min-width: 1px) and (max-width: 479px) {
}
JavaScript - When CSS isn't enough
Responsive design mainly deals with the width of the site because scrolling down is usually not a problem. However, on my DOTS site, I purposely added a footer so I could show how to drop a element if it collides with another element. This is one area that is important to know how to do but can't always be done with CSS.
Basic HTML Footer
< div class =" footer" >
< div >
© DOTS 2013. All Rights Reserved
< / div >
< / div >
Footer CSS. Notice in this css code, an absolute position with the bottom of 0 and a width of 100% of the screen forces this footer to always stay at the bottom.
.footer {
position: absolute;
background: none #55AAFF;
bottom: 0;
width: 100%;
height: 50px; /* Height of the footer */
margin: 0 10px;
padding: 0;
}
Javascript to hide footer if goes over the .dotsTable class.
$(function () {
$(window).resize(function() {
$(' .footer' ).show();
var dotsTable = $(" .dotsTable" );
var tablebottom = dotsTable.position().top + dotsTable.height();
var footertop = $(" .footer" ).position().top;
if (footertop <= tablebottom)
$(' .footer' ).hide();
});
});
In the above jQeury code, notice I first make sure the footer is shown. You can't get a position of an object if it's hidden. jQuery has a position function that returns the top and left pixels of where the element is within the DOM window. By adding the height function to this value, you can get the bottom which I do here on the dotsTable.
I then test to see if the top of the footer is above the table bottom and if it is I then hide it. It's pretty straight forward code but important when testing and fixing elements that cross each other during a window resize.
JavaScript - DOTS Map
The DOTS map is a simple HTML table. I decided not to use <img> tags for the buttons but instead put the buttons as background images. This is a lot better because the table becomes responsive and let's the images grow and shrink with it but there's a trick to making this happen. Let me show this in the HTML and CSS that let's this functionality happen.
The HTML is extremely simple which is the goal for HTML5 page design. Notice it's just a blank table with no content.
< div class =' dotsMap' >
< div id =" dotsSelect" >
< table class =" dotsTable" >
< tr >
< td id =" r1c1" > < / td >
< td id =" r1c2" > < / td >
< td id =" r1c3" > < / td >
< / tr >
< tr >
< td id =" r2c1" > < / td >
< td id =" r2c2" > < / td >
< td id =" r2c3" > < / td >
< / tr >
< tr >
< td id =" r3c1" > < / td >
< td id =" r3c2" > < / td >
< td id =" r3c3" > < / td >
< / tr >
< / table >
< / div >
< div id =" colorSelect" >
Select color
< div class =" colors" id =" red" > < / div >
< div class =" colors" id =" green" > < / div >
< div class =" colors" id =" blue" > < / div >
< / div >
< / div >
Here's the CSS responsible for the default background dots. Please notice here that we make the background images of each <td> have the background-size style of 'contain'. This allows the images to grow or shrink with the sizing of the cell. It's a nice way to make the table truly responsive. Alternatively, if we put <img> tags inside the cells, we would have to use JavaScript or substitute new images based on certain widths.
.dotsTable tr td {
background: url(../images/dots/silverDot.png) no-repeat;
background-size: contain;
width: 124px;
height: 124px;
}
From here the jQuery takes over and gives us the full functionality of changing the dot's colors. The 3 events trigger the DOTS to be set are mousedown, mouseenter, and mouseup. These are all mouse events so currently only the mouse on the desktop or a finger on a touch screen will be able to set the dots. I'm considering ideas of how to let a keyboard select the dots in the future but for now it's not possible.
var _imgFolder = " ./images/dots/" ;
var _silverDot = " silverDot.png" ;
var _redDot = " redDot.png" ;
var _greenDot = " greenDot.png" ;
var _blueDot = " blueDot.png" ;
var _mouseDown = 0 ;
var _currentColor = " rgb(255, 0, 0)" ;
$(function () {
$(' .dotsTable td' )
.mousedown(function () {
_mouseDown = 0 ;
var silverPath = (_imgFolder + _silverDot);
var img = _redDot;
if (_currentColor == ' rgb(255, 0, 0)' )
img = _redDot;
else if (_currentColor == ' rgb(0, 128, 0)' )
img = _greenDot;
else if (_currentColor == ' rgb(0, 0, 255)' )
img = _blueDot;
var bgImage = $(this ).css(' background-image' );
if (bgImage.indexOf(img) < 0 )
{
$(this ).css(' background-image' , ' url(' + _imgFolder + img + ' )' );
if (img == _redDot)
{
$(this ).data(' toggle' , " 1" );
$(this ).data(' color' , " 1" );
}
else if (img == _greenDot)
{
$(this ).data(' toggle' , " 1" );
$(this ).data(' color' , " 2" );
}
else if (img == _blueDot)
{
$(this ).data(' toggle' , " 1" );
$(this ).data(' color' , " 3" );
}
else
{
$(this ).data(' toggle' , " 0" );
$(this ).data(' color' , " 0" );
}
}
else
{
$(this ).css(' background-image' , ' url(' + silverPath + ' )' );
$(this ).data(' toggle' , " 0" );
$(this ).data(' color' , " 0" );
}
_mouseDown = 1 ;
})
.mouseenter(function () {
if (_mouseDown == 1 )
{
var silverPath = (_imgFolder + _silverDot);
var img = _redDot;
if (_currentColor == ' rgb(255, 0, 0)' )
img = _redDot;
else if (_currentColor == ' rgb(0, 128, 0)' )
img = _greenDot;
else if (_currentColor == ' rgb(0, 0, 255)' )
img = _blueDot;
var bgImage = $(this ).css(' background-image' );
if (bgImage.indexOf(img) < 0 )
{
$(this ).css(' background-image' , ' url(' + _imgFolder + img + ' )' );
if (img == _redDot)
{
$(this ).data(' toggle' , " 1" );
$(this ).data(' color' , " 1" );
}
else if (img == _greenDot)
{
$(this ).data(' toggle' , " 1" );
$(this ).data(' color' , " 2" );
}
else if (img == _blueDot)
{
$(this ).data(' toggle' , " 1" );
$(this ).data(' color' , " 3" );
}
else
{
$(this ).data(' toggle' , " 0" );
$(this ).data(' color' , " 0" );
}
}
else
{
$(this ).css(' background-image' , ' url(' + silverPath + ' )' );
$(this ).data(' toggle' , " 0" );
$(this ).data(' color' , " 0" );
}
}
})
.mouseup(function () {
_mouseDown = 0 ;
saveDots();
});
$(' .colors' ).click(function () {
$(this ).fadeTo(" fast" , 0 .40 )
.css(' border' , ' 2px solid black' );
_currentColor = $(this ).css(" background-color" );
$(' .colors' ).not(this ).fadeTo(" fast" , 1 )
.css(' border' , ' 0' );
});
$(document).ready(function () {
$(' .colors#red' )
.fadeTo(" fast" , 0 .40 )
.css(' border' , ' 2px solid black' );
$(' #r1c1' ).data(' toggle' , " 0" );
$(' #r1c2' ).data(' toggle' , " 0" );
$(' #r1c3' ).data(' toggle' , " 0" );
$(' #r2c1' ).data(' toggle' , " 0" );
$(' #r2c2' ).data(' toggle' , " 0" );
$(' #r2c3' ).data(' toggle' , " 0" );
$(' #r3c1' ).data(' toggle' , " 0" );
$(' #r3c2' ).data(' toggle' , " 0" );
$(' #r3c3' ).data(' toggle' , " 0" );
$(' #r1c1' ).data(' color' , " 0" );
$(' #r1c2' ).data(' color' , " 0" );
$(' #r1c3' ).data(' color' , " 0" );
$(' #r2c1' ).data(' color' , " 0" );
$(' #r2c2' ).data(' color' , " 0" );
$(' #r2c3' ).data(' color' , " 0" );
$(' #r3c1' ).data(' color' , " 0" );
$(' #r3c2' ).data(' color' , " 0" );
$(' #r3c3' ).data(' color' , " 0" );
});
});
function saveDots() {
var dot1 = $(' #r1c1' ).data(' toggle' ) + ' .' + $(' #r1c1' ).data(' color' );
var dot2 = $(' #r1c2' ).data(' toggle' ) + ' .' + $(' #r1c2' ).data(' color' );
var dot3 = $(' #r1c3' ).data(' toggle' ) + ' .' + $(' #r1c3' ).data(' color' );
var dot4 = $(' #r2c1' ).data(' toggle' ) + ' .' + $(' #r2c1' ).data(' color' );
var dot5 = $(' #r2c2' ).data(' toggle' ) + ' .' + $(' #r2c2' ).data(' color' );
var dot6 = $(' #r2c3' ).data(' toggle' ) + ' .' + $(' #r2c3' ).data(' color' );
var dot7 = $(' #r3c1' ).data(' toggle' ) + ' .' + $(' #r3c1' ).data(' color' );
var dot8 = $(' #r3c2' ).data(' toggle' ) + ' .' + $(' #r3c2' ).data(' color' );
var dot9 = $(' #r3c3' ).data(' toggle' ) + ' .' + $(' #r3c3' ).data(' color' );
if ((dot1 == " 1.2" ) && (dot2 == " 1.2" ) && (dot3 == " 1.2" )
&& (dot4 == " 1.2" ) && (dot5 == " 1.3" ) && (dot6 == " 1.3" )
&& (dot7 == " 1.2" ) && (dot8 == " 1.2" ) && (dot9 == " 1.2" ))
sayHiBob();
}
The Mousedown event starts the selection of the DOTS. At that time, the user can drag the mouse over other buttons using the Mouseenter event or release the mouse triggering the Mouseup event. Whenever the Mouseup event happens we trigger the SaveDots method that will eventually make an AJAX call to the server to save the current state of the DOTS.
Notice in the JavaScript, I'm saving the DOTS information by using jQuery .data command. This is a nice way to save information but there are some catches with this The data is stored in the jQuery cache so you must retrieve the data by using the .data command and not the .attr command. The reason people tend to make this mistake is because the .data function in JQuery will attempt to convert the variable stored into a type based on the data. In example, "1.4" will be returned as number and not a string where as the storing the data with a the .attr function will always make it a string.
Publishing To Azure
This article is focused around building websites in Azure so there needs to be instructions on how to do this. Attached is a great video which shows the simple process of creating and publishing your website to Azure. Azure really does make it simple to get a website up quickly.
Closing
DOTS is going to present many unique challenges for me. This project will be the first time I branch out of my database roots and attempt to also write a communication method or protocol. In doing this, I'm hoping to gain and pass a long some great knowledge of modern techniques of building websites and interacting with the cloud.
I also would like to thank my co-workers for their help in discussing and helping me come up with an idea for entering this contest.
Computers were my hobby before many had them in their homes. I've been programming in some fashion for over 20 years. I live in South Florida with my wife, my 3 year old daughter, and my 2 year old son. They keep us busy but when I do have personal time, I'm usually hacking away on some new technology.
"Capture the domain and the programming is easy" - unknown