feedback
Mar 11 2009

MVC Edit View Template Upgrades

by John Dyer

I’m building a new LMS using ASP.NET MVC and I am making heavy use of the View templates added in RC1. (see: T4 Templates: A Quick-Start Guide for ASP.NET MVC Developers)

I made a few changes to the default template to allow (1) table rows and cells instead of <p> tags, (2)add spaced to “ProperyName” so it looks like “Property Name”, and (3) use reflection to determine the <input> type generated by the Html helper. For all string Properties, a normal <input type=”text” /> is still generated, but for Int32, I am generating a <select> and for Booleans, a <input type=”checkbox” /> since these are the normal fields I use for forms.

For an object that looks like this

public class Person {
public string FullName { get; set; }
public bool IsActive { get; set; }
}

The default Edit View looks like this:

<p>
<label for="FullName">FullName:</label>
<%= Html.TextBox("FullName") %>
<%= Html.ValidationMessage("FullName", "*") %>
</p>
<p>
<label for="CampusID">IsActive:</label>
<%= Html.TextBox("IsActive") %>
<%= Html.ValidationMessage("IsActive", "*") %>
</p>

Here's what I wanted the Edit View to look like:

<tr>
<td class="form-title"><label for="FullName">Full Name</label></td>
<td class="form-input"><%= Html.TextBox("FullName") %></td>
<td class="form-val"><%= Html.ValidationMessage("FullName", "*") %></td>
</tr>
<tr>
<td class="form-title"><label for="Password">Is Active</label></td>
<td class="form-input"><%= Html.CheckBox("IsActive") %></td>
<td class="form-val"><%= Html.ValidationMessage("IsActive", "*") %></td>
</tr>

Here’s how I handled the different property types

Property Type Html Helper Output
String (and others) Html.TextBox <input type="text" />
Boolean Html.CheckBox <input type="checkbox" />
Int32 Html.DropDownList <select>

You can modify this easily in the code below to put whatever controls you want for each property type. To use the template, just create a folder in your project called CodeTemplates\AddView:

image

Here is my are the parts of Edit.tt file that I updated:

<#
    
if(!String.IsNullOrEmpty(mvcHost.ViewDataTypeGenericString)) {
List<PropertyInfo> properties = new List<PropertyInfo>();
FilterProperties(mvcHost.ViewDataType, properties);
#>
<%= Html.ValidationSummary() %> <% using (Html.BeginForm()) {%>


<table class="form-admin">
<#
foreach(PropertyInfo pi in properties) {
#>
<tr>
<td class="form-title"><label for="<#= pi.Name #>"><#= FormatLabel(pi.Name) #></label></td>
<td class="form-input"><%= Html.<#= GetInputType(pi) #>("<#= pi.Name #>") %></td>
<td class="form-val"><%= Html.ValidationMessage("<#= pi.Name #>", "*") %></td>
</tr>
<#
}
#>
</table>
<input type="submit" value="Save" />
<% } %>


<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
<#+
public string FormatLabel(string label) {
return System.Text.RegularExpressions.Regex.Replace(label, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 ");
}


public string GetInputType(PropertyInfo pi) {
switch (pi.PropertyType.ToString()) {
case "System.Int32":
case "System.Int64":
return "DropDownList";
case "System.Boolean":
return "CheckBox";
case "System.String":
default:
return "TextBox";
}
}



public void FilterProperties(Type type, List<PropertyInfo> properties) { if(type != null) {
PropertyInfo[] publicProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);


foreach (PropertyInfo pi in publicProperties)
{
if (IsBindableType(pi.PropertyType) && pi.CanRead && pi.CanWrite)
{
properties.Add(pi);
}
}
}
}
#>

Hope this is helpful to you!

Feb 20 2009

iTunesU Manager App Source Released

by John Dyer

A while back, I created an iTunesU Manager application for DTS's iTunesU site, and I finally got around to putting up the source code and executables. Below is a screenshot of the app and links to the Google code repository. The app requires .NET 2.0 (it's written in C#) and an iTunesU administrative account.

iTunesU Manager
Jan 16 2009

Nested Comments for BlogEngine.NET

by John Dyer

There are some great changes coming for BlogEngine.NET 1.5.0.0, and one of them is nested comments! I checked in the changes to Codeplex just last night, and I’ve implemented them here as a demo while we hammer out the final details.

Nested (or threaded) comments have been added to a lot of blog platforms lately (including WordPress 2.7), and it is a major feature of comment plugins like Disqus and Intense Debate. I personally think threaded comments make longer posts with lots of comments make a lot more sense.

Here’s an example of how a the comments in a recent post of mine make a lot more sense after turning on nesting. Since I responded in bursts to comments, they were out of order, but with nesting you can see that my comment (in dark brown) are now contextually nested and make much more sense. (Note: To make this work, I had to go back and manually add the “parentid” attribute to my comments to make them nested.)

Before (not nested)

After (nested)

Not nested Not Nested

 

If you want to try it out, you can try it on this post or download the latest check-in from Codeplex. Just be warned that this isn’t the final release. There may be some quirks in the JavaScript.

To add nesting to your existing themes, you’ll need to add the following code (marked by HTML comments) from the Standard Theme:

<div id="id_<%=Comment.Id %>" class="vcard comment<%= Post.Author.Equals(Comment.Author, StringComparison.OrdinalIgnoreCase) ? " self" : "" %>">
<p class="date"><%= Comment.DateCreated %> <a href="#id_<%=Comment.Id %>">#</a></p>
<p class="gravatar"><%= Gravatar(80)%></p>
<p class="content"><%= Text %></p>
<p class="author"> <%= Comment.Website != null ? "<a href=\"" + Comment.Website + "\" class=\"url fn\">" + Comment.Author + "</a>" : "<span class=\"fn\">" +Comment.Author + "</span>" %>
<%= Flag %>
<%= ((BlogEngine.Core.BlogSettings.Instance.IsCommentNestingEnabled && Comment.IsApproved) ? " | " : "") %>
<%= ReplyToLink %> <!—- add this for reply to links –>
<%= AdminLinks %>
</p> </div>
<!—- Start: threading –>
<div class="comment-replies" id="replies_<%=Comment.Id %>" <%= (Comment.Comments.Count == 0) ? " style=\"display:none;\"" : "" %>>
<asp:PlaceHolder ID="phSubComments" runat="server" />
</div>
<!—- End: threading –>

Hope you like it, and let me know if you implement it on your site!

Dec 8 2008

Everyone’s Going “HD” (Sort of)

by John Dyer

Last week, YouTube made big news by introducing “HD” video, thought it’s unclear what YouTube’s definition of “HD” is. The video is certainly higher definition, but it’s certainly not 720p or 1080p which is technically what HD is supposed to be. It might be 480p which is what Hulu.com does for their high quality streams (and is also what the Wii ouputs).

At DTS, we also recently revamped our videos to be “HD” (in the higher definition sense), moving to 480p in most cases.

We’ve also changed the player quite a bit. The old player had a lot of “chrome” around it and this new one is chromeless (ala Vimeo) and has the option to popout (similar to Hulu). Compare the old player below, with the new player showing two recent profiles, one of an alumnus and the other of a currents student who is also an NFL player.

Old player

image

New Embedded Player Samples

Some Technical Information

This player needed to be able to play both MP4s for video and MP3s for audio. Unfortunately, Flash’s built-in video controls like PlayButton and Seekbar only work for video, and there is no way to use them for audio. I wrote a some wrapper classes that can handle both MP4/FLVs and MP3s and normalizes the event model so they can both be hooked to the same control UI. If we move back to streaming it should be easy to write another class for that and have it all “just work.”

If anyone is interested in the source code, I’d be happy to publish it as an example of a Flash IDE AS3 video player that can also handle MP3s.

Dec 8 2008

Technology Blog

by John Dyer

I would like to keep this blog focused on technical developments and code samples, but a few recent posts have been showing I am growing in my interest for the philosophy behind technology. To keep the two interests separate, I’ve started a separate blog called

www.donteatthefruit.com

It will be aimed at discussing the influence of technology on society and human relationships. Right now, I’m looking at Neil Postman’s “Five Things You Need to Know about Technological Change” as related to churches.

Stay tuned to this blog for more technical developments!

Dec 2 2008

PNG transparency in IE6 (without JavaScript)

by John Dyer

As most of us know IE6 does not support PNGs with alpha transparency. We recently updated DTS’s site with some popups that have a drop shadow using PNG-24 images with alpha transparency. Here’s how it looks in IE6 compared to any modern browser (FF, IE7, Opera, Safari, Chrome, etc.). Notice the nasty blue border.

PNG-32 (problems in IE6)

IE6
image

Correct Display
image

I wish we could ignore IE6 users, but around 20% of our traffic still hasn’t upgraded, so we have to make it work for them. There are tons of JavaScript and CSS hacks out there to get IE6 to display PNGs with alpha transparency correctly, but we’re trying to avoid hacks whenever possible so as to not break things in the future. Also IE6’s filter technology can cause other problems. To fix this, I found a sweet “non-hack” solution on sitepoint which recommends using PNG-8 instead of PNG-24.

To summarize the article on PNG-8 and PNG-32.

PNG-32 PNG-8
16.7 million colors (like a JPEG) 256 colors (like a GIF)
alpha transparency, not just indexed (like GIF) alpha transparency (just like PNG-32)
doesn’t work in IE6 works in IE6 like a GIF (indexed transparency)

 

PNG-8 with alpha transparency (IE6 works, pretty much)

Here’s what the PNG8 looks like in IE6 on our site. Notice that the drop shadow is missing, but the transparency still remains.

IE6
 image

Correct Display
image

Everything “works” for IE6 users even thought it’s a slightly downgraded experience since the shadow is missing. For us, this is preferable to using JavaScript or CSS hacks that could cause other problems with animation. Since this is a image that only needs 256 colors, the PNG-8 is the perfect solution that is win-win-win.

How to make Alpha PNG-8 Images

The problem with all of this is that there is only one program that can make this specific kind of PNG-8 – Adobe Fireworks. Photoshop can’t do it, and I’m not sure if any other graphics programs can either. Here’s a step by step for making the PNG-8

1. Open the PNG-32 (or photoshop file)

image

2. Change the Image Type to “PNG 8”

image

3. Change to “Alpha Transparency”, then click the “Rebuild” button

Now you will see the new color palette with alpha colors. IE6 will only display the solid colors, not the fully transparent (upper left) or semi-transparent (the three with inset clear boxes).

image 

image

4. Chose File-Export to save the PNG-8

image

And that’s it. It takes a little more time but has made our development easier and provides a more stable experience for users.

Sources

Sep 15 2008

Wii + Flash + Papervision3D + C# = Alumni World Map

by John Dyer

The 2008 class gift for Dallas Seminary is supposed to be a large flat screen with a 3D world that shows where in the world DTS alumni are serving. The requirements were:

  1. The target OS is still unknown and I haven't done much native Windows or Mac 3D programming. This leads me to use Papervision in Flash which I know and is very easy to use.
  2. The data needs to be easily updatable. Rather than use a database, I built a flat file using a quick C# app that plots alumni by state and country and geocodes their location.
  3. At DTS, the Admissions and Alumni offices are nearby, so the application needs to be interesting to Admissions. Ever since my sweet wife got me a Nintendo Wii a few months ago, I've wanted an excuse to program with it. For this project I thought, What's more fun and interesting than controlling the globe with a Nintendo Wii controller?

Video Demo

Here is a (low quality) video of an early version of the project that gives you an idea of what it's supposed to accomplish and look like. The first few seconds use mouse navigation, then it switches to WiiMote navigation.

wiiflashworld
This video requires Adobe Flash player

Live Demo

To see a live demo, click the following image. If you want to control using a WiiMote, do the following. (1) connect your WiiMote to a PC via bluetooth. (2) Download the WiiFlash 0.4 package (3) run the included WiiFlash Server, (4) refresh the demo page page, (5) click the "Home" button the WiiMote to toggle controlling via mouse or WiiMote.

Alumni World Globe

 

Libraries Used

All the tools for this project have been around for almost a year, so nothing is particularly cutting edge, but the mashup and purpose are pretty unique and really fun. Hopefully, playing with the WiiMote will be as fun as actually viewing the map, making the entire experience for prospective students really positive.

Aug 20 2008

Papervision3D Bookshelf

by John Dyer

I recently completed a website that catalogs books and in the development I wanted to make something really new. The backend is all ASP.NET, implementing UrlRewriter.NET and AJAX.NET libraries. The frontend uses several JavaScript libraries including Prototype, Scriptaculous, and Tablesort.

The one really unique feature of the site is the 3D bookshelf built using Papervision3D. Just yesterday it was featured in blog Daily PV3D as Papervision showcase.

You can check out the book shelf here:

http://www.bestcommentaries.com/category/proverbs/

Screenshots

Plain bookshelf:

image

Mouse over the third book from the left:

image 

Book clicked:

image

How it works

Using Papervision, it's relatively easy to make a 6 sided polygon (cube) and then wrap images around it. I use the physical dimensions of the actual book to size the cube. Then, for the cover, I use an image of the book and wrap the last pixel around the side since I don't have spin images. I tried using System.Drawing code to write the author's name on the spine, but I could never get it to look just right, so I left it out. The only real catch was that I needed to place the shelf on a different Papervision scene to prevent clipping problems. The bookshelf also interacts with an HTML table down below via Flash's JavaScript ExternalInterface.

Since developing this 3D bookshelf, I found one site that does something somewhat similar, but they have the spine images which I can't afford to find for 1000s of books. Also, I think that the JavaScript interaction on mine might give it an edge.

Aug 18 2008

Podcast on Technology

by John Dyer

A few weeks ago, I was invited to speak on a podcast with the best possible name of all time:

www.pontificast.com

image

Joey and Ryan (two smart, funny, creative guys) had me on for three episodes to discuss the effect of technology on people. I've been reading quite a few books and articles in this area lately, and concurrently such considerations have begun to move out of the academy and into the mainstream with articles such as Nicholas Carr's article "Is Google Making Us Stupid?"

Here are links to the three episodes:

Hope you enjoy!

Jul 22 2008

Show Commenter's Latest Post: BlogEngine.NET Extension

by John Dyer

Background

Over the past few weeks, I've seen a few WordPress blogs that pull in the last post from a commenter's website. I also saw a post from Mads about how to find semantic links on a webpage.

So, I mashed his code together with some code from the BlogRoll control and created an extension that goes out and looks for RSS feeds at the commenter's website and then pulls in the latest post. [side note: I wish I could say, "a half hour later ... ", but it actually took me a while to get it to work...]

It all happens asynchronously, so if you comment on this post, it'll take a few seconds for it to show up. Then it will keep checking every so often for new posts.

Example

Last year, I posted a JavaScript color picker and the post now has over 100 comments. Here's what it looks like with the extension running:

 Comments with Recent Posts

Download & Installation

  • Download Commenter's Latest Post Extension
  • The last post is wrapped in the following class so you can style it:
    <span class="commenterslastpost"></span>
  • Sometimes the ResolveLinks extension interferes with this, so you might want to add the following code around the foreach loop:
    if (e.Body.IndexOf("href=\"" + match.Value + "\"") == -1) { ... }

Add a comment to this post to see it in action...

Jul 18 2008

iTunesU Site Utility in C# (.NET)

by John Dyer

In the process of moving Dallas Seminary's content to iTunesU, I created a very simple application to edit site details via the Web Service API. It currently has the following functions:

  • Add/Edit/Delete Sections
  • Add/Edit/Delete Courses
  • Add/Edit/Delete Groups
  • Upload/Edit/Delete Tracks

There are a lot of things it doesn't do, like let you edit themes or add images to courses, but it is really helping us get started. Here's a screenshot:image

You just enter your shared secret and domain name, press "Load Site Tree" and then right click on the various items to add/edit/delete.

And here's what it looks like in iTunes.image

Download & Installation

Links

  • iTunesU Support Site - Here's where I started
  • iTunesU Java Library - this is much more fully featured and documented than my code.
  • Woolamaloo - Rich Wolf's Mac tool which is much more fully featured than this tool. He also has a Windows app, but as far as I can tell it only lets you login.

My source code is very rough, but it someone needs it, I'm happy to provide it. Also, our iTunes U site is not yet public, but it will be in a few weeks.

Jul 17 2008

Programming History

by John Dyer

From Keyvan Nayyari and Janko to Mads Kristensen and now to me comes a challenge to tell how I got into programming...

How old were you when you started programming?

I think I was around 14 or 15.

How did you get started in programming?

My friend and I made text adventure games.

What was your first language?

It was some form of BASIC.

What was the first real program you wrote?

By "text adventure game", I really mean lame spaghetti-coded ASCII choose your own adventure "games." My friend had most of the funny ideas and I did most of the programming. He's now in a crazy band in Austin, TX called Natchet Taylor, and I work at a seminary!

What languages have you used since?

ASP, PHP, C#, ActionScript, SQL, X/HTML, JavaScript, CSS, and all the rest...

What was your first professional programming gig?

When I graduated from college, I took a job as a youth pastor. I needed extra cash, so I got a job as as ASP programmer for http://www.texags.com/. At that point, all I had really done was build a personal webpage in college (with animated flaming gifs!), so I just learned everything on the job. It was great fun. In those days, I'd write everything for IE, and then fix it for Netscape. Funny how things change.

If you knew then what you know now, would you have started programming?

Totally. There's always good work, and it really frees me up to be anywhere. I've made it through an entire masters degree since I could work whenever and wherever, and still be involved with friends and in ministry.

What is the one thing you would tell new developers?

I'll cheat and go with two:

  1. Always, always, always have a signed contract with everything spelled out in detail and a 25-50% payment before writing a single line of code.
  2. Release as much code as you can (to a blog or whatever). If your code is worth publishing, it means you probably did a good job, and would be something you won't hate to go back and modify later.

What’s the most fun you’ve ever had … programming?

I would have to say programming online education stuff with foreign language support. I have no idea what any of it says, but it's really fun to develop stuff that is used in a home in Dallas, a tent in the deserts of Iraq, in the Packers lockerroom, and in an underground church in China - and all of it not just to make a buck, but to make a difference in the world. That's rock-star coding.

Okay, I'm passing this on to Nathan Smith, Chris Merritt, and John Saddington. Have fun guys.

Jun 2 2008

Online Education Player Design Considerations

by John Dyer

Dallas Seminary has been doing video-based online education for about 5 years now. One of the initial goals was to replicate the classroom teaching experience as much as possible by including the video and the professor's illustrations (Powerpoint, Keynote, etc.). Beyond that, we also wanted to enhance the experience by adding things like a transcript and editing down the video to the most important segments.

Our initial player was created by Yahoo!'s Broadcast.com division and it used HTML frames and Windows media. This limited us to Internet Explorer, but there was no other option at the time. Then Flash 7 came out with video support and I custom built the player below. Since then, video on the web has come a long way, and the introduction of H.264 support means that we only need one format for playing on the web and on the desktop.

Here is the original design using 320x240 video and 480x360 slides:

  • image

Here are some changes we wanted to make:

  • Move from Flash 8 to 9 - use AS3 and enable fullscreen support
  • Use H.264 video - to simplify our workflow
  • Increase the video size, quality, and availability
  • Some users found the auto-scrolling transcript distracting and we need another option for them
  • Many classes don't have slides, so we need to de-emphasize those, yet also provide a good slide navigation system.
  • More narrow player - the current design is about 850px which makes it hard to have many more windows open at the same time.

Here are wireframe mockups of various design proposals

  • First player (2003) using Yahoo!'s Broadcast.com using HTML/Frames/WMV
    Obviously, WMV is limited to really working in IE, and we were stuck with Yahoo!'s platform.
    image
    old_online_ed_Yahoo_Video_Skin
  • Flash player with 320x240 video
    This player is wider since the slides are bigger, but the transcript is more narrow column which makes it easier to read.
    image 
    image

New Designs

  • Swapped video and slides sizes, controls at the bottom
    This swaps the video and slide sizes. It's nice, but the transcript is far away and the slides are hard to read. The player is also still very wide.
    image
  • Larger video size, small slides on the side
    To make the video even bigger, the transcript is now a single line like closed captioning on TV. Rather than give the slides their own dedicated space, the slides have a tray on the right and the full size slide appears over the video for a few seconds. The width is slightly smaller, but not much.
    image
     
  • Coverflow Style Player
    To make the player more narrow (for multi-tasking), we move the slides to the bottom and use the Apple CoverFlow to show a lot of them at once. This makes the player more narrow which is good, but also taller. To shorten it, we've moved all the controls on top of the video that appears/diasppears on mouse hover.

     image

    Here is a screenshot of a fairly common desktop size (1680x1050) with MS Word and a preview version of this player open. (note: I've made sure the controls are visible for the screenshot, but they are hidden normally) 
    image
    image

This seems effective, but there is a possible drawback in that the Coverflow might be somewhat distracting to some students (it can be turned off). Also, some may prefer the older style transcript with more than one line visible at once.

Links to preview the players:

Another future goal is to build the player as an AIR application so that videos can be downloaded for offline use.

May 15 2008

ISBN Functions in C# (ISBN-10 to ISBN-13 Conversion)

by John Dyer

While working with some book data, I needed to merge the old ISBN-10 and ISBN-13 data. Unfortunately, I couldn't find any C# code to do the conversion. Search for "ISBN C#" in Google only return book stores with C# books.

So here is a little class that will convert and validate ISBNs. Here's how the code would look:

string isbn10 = "0830818030"; 
string isbn13 = ISBN.Convert10to13(isbn10); // returns "9780830818037"

string isbn = "083081803X"; // this one has a bad checksum (last digit) 
string correctIsbn = ""; 
if (!ISBN.IsValid(isbn, out correctIsbn)) { 
	isbn = corretnIsbn; // returns "0830818030"
}

An ISBN object can also be instantiated and used:

IBSN myBook = new ISBN("0-83081-803-0"); 
string isbn13 = myBook.ISBN13; // returns "9780830818037"
string isbn10 = myBook.ISBN10; // returns "0830818030" 

Here is the class:

public class ISBN
    {

        public ISBN(string isbn)
        {
            SetIsbn(isbn);
        }

        private string _isbn10 = "";
        private string _isbn13 = "";

        public string ISBN10
        {
            get
            {
                return _isbn10;
            }
            set
            {                
                string corrected = "";
               
                if (!IsValid(value, out corrected) && corrected == "")
                    throw new Exception("invalid ISBN");

                SetIsbn(corrected);
            }
        }

        public string ISBN13
        {
            get
            {
                return _isbn13;
            }
            set
            {
                string corrected = "";

                if (!IsValid(value, out corrected) && corrected == "")
                    throw new Exception("invalid ISBN");

                SetIsbn(corrected);
            }
        }

        private void SetIsbn(string isbn)
        {
            isbn = CleanIsbn(isbn);

            if (isbn.Length == 10)
            {
                _isbn10 = isbn;
                _isbn13 = Convert10to13(isbn);
            }
            else if (isbn.Length == 13)
            {
                _isbn13 = isbn;
                _isbn10 = Convert13to10(isbn);
            }
        }

        private static string CleanIsbn(string isbn)
        {
            return isbn.Replace("-", "").Replace(" ", "");
        }


        public static string Convert10to13(string isbn)
        {
            return Convert10to13(isbn, true);
        }
        public static string Convert10to13(string isbn, bool throwError) {
            
            // remove - and space
            string isbn10 = CleanIsbn(isbn);

            if (isbn10.Length != 10 && throwError)
                throw new Exception("ISBN must be 10 characters long");

            // 1) Drop the check digit (the last digit)
            isbn10 = isbn10.Substring(0, 9);

            // 2) Add the prefix '978' 
            string isbn13 = "978" + isbn10;

            // 3) Recalculate check digit 
            isbn13 = isbn13 + Isbn13Checksum(isbn13);

            return isbn13;
        }

        public static string Convert13to10(string isbn)
        {
            return Convert13to10(isbn, true);
        }

        public static string Convert13to10(string isbn, bool throwError)
        {

            // remove - and space
            string isbn13 = CleanIsbn(isbn);

            if (isbn13.Length != 13 && throwError)
                throw new Exception("ISBN must be 13 characters long");

            // 1) Drop the check digit (the last digit) and prefix '978'
            string isbn10 = isbn13.Substring(3, 9);
     
            // 2) Recalculate your check digit using the modules 10 check digit routine.
            isbn10 = isbn10 + Isbn10Checksum(isbn10);

            return isbn10;
        }

        public static bool IsValid(string isbn)
        {
            string correctIsbn = "";
            return IsValid(isbn, out correctIsbn);
        }

        public static bool IsValid(string isbn, out string correctISBN)
        {
            // remove - and space
            isbn = CleanIsbn(isbn);

            if (isbn.Length == 10) {
                return ValidateIsbn10(isbn, out correctISBN);
            }
            else if (isbn.Length == 13)
            {
                return ValidateIsbn13(isbn, out correctISBN);
            }
            else
            {
                correctISBN = "";
                return false;
            }

        }

        private static string Isbn10Checksum(string isbn)
        {
            int sum = 0;
            for (int i = 0; i < 9; i++)
                 sum += (10-i) * Int32.Parse(isbn[i].ToString());
   
            float div = sum / 11;
            float rem = sum % 11;

            if (rem == 0)
                return "0";
            else if (rem == 1)
                return "X";
            else
                return (11 - rem).ToString();
        }

        private static string Isbn13Checksum(string isbn)
        {
            float sum = 0;
            for (int i = 0; i < 12; i++)
                sum += ((i % 2 == 0) ? 1 : 3) * Int32.Parse(isbn[i].ToString());

            float div = sum / 10;
            float rem = sum % 10;

            if (rem == 0)
                return "0";
            else
                return (10 - rem).ToString();
        }


        private static bool ValidateIsbn10(string isbn, out string correctISBN)
        {
            correctISBN = isbn.Substring(0, 9) + Isbn10Checksum(isbn);

            return (correctISBN == isbn);
        }

        private static bool ValidateIsbn13(string isbn, out string correctISBN)
        {
            correctISBN = isbn.Substring(0, 12) + Isbn13Checksum(isbn);

            return (correctISBN == isbn);
        }
}

I initially wanted to also make a method that would add back in the correct dashes, but I found out that the make up is based on country and publisher codes assigned by the International ISBN Agency which regularly updates the list of codes making it pretty much impossible to permanantly functionalize.

May 12 2008

The Best Way to Demo Websites for Clients

by John Dyer

For the last few years, my web team has used a projector to collaborate on web projects. We use it for going through our weekly work items, demoing designs, doing training, and so on.

Unfortunately, it was an old projector with a weak bulb so we always had to turn out the lights to use it. Even then it was hard to see because the contrast and color depth were poor, and the resolution was only 1024x768. So last year I budgeted to get a new projector to solve these problems.

Instead of getting a new projector, I decided to get a LCD HDTV and use it as a monitor. I found a killer deal at Sam's Club on a 65" Olevia. The screen isn't quote as nice as something like a Sony, but for what we are doing, it is absolutely amazing. The 1920x1080 resolution and super bright LCD screen is perfect for looking at web designs. In this pic, We have our task app on the right and a full size web page on the left. Even though the text is tiny it's readable from about 8' away:

IMG_3278 

IMG_3279

I have an old PC running the display, and I'm using a few little utilities to make enhance presentations:

  • PowerStrip - Some PCs and Macs can't natively display 1920x1080 resolution. This little Windows app helps out and can usually enable even really old machines to do HD resolutions.
  • ZoomIt - this is a little app by the former SysInternals.com guys. It lets you zoom into a screen with the mouse scroll wheel and draw on the screen. This features are invaluable for mockups.
  • Zune Theme Modified - I also used a modified Zune theme, because I like how the dark colors make the UI fade into the background and focus attention on the design.

On the fun side, we can occasionally use it for things other than web design. Since we're in a basement, we don't have a good way of getting an antenna to pipe in some HD goodness, but we can watch trailers in full 1080p goodness!

IMG_3281