Scott Hanselman

NerdDinner being updated to MVC3 with Razor, HTML5, GeoLocation, EF CodeFirst, jQuery Mobile, YepNope and Modernizr and a fixed Mobile Device Capabilities ViewEngine

August 26, '11 Comments [28] Posted in ASP.NET | ASP.NET MVC | HTML5 | IE9 | Mobile | NerdDinner
Sponsored By

NerdDinner with jQuery Mobile on an iPhone asking for my locationTwo years ago Rob, Phil, and I released our MVC 1.0 book with the Gu helping with the big intro. I created the basic Nerd Dinner sample application (code here) and released the first 185 pages for free. Since the initial 1.0 release, we've had help from lots of people like Dave Ward, Andrew Aarnott and Jon Galloway on a lot of little things like JavaScript and OpenAuth support, then John V. Petersen moving us to MVC3 with Razor Views, and Peter Mourfield taking on lots of JavaScript and new features. These guys started working on a feature here and a feature there in our spare time. It's been a collaborative effort with folks dropping in, contributing here and there with long periods of silence in between.

After John V. Petersen moved us to MVC3 and Razor, Peter Mourfield got on a feature tear and now we've added or updated:

Now, to be clear, this isn't a release, it's an initial almost release. Call it an Alpha. That said, it's up live at http://www.nerddinner.com and the source continues to move forward in the Trunk on Codeplex. We've got some inconsistencies with the mobile site and back  button, and geoloc is not working completely on an iPhone but it's decent on a browser. We're working on this an hour here and an hour there, but if you, Dear Reader, find any bugs in the trunk or obvious stupid mistakes, please to let us know and *cough* submit a patch *cough*. Or at least leave a nice Issue we can track.

As we get these features working rock solid, Pete and I will do a series of posts digging in to what worked well and what didn't in each feature. Already Pete has a good blog post talking about adding HTML5 Geolocation to Nerd Dinner with yepnope.js, and Modernizr. He used yepnope, a great library for saying "do you support this feature? Yep? Get this JS. Nope? Get this JS. For example:

<script type="text/javascript">
$(document).ready(function () {
yepnope({
test: Modernizr.geolocation,
yep: '@Url.Content("~/Scripts/geo.js")',
nope: '@Url.Content("~/Scripts/geo-polyfill.js")',
callback: function (url, result, key) {
getCurrentLocation();
}
});
});
</script>

Love it. More details and code on Pete's blog post. In the image below you can see IE9 warning me that my local site wants to track my physical location.

Geolocation in IE9

Here's Firefox prompting me for a location on the live site:

Firefox wants to know where I am

And Chrome:

Chrome knows where you live!

As I said, there are surely lots of bugs and subtleties we need to iron out, but I'm glad we're actually moving this sample forward. Hope you enjoy, and do feel free to fix our bugs for us, Dear Reader. ;)

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Creating a Podcast Player with HTML5 for a IE9 Pinned Site on Windows 7

August 22, '11 Comments [8] Posted in IE9 | Javascript
Sponsored By

I was looking at the HTML5Rocks podcast player sample today, and remembered I never blogged about the poor man's Podcast Player that I created for the This Developer's Life for IE9 in April. Currently there's a Flash Player on each page on TDL and one day someone will create the One HTML5 Podcast Player to Rule Them All, but so far I haven't seen it. Most are just one-offs and samples. As is my little demo here.

The HTML5Rocks player has some clever bits to it, and it's worth you doing a View Source and checking it out. There is an empty <audio/> tag at the top of the page and they ask it "can you play MP3s?" and show a compatibility message depending on what it says. You can also put text inside the <audio/> element that will be shown if the element isn't supported at all.

 $('#compatibilityMsg').html('Your browser <strong>' + 
($('#player').get(0).canPlayType('audio/mpeg') != '' ? 'can' : 'cannot') +
'</strong> play .mp3 files using HTML5 audio');

Playing audio with the <audio> tag really couldn't be simpler. The HTML5Rocks sample has some extras like setting volume and seeking that you don't see much in samples.

I wanted to create a little Podcast player for TDL that would combine things like Site Pinning and Jump Lists with some custom buttons for pinned sites and use HTML5 audio for playing the show.

So, the features:

  • Pinnable (drag the FavIcon to the TaskBar)
  • Right-click Jumplist with Recent Shows
  • Play the show with Task Buttons from the Preview
  • Previous, Next, Play, Pause.
  • Minimal code

Plus, I'm lousy at JavaScript. Here's what it looks like in action (as an animated GIF, because those are coming back in style, didn't you hear?) for those of you who don't want to try it yourselves.

Here's the general idea as code.

On the home page there is a list of all the episodes, created from a for loop going through the database of shows. I just added a non-preload audio element next to the div for each show:

<audio id="audio-2-0-4-taste" preload="none" src="http://traffic.libsyn.com/devlife/204-Taste.mp3"></audio>
<div class="episode">
<a href='post/2-0-3-education' class="showlink">
<img src="Images//203-lead.png"
alt="2.0.3 Education" width="320" height="220"/>
<div class='title'>
<p>2.0.3 Education</p>
<div class='description'>
<p>Scott and Rob talk to two developers about the role education has played in their careers</p>
</div>
</div>
</a>
</div>

Every show has an href with a class "showlink." I collect them all and give them to my jQuery plugin:

<script>

$(function(){
$(".showlink").IE9PodcastPlayer();
});
</script>

Comments appreciated as I'm still not awesome at jQuery and JavaScript. There are some options/settings that can be passed in, but I set some defaults that work for me since I did it for this one site.

Basically, I add some buttons, setup click events to go forward and backward through the list of shows passed in.

(function( $ ){
$.fn.IE9PodcastPlayer = function(options) {

var settings = {
'playerStatusDiv' : '#podcastStatus',
'currentShowIndex' : 0
};

this.each(function() {
// If options exist, lets merge them
// with our default settings
if ( options ) {
$.extend( settings, options );
}
});

function initButtons() {
try {
// Developer sample code
if(window.external.msIsSiteMode()) {
// Add buttons listener
document.addEventListener('msthumbnailclick', onButtonClicked, false);

// Add buttons
btnPrev = window.external.msSiteModeAddThumbBarButton('/images/prev.ico', 'Previous');
btnPlayPause = window.external.msSiteModeAddThumbBarButton('/images/play.ico', 'Play');
btnNext = window.external.msSiteModeAddThumbBarButton('/images/next.ico', 'Next');

// Add styles
stylePlay = window.external.msSiteModeAddButtonStyle(btnPlayPause, '/images/play.ico', "Play");
stylePause = window.external.msSiteModeAddButtonStyle(btnPlayPause, '/images/pause.ico', "Pause");

// Show thumbar
window.external.msSiteModeShowThumbBar();
}
}
catch(e) {
// fail silently
}
}

function onButtonClicked(e) {
var btnText = "",
lastIndex = 0;

if (e.buttonID !== btnPlayPause) {

switch (e.buttonID) {
case btnPrev:
btnText = "Previous";
settings.currentShowIndex--;
if (settings.currentShowIndex < 0) { settings.currentShowIndex = 0 };
break;
case btnNext:
btnText = "Next";
lastIndex = $('audio').length-1;
settings.currentShowIndex++;
if(settings.currentShowIndex >= lastIndex) { settings.currentShowIndex = lastIndex };
break;
}

stopAll();
$(settings.playerStatusDiv).text(btnText).fadeIn('slow',
function(){playPause(settings.currentShowIndex)}
);
} else {

playPause(settings.currentShowIndex);

}
}

function stopAll() {
$('audio').each(function(){
try {
$(this)[0].pause();
}
catch(e) {
// fail silently
};
});
$(settings.playerStatusDiv).hide();
}

function playPause(podcastID) {
var player = $('audio')[podcastID];
if(player.paused)
{
player.play();
$(settings.playerStatusDiv).text("Playing...").fadeIn('slow');
}
else
{
player.pause();
$(settings.playerStatusDiv).text("Paused").fadeIn('slow');
}

updatePlayPauseButton(podcastID);
}

function updatePlayPauseButton(podcastID) {
var player = $('audio')[podcastID];
try {
if(window.external.msIsSiteMode()) {
if (player.paused)
window.external.msSiteModeShowButtonStyle(btnPlayPause, stylePlay);
else
window.external.msSiteModeShowButtonStyle(btnPlayPause, stylePause);
}
}
catch(e) {
// fail silently
}
}

function addSite() {
try {
window.external.msAddSiteMode();
}
catch (e) {
alert("This feature is only available in Internet Explorer 9. Bummer.");
}
}

initButtons();
updatePlayPauseButton(0);

if(location.pathname == "/")
{
window.external.msSiteModeClearJumpList()
window.external.msSiteModeCreateJumplist('Episodes');

//This is the stuff we selected and passed in!
this.filter(":lt(10)").each(function() {
window.external.msSiteModeAddJumpListItem($(this).text().substring(41,60), this.href, '/favicon.ico');
});

window.external.msSiteModeShowJumplist();
}

};
})( jQuery );

The one part that I had to hack and still feel yucky about is at the end here with the filter() and substring(). See how I have the truncating of the show title hard coded? I was getting too much text when I passed in the whole <a/> element and children. I need to figure out a cleaner way to tell my plugin about my titles AND my audio files. Comments always appreciated.

If you REALLY want to see a jQuery plugin that will enable pinning and dynamic jump lists and isn't a piece of crap that I wrote, check out Pinify the jQuery Site Pinning Plugin or on NuGet.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Mix 11 Videos - Download them all with RSS

April 18, '11 Comments [19] Posted in ASP.NET | ASP.NET Ajax | ASP.NET Dynamic Data | ASP.NET MVC | Channel9 | HTML5 | IE9 | IIS | Mix | NuGet | Speaking | VS2010
Sponsored By

Such a fun time was had at Mix 11 this last week in Vegas. I only saw a few talks as I was busy presenting, but now as I sit at home on my first day back, I say to myself, Self, how can I get all the Mix videos at once?

First, you can watch all the videos online at http://channel9.msdn.com/Events/MIX/MIX11 

Second, you can get them via RSS. Most major browsers are hiding the RSS button these days, but the discovery metadata is all still there. In IE9, for example, if you show the Command Bar, you can see the RSS Feeds for the Mix site:

Hey, the Mix Site has RSS feeds in its Meta Tags!

What's all this awesomeness? Oh, yes, it's the Mix talks via RSS with enclosures, just as you've always wanted. Now you can list the thousand ways that you might retrieve these lovely files and abuse Microsoft's bandwidth while hoarding knowledge on your multi-terabyte personal SAN.

Direct links to the Mix RSS feeds that include Enclosures:

So now you can get them with iTunes or Zune, or PowerShell, 'cause that's bad-ass. Yes, you can use Curl also, nyah.

$feed=[xml](New-Object System.Net.WebClient).DownloadString("http://channel9.msdn.com/Events/MIX/MIX11/RSS")
foreach($i in $feed.rss.channel.item) {
$url = New-Object System.Uri($i.enclosure.url)
$url.ToString()
$url.Segments[-1]
(New-Object System.Net.WebClient).DownloadFile($url, $url.Segments[-1])
}

Or, you can subscribe in iTunes from Advanced|Subscribe to Podcast, assume, of course, you want iTunes in your life.

I hate iTunes with the heat of a thousand suns

Or, in Zune (which is a good Podcast Downloader even if you don't have a Zune) you can go to Collection|Podcasts and click Add A Podcast:

Zune's OK

Another nice, lightweight Podcast Download is the Open Source "Juice!" from http://juicereceiver.sourceforge.net/

Juice Podcast Downloader

Go get them! Here's the presentations that Web Platform and Tools Team (ASP.NET, IIS, etc) presented:

Enjoy!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Mix 11 - Web Platform and Tools Keynote Demo Script

April 13, '11 Comments [18] Posted in ASP.NET | ASP.NET MVC | HTML5 | IE9 | Javascript | Microsoft | Mix | NuGet | VS2010 | WebMatrix
Sponsored By

It's Day 1 of the Mix 11 conference here in Las Vegas. I work for the Web Platform and Tools (that's ASP.NET, IIS, IIS Media, etc) group and I did the Web Platform demos for Scott Guthrie's part of the keynote. A lot of people in Dev and QA worked hard all year long to make some fun and cool products and as the designated "talking head," I had just 16 minutes to make all of them (people + products) look good. I hope I did them all justice.

We built a backend and a front end for Rob and my sie http://www.thisdeveloperslife.com. The show is something Rob Conery and I do moonlighting on the side (it's our hobby, not our job nor a Microsoft thing) but we needed a new site and this was a fun idea since we built the original site in WebMatrix.

If you'd like ALL the new bits, no matter what's on your machine currently, go to http://www.asp.net/get-started and use one of the new "get everything" green buttons. It'll use Web Platform Installer and if you have nothing, you'll get the free VS Express. If you have Visual Studio proper, you'll get SP1, the new MVC 3 Tools Update as well as stuff like IIS Express and SQL Compact. Get Everything.

We updated the ASP.NET Website for Mix as well, with three new sections. We've also got three 3 intro videos for each technology, as well as an all new Learning Resource section AND free videos from Pluralsight!

Here's how you make the backend I made in the Keynote. You can watch it here. ScottGu and I were after the IE9/10 section. http://live.visitmix.com/Keynotes

You can seek within the Keynote using these links:

If you'd like a MUCH more detailed "Getting Started" tutorial of mine that Rick Anderson just updated to include the new MVC 3 Tools Update, check out the C# version here, and the VB version here.

This blog post just shows you how to do what I did, check out the tutorial for much more detail.

ASP.NET MVC 3 with Tools Update - This Developer's Life Backend Administration

From Visual Studio, click File | New Project and select ASP.NET MVC 3 Application. Name it "Backend."

Add New Project

Click Internet Application and make sure Use HTML 5 is checked.

New ASP.NET MVC 3 Project

Check out your packages.config if you like, or noticed the installed packages in NuGet.

Add Library Package Reference

Right click on Models, select Add Class. Name the file Podcast.cs. Here is your Entity Framework 4.1 Code First model:

namespace Backend.Models
{
public class Episode
{
public int Id { get; set; }
[Required]
public string Title { get; set; }
public DateTime? PublishedAt { get; set; }
public string Summary { get; set; }
public string LeadImage { get; set; }
public string ShortUrl { get; set; }
public virtual ICollection<MusicTrack> MusicTracks { get; set; }
}

public class MusicTrack
{
public int Id { get; set; }
public string Name { get; set; }
public string URL { get; set; }

public int EpisodeId { get; set; }
public Episode Episode { get; set; }
}
}

Now, make sure you compile. I press Ctrl-Shift-B to do this, but you can also do it from the Build Menu.

Right click on Controllers, select Add Controller. Make an EpisodeController. Pick the Entity Framework template (remember you can make your own, if you like. More on this soon!) and click the Data context class dropdown and Make a PodcastContext. Your dialog will look like this.

Add Controller

Compile. Now do the same thing for MusicTrack. Now, check our your Solution Explorer and all your scaffolded code.

Wow, that's a lot of scaffolded code!

Right click on References and select Add Library Reference. You can also do this from the Tools | Library Package Manager menu.

Click on Online on the left side to access NuGet.org, and in the upper right corner, search for "EntityFramework.SqlServerCompact" to bring down support for SQL Server Compact Edition.

Add Library Package Reference (52)

Now, run your app and visit /Episode. Make an episode or three, then visit /MusicTrack.

TDLAdminSite

Homework for you - Extend the Backend Demo!

  • Add the MvcScaffolding Nuget package and rerun the Add Controller commands. What's different?
  • Add an Editor Template for DateTimes with a jQuery DatePicker
  • Add different attributes like [StringLength] or [Range] to your Code First model. Delete the .SDF file in App_Data and re-run. How can you affect your database?
  • Add some other NuGet packages like IE9ify. What cool features can you add like Jump Lists using Javascript?

WebMatrix - This Developer's Life Frontend Administration

Ok, so now we need a frontend for our podcast site. We got one from http://www.templatemonster.com. They can sell you a template and then bring it down directly into Web Matrix. Since you may not want to buy a template just for this demo, you'll want to come up with some basic template for yourself. WebMatrix comes with a Bakery Template and some others, so perhaps try one of those. Perhaps the Bakery Template after clicking Web Site From Template.

We used a template like this, but like I said, I can't give it to you.

TDL Front

Maybe you can start here? ;)

Fourth Coffee - Home - Windows Internet Explorer (54)

You can right click on App_Data and bring in the SQL Database File (Mine was called TDL.sdf, but yours may vary) from the first step with Add Existing File. Some templates include databases. You can use them if you like, or delete them.

Files in Web Matrix

For the demo, I had two database files. The one I created in the first step, and then another one that I already filled out with all our shows earlier.

Lots of data in the database

If you're using the Bakery Template it's a little different from our template since it's about products and includes a featured product, but it's still a cool template.

I skipped some steps in the keynote to make the demo flow, for example, my images were already in an images folder. For this blog post, I'll copy the images from http://www.thisdeveloperslife.com (or you can grab your family photos or whatever) and put them in /images.

Show Images

Next, I'll change the Default.cshtml for my (now) Bakery Template. I'll updated things in the Razor code like Products to Episode, and making sure I'm using column names from the TDL database, and not the Bakery one.

@{
Page.Title = "Home";

var db = Database.Open("TDL");
var shows = db.Query("SELECT * FROM Episodes").ToList();
}

<h1>Welcome to This Developer's Life!</h1>

<ul id="products">
@foreach (var s in shows) {
<li class="product">
<div class="productInfo">
<h3>@s.Title</h3>
<img class="product-image" src="@Href("~/Images/"+ s.LeadImage)" alt="Image of @s.Title" />
<p class="description">@s.Summary</p>
</div>
</li>
}
</ul>

