Responsive web design term is related to the concept of
developing a website design in a manner, that helps the lay out to get changed
according to the user’s computer screen resolution. More precisely, the concept
allows for an advanced 4 column layout 1292 pixels wide, on a 1025 pixel width screen, that auto-simplifies into 2
columns. Also it suitably fixes on the smartphone and computer tablet screen.
SignalR is an Async library for .NET to help build
real-time, multi-user interactive web applications
LESS extends CSS with dynamic behavior such as variables,
mixins, operations and functions. LESS runs on both the client-side (Chrome,
Safari, Firefox) and server-side, with Node.js and Rhino.
In this article, we’ll create a simple retrospective app
using Responsive web design techniques, CSS3, LESS and SignalR that will allow
multiple collaborators to review the same article in real-time.
1. Creating
the html page.
Use the Less stylesheet language for creating the CSS for
the website. you can download the less.js files from http://lesscss.org/ that
is used in this article. You can define variables and classes using Less and
then use them in the CSS files as:
@backgroundColor: #E6E6E6;
body {
background-color: @backgroundColor;
}
.shadow(@borderColor)
{
-moz-box-shadow: 3px 3px 4px @borderColor;
-webkit-box-shadow: 3px
3px 4px @borderColor;
box-shadow: 3px 3px 4px @borderColor;
}
.goodDataContent
{
.dataContent;
.shadow(@goodBorderColor);
background-color: @goodDataBackgroundColor;
margin-left: 50px;
}
2. Using
media queries to render CSS based on screen preferences
Media queries are an excellent way to deliver different
styles to different devices, providing the best experience for each type of
user. A part of the CSS3 specification, media queries expand the role of the
media attribute that controls how your styles are applied. For .e.g. in our app
I have defined the image size and size of the contents by using media-queries
as given below.
@media all and (max-width: 700), (max-height: 500)
{
.goodImageContent
{
.imageContent(72);
background-image:url(Images/good_78x78.png);
}
.badImageContent
{
.imageContent(72);
background-image:url(Images/bad_72x72.png);
}
.betterImageContent
{
.imageContent(72);
background-image:url(Images/idea_72x72.png);
}
}
3. Creating
the Retrospective manger Hub.
Hubs provide a higher level RPC framework over a PersistentConnection. If you have
different types of messages that you want to send between server and client then
hubs is recommended so you don't have to do your own dispatching.
To get started using Hubs, create a class that derives from
Hub.
[HubName("retrospectiveManager")]
public class RetrospectiveManager : Hub
{
[HubMethodName("newCharEntry")]
public void
RegisterNewChar(string data, string content, string
teamId, string browserIp)
{
switch (content)
{
case "Good":
Clients.addGood(data, teamId, browserIp);
break;
case "Bad":
Clients.addBad(data, teamId, browserIp);
break;
case "Better":
Clients.addBetter(data, teamId, browserIp);
break;
default:
Clients.addMessage(data, teamId, browserIp);
break;
}
}
}
Our hub receives messages via the RegisterNewChar method and
broadcasts the data to addGood, addBad methods.
4. Using
connections
Create a connection between the client and the server. When
the connection has been started, we want to call the join method on the server.
retro = $.connection.retrospectiveManager;
$.connection.hub.start({ transport: 'auto' }, null);
retro.addGood = function
(data, team, id) {
if (browserId != id && teamId == team) {
$('#goodDataContentDiv').html(data);
}
};
5. HTML for
the page
<div>
<div class="sectionContent">
<div class="goodImageContent">
div>
<div class="goodDataContent"
contenteditable="true"
accesskey="G"
id="goodDataContentDiv"
onkeyup="sendGoodChar()">
What went well in this sprint?
<br />
1.
div>
div>
<div class="sectionContent">
<div class="badImageContent">
div>
<div class="badDataContent"
contenteditable="true"
accesskey="B"
id="badDataContentDiv"
onkeyup="sendBadChar()">
What didn't go well in this sprint?
<br />
1.
div>
div>
<div class="sectionContent">
<div class="betterImageContent">
div>
<div class="betterDataContent"
contenteditable="true"
accesskey="I"
id="betterDataContentDiv"
onkeyup="sendBetterChar()">
What can we do better next time?
<br />
1.
div>
div>
div>
I have provided the app as free for distributed teams to
use. You can use the app from the URL http://freeapps.agilecockpit.com/Retrospective.aspx.
Use the teamId as the querystring for similar teams so that the teams with the
same id can view data from other team members.
For e.g. you can use any number as a team id and share it
with other team members and start using it like http://freeapps.agilecockpit.com/Retrospective.aspx?teamId=22
Screen shots: