Friday, 31 October 2014

Creating a clean WebAPI project

12345

Custom validation with DataAnnotations

You can download the source:  https://github.com/stevenh77/CustomValidationWithDataAnnotations

// because sometimes you have to use MVC :)
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace CustomValidation
{
class Program
{
static void Main(string[] args)
{
var invalidPerson = new Person()
{
FirstName = "Tom",
Surname = "Tom"
};
var validPerson = new Person()
{
FirstName = "Steve",
Surname = "Hollidge"
};
Validate(validPerson);
Validate(invalidPerson);
}
private static void Validate(Person person)
{
var context = new ValidationContext(person, null, null);
var results = new List<ValidationResult>();
var isValid = Validator.TryValidateObject(person, context, results, true);
if (isValid) return;
foreach (var validationResult in results)
{
Console.WriteLine(validationResult.ErrorMessage);
}
}
}
class Person
{
[ContainsTheLetterTValidationAttribute]
public string FirstName { get; set; }
[DifferentValueValidation("FirstName")]
public string Surname { get; set; }
}
public class ContainsTheLetterTValidationAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
// check type
var stringValue = value as string;
if (stringValue == null)
{
return new ValidationResult(string.Format("Unknown type or null value"));
}
// actual validation comparison occurs here
return stringValue.ToLowerInvariant().Contains("t")
? null
: new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
public class DifferentValueValidationAttribute : ValidationAttribute
{
private readonly string other;
public DifferentValueValidationAttribute(string other)
{
this.other = other;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var property = validationContext.ObjectType.GetProperty(other);
if (property == null)
{
return new ValidationResult(
string.Format("Unknown property: {0}", other)
);
}
var otherValue = property.GetValue(validationContext.ObjectInstance, null);
// actual validation comparison occurs here
return (value ==otherValue)
? new ValidationResult(FormatErrorMessage(validationContext.DisplayName))
: null;
}
}
}

Monday, 27 October 2014

CSS3 Show Hide Divs

Here’s an example of showing and hiding divs with a CSS3 animation.

Demo: http://stevenhollidge.com/blog-source-code/showhide/

1

2

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>CSS3 Animations: Show/Hide divs</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<style>
.mainContainer {
border-color: #ddd;
border-width: 1px;
border-radius: 4px 4px 0 0;
border-style: solid;
padding: 15px;
margin: 30px;
width: 275px;
height: 260px;
transition: 0.4s;
}
.mainContainerBig {
height: 450px;
transition: 0.4s;
}
.section {
margin: 10px 0 0 0;
transition: opacity 1s ease-in 0.2s;
opacity: 0;
height: 0;
overflow: hidden;
}
.visible {
opacity: 1;
height: auto;
overflow: auto;
}
.labelRow {
margin: 20px 0 0 0;
}
.textRow {
margin: 0 0 0 0;
}
.bigLabel {
font-size: 30px;
}
</style>
</head>
<body>
<div id="mainContainer" class="mainContainer">
<div class="btn-group" data-toggle="buttons">
<label id="option1label" class="btn btn-primary active">
<input type="radio" name="options" id="option1" checked> Abbreviations
</label>
<label id="option2label" class="btn btn-primary">
<input type="radio" name="options" id="option2"> Actual Amounts
</label>
</div>
<div id='smallSection' class='section visible'>
<div class='row labelRow'>
<div class='col-md-6'>Total</div>
<div class='col-md-6'>Total</div>
</div>
<div class='row textRow'>
<div class='col-md-6 bigLabel'>560k</div>
<div class='col-md-6 bigLabel'>560k</div>
</div>
<div class='row labelRow'>
<div class='col-md-6'>Total</div>
<div class='col-md-6'>Total</div>
</div>
<div class='row textRow'>
<div class='col-md-6 bigLabel'>560k</div>
<div class='col-md-6 bigLabel'>560k</div>
</div>
</div>
<div id='bigSection' class="section">
<div class='row labelRow'>
<div class='col-md-12'>Total</div>
</div>
<div class='row textRow'>
<div class='col-md-6 bigLabel'>560,456,232.00</div>
</div>
<div class='row labelRow'>
<div class='col-md-12'>Total</div>
</div>
<div class='row textRow'>
<div class='col-md-6 bigLabel'>560,456,232.00</div>
</div>
<div class='row labelRow'>
<div class='col-md-12'>Total</div>
</div>
<div class='row textRow'>
<div class='col-md-6 bigLabel'>560,456,232.00</div>
</div>
<div class='row labelRow'>
<div class='col-md-12'>Total</div>
</div>
<div class='row textRow'>
<div class='col-md-6 bigLabel'>560,456,232.00</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script>
$('label[id=option1label]').click(function() {
showHideDivs(false);
});
$('label[id=option2label]').click(function() {
showHideDivs(true);
});
function showHideDivs(showBig) {
$('#mainContainer').toggleClass("mainContainerBig", showBig);
$('#smallSection').toggleClass("visible", !showBig);
$('#bigSection').toggleClass("visible", showBig);
}
</script>
</body>
</html>
view raw showhidedivs hosted with ❤ by GitHub

Sunday, 26 October 2014

How to fix orphaned SQL users

-- tells you the orphaned users
EXEC sp_change_users_login 'report'
-- to fix if you already have the server login:
EXEC sp_change_users_login 'Auto_Fix', 'enter your username here'
-- to fix if you don't already have the server login:
EXEC sp_change_users_login 'Auto_Fix', 'user', 'enter your login here', 'enter your password here'

Intro.js

Here’s how to add an intro to your site:

1) Download intro.js from https://github.com/usablica/intro.js/tags (which also contains lots of example usages)

2) Add the bootstrap-responsive.min.css and introjs.css files to the head of your page (see lines 6 and 7)

3) Add data-step and data-intro attributes to the sections of your page where you want the introduction to display (see lines 11, 12 and 13)

4) Add a button or link which starts the intro (see line 14)

5) Add the intro.js file to the bottom of your page (see line 16)

 

<!DOCTYPE html>
<head>
<link href="bootstrap.min.css" rel="stylesheet">
<!-- Add IntroJs styles -->
<link href="bootstrap-responsive.min.css" rel="stylesheet">
<link href="introjs.css" rel="stylesheet">
<!-- end IntroJs styles -->
</head>
<body>
<h1 data-step="1" data-intro="Welcome to my demo, this is the title of my page">Demo for intro.js</h1>
<p data-step="2" data-intro="Here is some more text">This page shows how easy it is to add intro.js</p>
<p data-step="3" data-intro="I've also included an extra UX tip for devs">You can use cookies to detect if the user is new to your page</p>
<a class="btn btn-large btn-success" href="javascript:void(0);" onclick="javascript:introJs().start();">Start intro</a>
</body>
<script type="text/javascript" src="intro.js"></script>
</html>
view raw DemoForIntroJs hosted with ❤ by GitHub

Here is an example runs the intro only the first time a user visits your page


http://stevenhollidge.com/blog-source-code/introjs/index-with-cookie.html


Friday, 24 October 2014

Injecting a Mock into Angular Service

// http://stackoverflow.com/questions/14773269/injecting-a-mock-into-an-angularjs-service
angular.module('myModule')
.factory('myService', function (myDependency) {
return {
useDependency: function () {
return myDependency.getSomething();
}
};
});
describe('Service: myService', function () {
var myService,
mockDependency;
beforeEach(module('myModule'));
beforeEach(function () {
mockDependency = {
getSomething: function () {
return 'mockReturnValue';
}
};
module(function ($provide) {
$provide.value('myDependency', mockDependency);
});
});
it('should return value from mock dependency', inject(function (myService) {
expect(myService.useDependency()).toBe('mockReturnValue');
}));
});

Extending HighCharts

Demo:  http://stevenhollidge.com/blog-source-code/highcharts/

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Markers for column type series - HighCharts example</title>
<script type='text/javascript' src='./js/jquery-1.9.1.js'></script>
<script type='text/javascript'>//<![CDATA[
$(function () {
(function (H) {
H.wrap(H.Tooltip.prototype, 'refresh', function (proceed, points) {
// Run the original proceed method
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
// For each point add or update trackball
H.each(points, function (point) {
// Function variables
var series = point.series,
chart = series.chart,
pointX = point.plotX + series.xAxis.pos,
pointY = H.pick(point.plotClose, point.plotY) + series.yAxis.pos;
// If trackball functionality does not already exist
if (!point.series.options.marker) {
// If trackball is not defined
if (!series.trackball) {
series.trackball = chart.renderer.circle(pointX, pointY, 5).attr({
fill: series.color,
stroke: 'white',
'stroke-width': 1,
zIndex: 5
}).add();
} else {
series.trackball.attr({
x: pointX,
y: pointY
});
}
}
});
});
H.wrap(H.Tooltip.prototype, 'hide', function (proceed) {
var series = this.chart.series;
// Run original proceed method
proceed.apply(this);
// For each series destroy trackball
H.each(series, function (serie) {
var trackball = serie.trackball;
if (trackball) {
serie.trackball = trackball.destroy();
}
});
});
}(Highcharts));
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=aapl-ohlcv.json&callback=?', function (data) {
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length;
for (i = 0; i < dataLength; i++) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
// set the allowed units for data grouping
var groupingUnits = [
[
'week', // unit name
[1] // allowed multiples
],
[
'month', [1, 2, 3, 4, 6]]
];
// create the chart
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
title: {
text: 'OHLC'
},
height: 200,
lineWidth: 2
}, {
title: {
text: 'Volume'
},
top: 300,
height: 100,
offset: 0,
lineWidth: 2
}],
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
});
//]]>
</script>
</head>
<body>
<script src="./js/highstock.js"></script>
<script src="./js/exporting.js"></script>
<div id="container" style="height: 500px; min-width: 500px"></div>
</body>
</html>

Wednesday, 22 October 2014

Mail Chimp UX

Generally I like Mail Chimp as a company and their UX so I might add to this blog post over time.

Validation

image

Nothing ground breaking here and it could be more responsive to the user as they insert data but I quite liked the green tick on green background to indicate a valid password.  Perhaps the errors could be in a similar style.

Another data entry example

image

Home Page

image

Wednesday, 15 October 2014

UX Hacks: Leading the User

Here are a few quick UX tips, tricks and hacks taken from the Hacking the User Experience Pluralsight course.

Original UI:

image

UI redesigned to remove noise and simplify the design:

image

Leading the user

Visual clues added to lead the user through the process (step 1, 2 and 3):

image

Another option for leading the user is an introduction overlay:

image

A third option could be to introduce a wizard:

image

Some more UX resources:

http://usabilityhub.com

image

image

Calculating color contrast in JavaScript

image

To calculate which foreground color to use on a background we have the following function:

function getContrastYIQ(hexcolor){
var r = parseInt(hexcolor.substr(0,2),16);
var g = parseInt(hexcolor.substr(2,2),16);
var b = parseInt(hexcolor.substr(4,2),16);
var yiq = ((r*299)+(g*587)+(b*114))/1000;
return (yiq >= 128) ? 'black' : 'white';
}

Taken from: http://24ways.org/2010/calculating-color-contrast/

You can use this website to confirm it meets the W3C standards:  http://snook.ca/technical/colour_contrast/colour.html

Tuesday, 14 October 2014

HTML dropdown lists and multi select

Here are a couple of options for improving dropdown lists and multi select boxes:

Select2

http://ivaynberg.github.io/select2/

image

image

Chosen

http://harvesthq.github.io/chosen/

image

image