It ends up being not much code. It's not as pretty as the more complex template we used, but you get the idea. You can take templates from anywhere (they don't need to be Razor templates, just HTML!) and then sprinkle in a little Razor code like I did.

I give you, "This Developer's Life - Cheesy Bakery Template Edition":

This Developer's Life Site - Cheesy Bakery Edition

Now if you like, click on Site, then ASP.NET Web Pages Administration (or, just visit /_Admin) and setup your password. I skipped the creating of a password in the keynote and used a site with an existing password we'd setup earlier. Read the instructions carefully.

Bakery6 - Microsoft WebMatrix (57)

The Web Pages Administration site runs local as part of your site, and is how WebMatrix talks to NuGet.org. From here you can get helpers like the Facebook helper, Twitter helper, Disqus helper and more. Some of these helpers, like Disqus, require more setup that I showed in the keynote. For example, you have to visit Disqus.com, sign up for an account and get an API key, then tell your site about it before you use the helper. The Facebook and Twitter helpers also include lots of options, for example, the Twitter helper can be vertical or horizontal, and look different ways. Also check out IE9ify, a jQuery plugin and NuGet package that lets you add JumpLists and IE9 stuff to your site.

ASP.NET Web Pages Administration - Package Manager - Windows Internet Explorer (58)

At the end, I clicked Publish and then just imported the settings file from my ISP. WebMatrix then used WebDeploy to send my site and database to a server. That server was internal to the Mix keynote demo network, but Rob Conery and deployed the site the exact same way at 3am Tues morning. The public site at http://www.thisdeveloperslife.com was written by Rob and I in WebMatrix, uses HTML5, jQuery with SQL CE for a database and is deployed with WebDeploy and sports a tidy HTML5 theme Rob wrote, inspired by the one from the demo.

