Visual Studio Achievements Widget for BlogEngine

If you code in Visual Studio, you've probably heard of Channel 9's Visual Studio plugin that allows developers to earn achievements based on certain criteria met while programming in a visual studio solution.The Visual Studio Achievements plug-in analyzes a background thread each time code is compiled, as well as listens for particular events and actions from Visual Studio. The plugin has a leaderboard on Channel 9's website and there is also a REST API available to query user achievements. I decided to mess around with the API and develop a widget for BlogEngine.net. Now I know there is already a widget that you can easily insert into your theme that does essentially the same thing I created but you don't have the ability to change the data output or design of their widget. I made this pretty quickly and it does need some work. I appreciate any feedback or contributions to the widget.

Visual Studio Achievements Widget for BlogEngine.net
Visual Studio Achievements Widget for BlogEngine.net

 

Download it here: http://dnbegallery.org/cms/List/Widgets/VS-Achievements

JQ Mobile Theme for Blogengine.net

I created a mobile theme for Blogengine.net that uses JQuery Mobile. JQ Mobile overrides a lot of the default html and pages that normal Blogengine themes use and turns a Blogengine.net site into a mobile app.

JQ Mobile - Screenshot1
Home page - List of recent posts with paging

JQ Mobile - Screenshot2
Archive page - Grouped by Category and quick filter search on all posts

JQ Mobile - Screenshot3
Contact page

JQ Mobile - Screenshot4
Search page

 

Download JQ Mobile: here.

Google Accounts Merge - @gtempaccount.com?

I have been using Google Apps Standard(Free) for my domain michaeljbaird.com for over 3 years to take advantage of their email feature. Luckily I've been grandfathered in before Google decided to reduce Google Apps (free) to only 10 users, I used the same email address login for my personal account using Google Products and Google Apps. Today, I went login to my personal account today and got this message:

Google Apps
Google Account merge - An update to your account is required.

 

Moving data to your organization

Google asks what data do you want to transfer. In my mind I was thinking I wanted to do away with my personal account and only us the Google Apps login for everything. Wishful thinking.......

Google Apps
Choose what data you want to merge from Google products.

Google Apps - Select which Google Products to move
Select which Google Products to move.

Google Apps - Not Supported
Products not supported.

 

No Support for Google Profiles in Google Apps

Come to find out Google does not support Profiles in Google Apps. This was a deal breaker since I want to use introduced last Fall to switched between accounts.

BlogEngine.net Featured Posts Rotator Extension using JQuery

I had this need to showcase featured posts on the front page of my blog with a large image. I did not see any extensions for BlogEngine.net that did this, so I decided to write my own. This extension uses JQuery and a JQuery plugin called InnerFade.

Featured Posts Rotator BlogEngine.net Extension
Featured Posts Rotator Extension used by mobiletvworld.com

Admin
The Extension settings are pretty basic. You select if you want to add a CDN reference of the JQuery Framework to the header of your webpages or leave unchecked if you already reference JQuery in you theme. Next, you select a post you want to add an image to and hit upload.

Featured Posts Rotator Extension Admin Screen
Featured Posts Rotator Admin Screen

Theme SiteMaster
In your themes SiteMaster, add the following code in order for the rotator to appear on you blog. Note that if you do not add any images in the admin, the rotator control will not render to the front page.

style.css
Edit the style.css that is located in User controls/FeaturedPostsRotator/style.css to fit the needs of you theme.

The 1.0 version was written very quickly and may contain bugs so please report any. This extension has very basic features but I see the possibilities of adding more features to control settings in the admin in the future! Enjoy!

FeaturedPostsRotator_1.0.zip (14.59 kb)

ASP.net MVC and JQuery Cascading Dropdown list

Imagine that you have an E-Commerce site and you would like the user to drill down into the attributes of a product to help the user find exactly what they need. You display a dropdown list of product colors. Each time a user selects a new color, a dropdown list displaying products available in that color is populated. In this demo, I've created a small application demonstrating on how to use ASP.net MVC 1.0 framework and JQuery to complete the task.

ASP_net-MVC-and-JQuery-Dropdown-Cascading
ASP.net MVC and JQuery Cascading Dropdown list

Data Models

First, for demonstration purposes and easy download, I created two Model Data sources without the use of SQL. Colors and Products:

Models/Colors.cs

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace JQueryJsonSelectDemo.Models
{
  public class Color
  {
    public string ColorName { get; set; }
    public string ColorCode { get; set; }
    public int ColorId { get; set; }

    public static IQueryable<Color> GetColorDataList()
    {
      return new List<Color>()   
      {  
         new Color { ColorName = "Blue", ColorCode = "BL", ColorId = 1},  
         new Color { ColorName = "Red", ColorCode = "RD", ColorId = 2},  
         new Color { ColorName = "Grey", ColorCode = "GY", ColorId = 3},  
         new Color { ColorName = "Black", ColorCode = "BK", ColorId = 4},  
         new Color { ColorName = "Green", ColorCode = "GN", ColorId = 5},  
         new Color { ColorName = "Olive", ColorCode = "OL", ColorId = 6},  
         new Color { ColorName = "Orange", ColorCode = "O", ColorId = 7},  
         new Color { ColorName = "Pink", ColorCode = "PK", ColorId = 8},  
         new Color { ColorName = "Violet", ColorCode = "V", ColorId = 9},  
         new Color { ColorName = "Yellow", ColorCode = "YW", ColorId = 10}  
      }
      .AsQueryable<Color>();
    }
  }
}

 