Highlighted td blocks

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
font-family: "Lato","Helvetica Neue",Arial,sans-serif;
-webkit-font-smoothing: antialiased !important;
}
html {
font-size: 12px;
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
body {
font-family: "Lato","Helvetica Neue",Arial,sans-serif;
line-height: 1.42857;
color: gray;
}
table {
border-collapse: collapse;
border-spacing: 0;
background-color: transparent;
width: 250px;
max-width: 250px;
margin-bottom: 20px;
}
th {
text-align: left;
}
.table>thead>tr>th,.table>thead>tr>td,.table>tbody>tr>th,.table>tbody>tr>td,.table>tfoot>tr>th,.table>tfoot>tr>td {
padding: 10px;
line-height: 1.42857;
vertical-align: top;
border-top: 1px solid #ddd;
}
.table>caption+thead>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>th,.table>thead:first-child>tr:first-child>td {
border-top: 0;
}
.table>tbody+tbody {
border-top: 2px solid #ddd;
}
.table-condensed>thead>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>tfoot>tr>td {
padding: 5px;
}
.table-bordered>thead>tr>th,.table-bordered>thead>tr>td {
border-bottom-width: 2px;
}
.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th {
background-color: #f9f9f9;
}
.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th {
background-color: #f5f5f5;
}
table col[class*="col-"] {
position: static;
float: none;
display: table-column;
}
table td[class*="col-"],table th[class*="col-"] {
position: static;
float: none;
display: table-cell;
}
label {
display: inline-block;
max-width: 100%;
margin-bottom: 5px;
font-weight: bold;
}
.label-info {
background-color: #56bdf1;
}
.label-primary {
background-color: #1bb7a0;
}
.label-success {
background-color: #94b758;
}
.label-danger {
background-color: #fa7b58;
}
.label-warning {
background-color: #f3c536;
}
.label {
display: inline;
padding: .5em .8em;
font-size: 75%;
font-weight: bold;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
}
</style>
</head>
<body>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>Status</th>
<th>Player</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td><span class="label label-info">Goalkeeper</span></td>
<td>Julian Speroni</td>
</tr>
<tr>
<td>2</td>
<td><span class="label label-primary">Right back</span></td>
<td>Joel Ward</td>
</tr>
<tr>
<td>3</td>
<td><span class="label label-success">Defender</span></td>
<td>Scott Dann</td>
</tr>
<tr>
<td>4</td>
<td><span class="label label-warning">Midfielder</span></td>
<td>Mile Jedinak</td>
</tr>
<tr>
<td>5</td>
<td><span class="label label-danger">Winger</span></td>
<td>Yannick Bolaise</td>
</tr>
</tbody>
</table>
</body>
</html>

Monday, 13 October 2014

Example of DataRepository pattern

Here is a quick example of a data repository pattern used with EF. Note the UpdateEntity method in AccountRepository purely returns the entity to be updated, this perhaps should be named more clearly.

public class AccountRepository : DataRepositoryBase<Account>, IAccountRepository
{
protected override Account AddEntity(CarRentalContext entityContext, Account entity)
{
return entityContext.AccountSet.Add(entity);
}
protected override Account UpdateEntity(CarRentalContext entityContext, Account entity)
{
return (from e in entityContext.AccountSet
where e.AccountId == entity.AccountId
select e).FirstOrDefault();
}
protected override IEnumerable<Account> GetEntities(CarRentalContext entityContext)
{
return from e in entityContext.AccountSet
select e;
}
protected override Account GetEntity(CarRentalContext entityContext, int id)
{
var query = (from e in entityContext.AccountSet
where e.AccountId == id
select e);
var results = query.FirstOrDefault();
return results;
}
public Account GetByLogin(string login)
{
using (CarRentalContext entityContext = new CarRentalContext())
{
return (from a in entityContext.AccountSet
where a.LoginEmail == login
select a).FirstOrDefault();
}
}
}
public abstract class DataRepositoryBase<T> : DataRepositoryBase<T, CarRentalContext>
where T : class, IIdentifiableEntity, new()
{
}
public abstract class DataRepositoryBase<T, U> : IDataRepository<T>
where T : class, IIdentifiableEntity, new()
where U : DbContext, new()
{
protected abstract T AddEntity(U entityContext, T entity);
protected abstract T UpdateEntity(U entityContext, T entity);
protected abstract IEnumerable<T> GetEntities(U entityContext);
protected abstract T GetEntity(U entityContext, int id);
public T Add(T entity)
{
using (U entityContext = new U())
{
T addedEntity = AddEntity(entityContext, entity);
entityContext.SaveChanges();
return addedEntity;
}
}
public void Remove(T entity)
{
using (U entityContext = new U())
{
entityContext.Entry<T>(entity).State = EntityState.Deleted;
entityContext.SaveChanges();
}
}
public void Remove(int id)
{
using (U entityContext = new U())
{
T entity = GetEntity(entityContext, id);
entityContext.Entry<T>(entity).State = EntityState.Deleted;
entityContext.SaveChanges();
}
}
public T Update(T entity)
{
using (U entityContext = new U())
{
T existingEntity = UpdateEntity(entityContext, entity);
SimpleMapper.PropertyMap(entity, existingEntity);
entityContext.SaveChanges();
return existingEntity;
}
}
public IEnumerable<T> Get()
{
using (U entityContext = new U())
return (GetEntities(entityContext)).ToArray().ToList();
}
public T Get(int id)
{
using (U entityContext = new U())
return GetEntity(entityContext, id);
}
}
public interface IDataRepository
{
}
public interface IDataRepository<T> : IDataRepository
where T : class, IIdentifiableEntity, new()
{
T Add(T entity);
void Remove(T entity);
void Remove(int id);
T Update(T entity);
IEnumerable<T> Get();
T Get(int id);
}
public interface IIdentifiableEntity
{
int EntityId { get; set; }
}
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using CarRental.Business.Bootstrapper;
using CarRental.Business.Entities;
using CarRental.Data.Contracts;
using Core.Common.Contracts;
using Core.Common.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace CarRental.Data.Tests
{
[TestClass]
public class DataLayerTests
{
[TestInitialize]
public void Initialize()
{
ObjectBase.Container = MEFLoader.Init();
}
[TestMethod]
public void test_repository_usage()
{
RepositoryTestClass repositoryTest = new RepositoryTestClass();
IEnumerable<Car> cars = repositoryTest.GetCars();
Assert.IsTrue(cars != null);
}
[TestMethod]
public void test_repository_factory_usage()
{
RepositoryFactoryTestClass factoryTest = new RepositoryFactoryTestClass();
IEnumerable<Car> cars = factoryTest.GetCars();
Assert.IsTrue(cars != null);
}
[TestMethod]
public void test_repository_mocking()
{
List<Car> cars = new List<Car>()
{
new Car() { CarId = 1, Description = "Mustang" },
new Car() { CarId = 2, Description = "Corvette" }
};
Mock<ICarRepository> mockCarRepository = new Mock<ICarRepository>();
mockCarRepository.Setup(obj => obj.Get()).Returns(cars);
RepositoryTestClass repositoryTest = new RepositoryTestClass(mockCarRepository.Object);
IEnumerable<Car> ret = repositoryTest.GetCars();
Assert.IsTrue(ret == cars);
}
[TestMethod]
public void test_factory_mocking1()
{
List<Car> cars = new List<Car>()
{
new Car() { CarId = 1, Description = "Mustang" },
new Car() { CarId = 2, Description = "Corvette" }
};
Mock<IDataRepositoryFactory> mockDataRepository = new Mock<IDataRepositoryFactory>();
mockDataRepository.Setup(obj => obj.GetDataRepository<ICarRepository>().Get()).Returns(cars);
RepositoryFactoryTestClass factoryTest = new RepositoryFactoryTestClass(mockDataRepository.Object);
IEnumerable<Car> ret = factoryTest.GetCars();
Assert.IsTrue(ret == cars);
}
[TestMethod]
public void test_factory_mocking2()
{
List<Car> cars = new List<Car>()
{
new Car() { CarId = 1, Description = "Mustang" },
new Car() { CarId = 2, Description = "Corvette" }
};
Mock<ICarRepository> mockCarRepository = new Mock<ICarRepository>();
mockCarRepository.Setup(obj => obj.Get()).Returns(cars);
Mock<IDataRepositoryFactory> mockDataRepository = new Mock<IDataRepositoryFactory>();
mockDataRepository.Setup(obj => obj.GetDataRepository<ICarRepository>()).Returns(mockCarRepository.Object);
RepositoryFactoryTestClass factoryTest = new RepositoryFactoryTestClass(mockDataRepository.Object);
IEnumerable<Car> ret = factoryTest.GetCars();
Assert.IsTrue(ret == cars);
}
}
public class RepositoryTestClass
{
public RepositoryTestClass()
{
ObjectBase.Container.SatisfyImportsOnce(this);
}
public RepositoryTestClass(ICarRepository carRepository)
{
_CarRepository = carRepository;
}
[Import]
ICarRepository _CarRepository;
public IEnumerable<Car> GetCars()
{
IEnumerable<Car> cars = _CarRepository.Get();
return cars;
}
}
public class RepositoryFactoryTestClass
{
public RepositoryFactoryTestClass()
{
ObjectBase.Container.SatisfyImportsOnce(this);
}
public RepositoryFactoryTestClass(IDataRepositoryFactory dataRepositoryFactory)
{
_DataRepositoryFactory = dataRepositoryFactory;
}
[Import]
IDataRepositoryFactory _DataRepositoryFactory;
public IEnumerable<Car> GetCars()
{
ICarRepository carRepository = _DataRepositoryFactory.GetDataRepository<ICarRepository>();
IEnumerable<Car> cars = carRepository.Get();
return cars;
}
}
}

This example was taken from Miguel Castro and uses MEF as it's DI container.

Friday, 10 October 2014

Resolving within Angular routing

You can have your routing code make services or data available to your controller by using resolve.

image

This is how we expose these functions to the controller:

image

image