I'll blog later in a separate post how I made the podcast player with HTML5 audio tags, jQuery and IE9 site pinning.

I hope you enjoy the products Dear Reader as much as we enjoyed building them!

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web

Enabling Dragging of an Image to Pin a Site to the Windows Taskbar in IE9

February 18, '11 Comments [8] Posted in IE9
Sponsored By

My site's custom jumplist including Archives, Videos, Twitter and FacebookI blogged in September about a some features of IE9 that I really dug, specifically adding Jump Lists to your website and Pinning WebSites to the Taskbar.

I made a few small markup changes and now you can pin this blog to your taskbar if you're running Windows 7. I also added right-click Jump Lists to this blog as well.

However, I just noticed that the IE9 Release Candidate that just came out includes a little feature where you can drag an image from a website to pin the site to the taskbar.

Clearly this feature was created as an opportunity for me to enable you, Dear Reader, do drag my giant forehead to the Windows 7 taskbar. No question.

Enabling Dragging of an Image to Pin a Site to the Windows Taskbar in IE9

All I had to do was add:

class="msPinSite"

to the image I wanted to use. You can set other options as well, like the image that's used while dragging (it uses favicon by default) as well as callouts for mouseovers and stuff.

I just did this, as it was simpler:

<img class="msPinSite" src="http://www.hanselman.com/blog/images/tinyheadshot2.jpg" alt="Scott Hanselman" title="Drag this image to your Windows 7 Taskbar to pin this site with IE9 - Scott Hanselman">

Here I am dragging my headshot to the taskbar to pin it. Of course, you can always pin any site by dragging the favicon from the address bar.

Dragging the image down to the Taskbar. 

You can even add little toolbars to taskbar with JavaScript (for sites like Pandora, etc). It's all standard markup and JavaScript and it's setup in such a way that other browsers ignore it as they like.

You can also use JavaScript to push alerts to the icon, maybe for new messages, chat, etc. It's easy to this stuff, check it out there's a whole section on MSDN on Site Pinning. You can also View Source on this demo and figure it out. It took me 5-10 minutes. The hardest part for the Jump List was finding cool icons.

One more very nice browser for my collection of All Non-Released Browsers. Yet.

IE9, FireFox 4, Chrome 11, Opera 11

Enjoy.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Page 1 of 2 in the IE9 category Next Page

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.