Models/Product.cs

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace JQueryJsonSelectDemo.Models
{
  public class Product
  {
    public string ProductName { get; set; }
    public int ColorId { get; set; }
    public int ProductId { get; set; }

    public static IQueryable<Product> GetProductDataList()
    {
      return new List<Product>()   
      {  
         new Product { ProductName = "Cup", ColorId = 2, ProductId = 1},  
         new Product { ProductName = "MP3 Player", ColorId = 4, ProductId = 2},  
         new Product { ProductName = "52\" LCD TV", ColorId = 5, ProductId = 3},  
         new Product { ProductName = "Fork", ColorId = 6, ProductId = 4},  
         new Product { ProductName = "Spoon", ColorId = 10, ProductId = 5},  
         new Product { ProductName = "Shirt", ColorId = 6, ProductId = 6},  
         new Product { ProductName = "Pant", ColorId = 4, ProductId = 7},  
         new Product { ProductName = "Shoes", ColorId = 2, ProductId = 8},  
         new Product { ProductName = "Sun Glasses", ColorId = 1, ProductId = 9},  
         new Product { ProductName = "Pen", ColorId = 2, ProductId = 10}  
      }
      .AsQueryable<Product>();
    }
  }
}

 

The Controller

Next, I created a class (IndexFormViewModel) to pass the Colors as a SelectList Collection to the strongly-typed view. And also create an Action FindProductsByColorID that returns a JsonResult that will be used by the JQuery code in the view to populate the cascading dropdown list.

Controllers/HomeController.cs

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using JQueryJsonSelectDemo.Models;

namespace JQueryJsonSelectDemo.Controllers
{

  public class IndexFormViewModel
  {

    // Properties
    public SelectList Colors { get; private set; }

    // Constructor
    public IndexFormViewModel()
    {
      var colors = from c in Color.GetColorDataList()
                   select c;
      Colors = new SelectList(colors, "ColorId", "ColorName");
    }
  }

  [HandleError]
  public class HomeController : Controller
  {
    public ActionResult Index()
    {
      ViewData["Message"] = "ASP.net MVC JQuery Cascading Select Demo!";
      return View(new IndexFormViewModel());
    }

    public ActionResult About()
    {
      return View();
    }

    public JsonResult FindProductsByColorID(int colorid)
    {
      // Simulate Loading Data "wait" 
      System.Threading.Thread.Sleep(1500);

      // return Json result using LINQ to SQL
      return new JsonResult
      {
        Data = (from p in Product.GetProductDataList()
                where p.ColorId == colorid
                select p).ToArray<Product>()
      };
    }
  }
}

 

Routing for the Ajax to call.

I create a route that I can call using the JQuery Ajax code.

Global.asax

 

      routes.MapRoute(
          "FindProducts",
          "FindProducts/{colorid}",
          new { controller = "Home", action = "FindProductsByColorID", colorid = "" }
      );

 

The View

Finally, The view which contains the JQuery code to make an Ajax request to my Home Controller Action (FindProductsByColorID) which returns a Json Result. If data is returned from the Action, the Products dropdown will be removed from being disabled and the options will be populated by the array from the JsonResult.

Views/Home/Index.aspx

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<JQueryJsonSelectDemo.Controllers.IndexFormViewModel>" %>
<%@ Import Namespace="JQueryJsonSelectDemo.Models" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">Home Page</asp:Content>
<asp:Content ID="Head" ContentPlaceHolderID="HeadContent" runat="server">
<script type="text/javascript">
  $(function() {
    $("select#Colors").change(function() {
      var color = $("#Colors > option:selected").attr("value");

      $.ajax({
        type: "GET",
        contentType: "application/json; charset=utf-8",
        url: "FindProducts/" + color,
        data: "{}",
        dataType: "json",
        success: function(data) {
          $('#ProductsDiv > div').remove(); // remove any existing Products
          if (data.length > 0) {
            var options = '';
            for (p in data) {
              var product = data[p];
              options += "<option value='" + product.ProductId + "'>" + product.ProductName + "</option>";
            }
            $("#Products").removeAttr('disabled').html(options);

          } else {
            $("#Products").attr('disabled', true).html('');
            $("#ProductsDiv").append('<div>(None Found)</div>');
          }
        }
      });
    });
  });
</script>

</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
  <h2><%= Html.Encode(ViewData["Message"]) %></h2>
  
  <p>
    <label class="formlabel" for="Colors">Colors:</label>
    <%=Html.DropDownList("Colors", Model.Colors)%>
  </p>
  <p>
    <div id="ProductsDiv"></div>
  </p>
  <p>
    <label class="formlabel" for="Products">Products:</label>
    <select id="Products" disabled></select>
  </p>
</asp:Content>