Using Plunker With LESS

According to this update, it’s now possible to use compiled languages like LESS with plunker

According to the Client Side Usage from the Less Documentation, you should do the following:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet/less" type="text/css" href="style.less">
    <script src="//cdnjs.cloudflare.com/ajax/libs/less.js/1.7.3/less.min.js"></script>
  </head>
  <body>
  </body>
</html>

styles.less:

Here’s a super simple example of a less file that will chane the background color bright red

@background-color: red;
body { background: @background-color; }

Here’s an example in plunker

If it’s not showing up for whatever reason, then you probably have a compile error in your less, which will cause the entire sheet to not be delivered. You can check by copying and pasting your code into a online LESS compiler and seeing if it spits out any errors.

Adding a Desktop Mobile Toggle Button

The goal of a Bootstrap site is to deliver a mobile view that is so easily navigable that it never leaves the user yearning for a tiny shrunk down desktop experience on their phone. Still, despite a developers best intentions, some users just want what they want. And we should give it to them. We’re not designing sites so that we may enforce our will on others, but to provide content that users find easy to view, and some users have different preferences than others.

Luckily, we can easily provide both worlds, and default to a responsive view with the hopes that they will find it so convincing they’ll never need the desktop view.

Here’s a little snippet of code that I like to put on websites. You can see it in action on: http://kylemitofsky.com/

Add two toggles to your page.

<!-- Desktop / Mobile Footer -->
<div id="DesktopMobileFooter" class='h_center'>
    <hr/>
    <div class="MobileToggle">
        View <a id="DesktopSite" href="#" >Desktop</a> | <strong>Mobile</strong> Site
    </div>
    <div class="MobileToggle" style="display:none;">
        View <strong>Desktop</strong> | <a id="MobileSite" href="#" >Mobile</a> Site
    </div>
</div>

Then add the following JavaScript:

$(".MobileToggle a").click(function () {
    var viewport = ($(this).attr('id') === "MobileSite") ?
                    'width=device-width, initial-scale=1.0' :
                    'width=1200';
    $("meta[name=viewport]").attr('content', viewport);
    $(".MobileToggle").toggle();
    return false;
});

How To Deselect A Radio Button

Sometimes radio buttons can be quite frustrating as a user when you need to deselect having answered a question.

Here’s a quick way to temporarily allow a page to deselect radio buttons by pressing Ctrl + Click

  1. Navigate to any page that has radiobuttons. Here’s an example of one:
  2. Click F12 to open up the developer tools
  3. Navigate to the Console Pane
  4. Copy and paste in the following code into the editor:

    document.addEventListener('click', function(e){
     if (e.ctrlKey == true && 
         e.target.tagName == 'INPUT' && 
         e.target.type == "radio" && 
         e.target.checked == true) {
         e.target.checked = false;
     }
    });
  5. Click Run Script (or hit Enter)
  6. Now, to deselect a radio button just go back to the page and hold down Ctrl and click with your mouse.

Instructions

This screenshot should match your current browser, but if it doesn’t - here’s an album of screenshots for different browsers

Note: Of course, by the time you’re opening up the developer tools, you can just edit the HTML directly, but this is a little more reusable.

Pulling Your Website Up By Your Twitter Bootstraps

Hello Boston Code Camp!

Here are some resources to supplement my talk on Bootstrap 3 talk titled:
Pulling Your Website Up By Your Twitter Bootstraps

Here are some powerpoint slides:


Here is a working version of the website from the presentation:
http://kylemitofsky.com/BootstrapPresentation/

The entire code sample was published to GitHub here:
https://github.com/KyleMit/BootstrapPresentation

You can get Bootstrap here (and also read their great documentation):
http://getbootstrap.com/

You can style Bootstrap here:
http://bootswatch.com/

I’m really excited that every step of the demo can is actually a commit into the GitHub repository. I wrote an article about using using revision control to demo live coding changes, but here’s the meat of it. If you fork the repository on github and open it up it powershell, then you can step through every commit with these commands:

git config --local alias.child-sha "!git rev-list HEAD..master | tail -n 1"
git config --local alias.initial-commit "!git rev-list --all | tail -n 1"

git checkout master
git checkout $(git initial-commit)
git checkout $(git child-sha)

How to Pivot a DataTable in .NET

So I would have thought this problem would have already been solved by the Internets at large. As it turns out, I couldn’t find a very simple method to solve this relatively simple task. So here’s my attempt

Here’s a dead simple pivot table.

Let’s say I have a table that looks like this:

Person Age Sport
Susan 22 Tennis
Bob 29 Soccer
Terry 16 Basketball

And I want to pivot it to to look like this:

Person Susan Bob Terry
Age 22 29 16
Sport Tennis Soccer Basketball

Here’s How

Private Function PivotTable(oldTable As DataTable, 
                            Optional pivotColumnOrdinal As Integer = 0
                           ) As DataTable
    Dim newTable As New DataTable
    Dim dr As DataRow

    ' add pivot column name
    newTable.Columns.Add(oldTable.Columns(pivotColumnOrdinal).ColumnName)

    ' add pivot column values in each row as column headers to new Table
    For Each row In oldTable.Rows
        newTable.Columns.Add(row(pivotColumnOrdinal))
    Next

    ' loop through columns
    For col = 0 To oldTable.Columns.Count - 1
        'pivot column doen't get it's own row (it is already a header)
        If col = pivotColumnOrdinal Then Continue For

        ' each column becomes a new row
        dr = newTable.NewRow()

        ' add the Column Name in the first Column
        dr(0) = oldTable.Columns(col).ColumnName

        ' add data from every row to the pivoted row
        For row = 0 To oldTable.Rows.Count - 1
            dr(row + 1) = oldTable.Rows(row)(col)
        Next

        'add the DataRow to the new table
        newTable.Rows.Add(dr)
    Next

    Return newTable
End Function

Then just call like this:

Dim newTable = PivotTable(oldTable, 0)

And that’s that.

Stepping through a Code Demo

One challenge to delivering coding presentations is the trade-off between:

  • Showing actual real code that developers can get their head around
  •       VS
  • The time it costs to actually write it in front of them (debugging missing commas included).

Here are some of the ways I’ve seen to side step this issue in previous coding presentations I’ve attended:

  • Start with the full app. Study relevant sections.
  • Start with the full app, but mostly commented out. Uncomment section by section.
  • Start with a blank app and a notepad document with all the code you’ll eventually want. Copy and paste code section by section.
  • Start with the full app and use Unit Tests to step into relevant code.

Here is one more that I will be trying out:

  • Utilize revision control software to have each state of the code base represented by a different commit. Then step through the commits.

If executed well, I really like this last one. It avoids having too much information. Especially if content is new, it can disrupt the noise to signal ratio if attendees are thrown into a world with too much code. It also helps reduce copy and paste errors that might occur and the overall time it takes to update the code base. The beautiful thing is that each state of the code base has a known success. There is never the possibility that you have forgotten to uncomment that one critical line.

You can easily step back through the entire code base to rehearse. What’s more - so can participants when they get home. When have you ever left a coding presentation having been able to re-create every single step performed by the presenter?

Stepping Through Commits

Since this option definitely has the highest startup cost, I’ll detail some of the items along my learning curve.

I’ll preface this by saying that I’m using GitHub as my RCS of choice.

Also, I’ve never stepped through each revision in an entire codebase before!

It’s not something that is covered by most of the use cases for revision control. Of course, it’s a perfectly acceptable use, just not one that you’re likely to need when developing software.

The easiest way to change your working copy to a specific version is to use:

git checkout <revision>

Where <revision> is anything that identifies a revision

  • We can do this with the SHA of any particular commit.
  • Or we can step back through previous commits by using HEAD~n where n is the number of commits we want to step back

The problem is what we want to do is step forward through revisions. While the ~1 selects the parent of the current revision, there is no native function to select its child.

Note: This is partly because of the way that a Directed Acyclic Graph (DAG) works. Each commit knows who it’s parent is, but not which children might be attached to it.
Git History
For example, [B] knows it was branched off [A], but does not know who it’s child is (in fact has two children!)

Part of this complexity can be avoided as I’m looking to have a relatively straight forward linear revision history.

Child Selector

From the answer to what is the opposite of git diff HEAD~1?:

You can checkout the next branch like this:

git checkout $(git rev-list HEAD..master | tail -n 1)
In case you’re new to Git/Shell, let’s break this down a little.

The inner expression git rev-list will show a list of revisions. By specifying any two revision id’s joined by two periods, we’ll get a list of all the SHAs in between them.

So, for the following revision history:

     HEAD
      ↓
 A -- B -- C -- D -- E (master)

The command:

git rev-list HEAD..master

Will Return (with the most recent first):

E
D
C

Then by using the pipe operator in powershell, we can grab the last value by piping in | tail -n 1

So this command:

git rev-list HEAD..master | tail -n 1

Will just return the commit we want:

C

In order to make this into a one liner, we’ll need to wrap the query so we can pass the output into our checkout command. We can use the $( ) SubExpression operator to return a vector value, giving us the original equation.

Adding an Alias

If we’re using this a lot, it might look prettier to alias the query.
We can add a new command called child-sha to our local config file like this:

git config --local alias.child-sha "!git rev-list HEAD..master | tail -n 1"

Note: The exclamation point is important! Without it, git will only execute git specific commands. Adding it allows git to use powershell commands as well like | tail -n 1

Then we can checkout the next commit like this:

git checkout $(git child-sha)

Other Considerations

You’ll be seeing a lot of this dialog:
Reload Warning

To avoid this, go to:
Tools > Options > Environment > Documents > Detect when a file is changed
And make sure Auto-load changes is checked:
Auto Load Changes

Conclusion:

That’s about it. I’ll add my presentation here when it’s finished so you can see a little more concrete of an example.
Let me know if you give it a shot and have any experiences (good or bad).

Remove Items in For Loop

As a general rule, you should not modify a collection that your are looping over, only the items inside of that collection. The problem with removing items inside of a for loop is that it changes the collection that is being looped which will interfere with the list count in an indexed for loop and the iterator location in a for each loop.

Two common solutions are to:

  1. Create a new collection so you can modify one collection and loop over another.
  2. Loop backwards through the collection so changes to the iterator won’t impact the execution.

In this article, we’ll create two extension methods that utilize each of these solutions.

Create New Collection:

By calling ToList on the original collection, you create a brand new collection. Then, you can loop over the new list to find items that need to be removed from the original. Whenever you find an object that matches your removal criteria, you can safely remove it from the original collection because it is not currently being enumerated over.

I think it looks pretty spiffy too:

<Extension()>
Public Sub RemoveEachObject(Of T)(ByVal col As Collection(Of T), 
                                  ByVal match As Func(Of T, Boolean))
    For Each o As T In col.ToList()
        If match(o) Then col.Remove(o)
    Next
End Sub

Loop Backwards:

The previous solution works well, but a more efficient solution would be to loop backwards. For starters, the previous answer will have to create a copy of the entire collection. More importantly, when removing items, the Remove() method will have to loop through entire collection and check each item for reference equality with the passed in value. This can be quite expensive. It would be much easier to keep track of the current index in the collection and remove whatever item happened to be occupying it.

To do this, we’ll loop backwards and check the validity of each item in the collection based on the passed in lambda function. If it matches, then we’ll remove the current index.

<Extension()>
Public Sub RemoveEach(Of T)(ByVal col As Collection(Of T),
                            ByVal match As Func(Of T, Boolean))
    For i = col.Count - 1 To 0 Step -1
        If match(col(i)) Then col.RemoveAt(i)
    Next
End Sub

Usage

Then we can use either method like this:

Dim col As New Collection(Of Integer) From {1, 2, 3, 4}
col.RemoveEach(Function(i) (i Mod 2) = 0)
Console.WriteLine(String.Join(",", col))
'Produces: 1,3

This code has been written to extend Collection(Of T). You could just as easily extend List(Of T) as well, but the list class already exposes the method RemoveAll which already does this same thing.

For more info, check out this great answer to Remove from a List within a ‘foreach’ loop.

Using Shared Properties in ASP.NET and WinForms

A good business library should be able to drive behavior on any number of devices, exposing a application programming interface that is agnostic of its implementation.

However, we recently had a problem when we wanted to re-use a business library that was designed for a Windows Forms application for use in an ASP.NET web application. The problem was that our original application used shared properties to manage the state of the application.

Note: it seems prudent to avoid global variables, but this was where we found ourselves.

Why was this a problem? The original design meant that each instance of the application was owned by a single user under a single process. However, in ASP.NET, all users share a single process hosted by the ASP.NET runtime. Since shared variables are unique to the process they live on, variables that managed state for a single user (i.e. ActiveClient) would now be shared, overwritten, and cleared all at once by every single user within the web application.

Without massive re-writing of the business and application logic, we needed a way to give windows app users their own global variables as well as giving web app users a way to access their own instance of the shared properties.

Here’s how we did it:

First, consider what a normal shared property would look like in VB.NET:

Private Shared _activeClient As Client
Public Shared Property ActiveClient() As Client
    Get
        Return _activeClient
    End Get
    Set(ByVal value As Client)
        _activeClient = Value
    End Set
End Property

Note: For this example, I have a class named Client but this could be any variable that I wanted to share access to across the entire application for a single user.

It’s important to breakdown all the things that a property does here. The property doesn’t actually hold the value across all instances; the private shared field does. The property just provides global accessors and setters to retrieve and set the value.

ASP.NET Session Variables

In ASP.NET, we can store values unique to each user inside of the Session Variable. To figure out how to integrate this with the first case, let’s consider what a typical session variable looks like:

'setter
Session("ActiveClient") = new Client()
'getter
Dim myClient = DirectCast(Session("ActiveClient"), Client)

This works well enough, but it’s a little messy. We have to manually perform casting ourselves and also keep track of all the key strings across the entire application.

Here’s one way to improve this (and other projects) by adding strong typing to the ASP.NET session variable:

Public Shared Property ActiveClient() As Client
    Get
        If HttpContext.Current.Session("ActiveClient") Is Nothing Then
            HttpContext.Current.Session("ActiveClient") = New Client
        End If
        Return DirectCast(HttpContext.Current.Session("ActiveClient"), Client)
    End Get
    Set(value As Client)
        HttpContext.Current.Session("ActiveClient") = value
    End Set
End Property

We still have global accessors and setters provided by the shared property, but inside of the Get and Set operations we’re using the session variable to store the value for each individual user. Note that we’re using the static HttpContext.Current Property so the code doesn’t not have to live on a page with it’s own HttpContext.

Merging Both Properties

We now have a property in a windows application that stores a value unique to each user / process and a property in a web application that stores a value unique to each user / session. All that is left to do is to merge the properties accordingly.

The first step in doing so is to determine whether or not the assembly is currently executing as a web or windows application. We can do so by checking if the HttpContext Current property exists:

Dim isWebDeployed as Boolean = System.Web.HttpContext.Current IsNot Nothing

Using that information, we can just expand the logic in our getters and setters to first check the execution environment and then grab the appropriate value:

Private Shared _activeClient As New Client
Public Shared Property ActiveClient() As Client
    Get
        'check if deployed as web application
        If System.Web.HttpContext.Current IsNot Nothing Then
            'if we've never loaded, create new instance just for session
            If System.Web.HttpContext.Current.Session("ActiveClient") Is Nothing Then
                System.Web.HttpContext.Current.Session("ActiveClient") = New Client
            End If
            Return DirectCast(System.Web.HttpContext.Current.Session("ActiveClient"), Client)
        Else
            'application is windows application
            Return _activeClient
        End If
    End Get
    Set(ByVal value As Client)
        'check if deployed as web application
        If System.Web.HttpContext.Current IsNot Nothing Then
            System.Web.HttpContext.Current.Session("ActiveClient") = Value
        Else
            _activeClient = Value
        End If
    End Set
End Property

Extended Solution

Based off the number of instances you’re dealing with, the previous solution might work just fine. However, if you need to repeat this across multiple shared properties, you might want something a little more reusable.

Here’s a generic getter method that takes in the shared private field for a windows application and the key string for a web application and returns the appropriate value:

Public Shared Function GetPropertyBasedOnEnvironment(Of T)(ByRef sharedMember As T, ByVal propName As String) As T
    'check if deployed as web application
    If HttpContext.Current IsNot Nothing Then
        'application is web application
        Return TryCast(HttpContext.Current.Session(propName), T)
    Else
        'application is windows application
        Return sharedMember
    End If
End Function

Conversely, here’s generic setter method that can access the old value and assign it a new value depending on the current environment:

Public Shared Sub SetPropertyBasedOnEnvironment(Of T)(ByRef sharedMember As T, ByVal propName As String, newValue As T)
    'check if deployed as web application
    If HttpContext.Current IsNot Nothing Then
        'application is web application
        HttpContext.Current.Session(propName) = newValue
    Else
        'application is windows application
        sharedMember = newValue
    End If
End Sub

With those two methods accessible, we can now simplify our shared property using the following code:

Private Shared _activeClient As New Client
Public Shared Property ActiveClient() As Client
    Get
        Return GetPropertyBasedOnEnvironment(_activeClient, "ActiveClient")
    End Get
    Set(value As Client)
        SetPropertyBasedOnEnvironment(_activeClient, "ActiveClient", value)
    End Set
End Property

Bonus: if you’re using .NET 4.5 or above, you can further simplify the custom getter and setter methods by using CallerMemberNameAttribute to have the compiler pass the key string for you, like this:

Public Shared Function GetPropertyBasedOnEnvironment(Of T)(
                  ByRef sharedMember As T, 
                  <CallerMemberName> Optional propName As String = Nothing) As T
    'check if deployed as web application
    If HttpContext.Current IsNot Nothing Then
        Return DirectCast(HttpContext.Current.Session(propName), T)
    Else
        Return sharedMember
    End If
End Function

Again, there might be more elegant architectural solutions, but this helped resolve the issue we were having based on the situation we had coded ourselves into.

Bootstrap Navbar Active Class with MVC

The ASP.NET MVC project template comes with Bootstrap scaffolding by default. And Bootstrap comes with default styling for active navbar links. So you might find it a little odd that the ASP.NET bootstrap template does not style the active menu item by default.

It can, it just seems as if this functionality wasn’t included out of the box:

styled navabar

If you plan on utilizing the bootstrap’s powerful navigational layout, you should definitely add styling for the current page. It helps users keep track of where they are within the application and assists with navigation.

To do so, we can add the active class dynamically on the shared layout by checking the current routing data. Here’s how:

Markup

When you create a new ASP.NET Web Application using MVC, the project should already contain some default pages and navigational links in the navbar. The navbar is defined as part of the shared layout in the Views folder. Your Solution Explorer should look like this:

solution explorer

In the _layout.vbhtml file, you should find the following markup:

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li>@Html.ActionLink("Home", "Index", "Home")</li>
        <li>@Html.ActionLink("About", "About", "Home")</li>
        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
    </ul>
</div>

In order to highlight the current tab in the Bootstrap Navbar, the <li> element needs to be given the class named active. As an example, just try hard coding it in on any one of the current links:

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li class="active">@Html.ActionLink("Home", "Index", "Home")</li>
        <li>@Html.ActionLink("About", "About", "Home")</li>
        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
    </ul>
</div>

This should look like the screenshot from above. But what we’d really like to do, is generate the active class dynamically for each li depending on the current page. We’ll insert the string active with an extension method called IsActive that will take in parameters for the Controller and Route.

We can use our extension method to insert the active class on the appropriate action link like this:

<div class="navbar-collapse collapse">
    <ul class="nav navbar-nav">
        <li class='@Html.IsActive("Home", "Index")'>
            @Html.ActionLink("Home", "Index", "Home")
        </li>
        <li class='@Html.IsActive("Home", "About")'>
            @Html.ActionLink("About", "About", "Home")
        </li>
        <li class='@Html.IsActive("Home", "Contact")'>
            @Html.ActionLink("Contact", "Contact", "Home")
        </li>
    </ul>
</div>

Extension Method

If you don’t already have one, create a folder in your project named Utilities and add a static class (or Module in VB) named Utilities or Extensions.

Then, we’ll add an extension method called IsActive ontop of the HtmlHelper class. We’ll use this to return the active class if the passed in controller text and action text match the current route.

To programmatically determine the current controller and action, we’ll use the ViewContext property on our HtmlHelper object. The ViewContext exposes, among other things, a property containing the RouteData which contains a collection of URL parameter values and default values for the route in its Values property.

The whole thing should look like this:

public static class Utilities
{
    public static string IsActive(this HtmlHelper html, 
                                  string control,
                                  string action)
    {
        var routeData = html.ViewContext.RouteData;

        var routeAction = (string)routeData.Values["action"];
        var routeControl = (string)routeData.Values["controller"];

        // both must match
        var returnActive = control == routeControl &&
                           action == routeAction;

        return returnActive ? "active" : "";
    }
}

Finally, in order for your view to access this method, you’ll have to make sure you import the namespace into your view using the razor syntax like this:

@using YourProjectName.Utilities

Run your project and the current page should be highlighted!

Closing Remarks

You’ll notice that the login pages do not highlight when you navigate to the default account pages provided. See if you can use the info here to modify the _loginPartial page in the Shared Layout section. If you get stuck, you can look at the full demo below.

Chris Way has a great blog post on Setting the active link in a Twitter Bootstrap Navbar in ASP.NET MVC. He comes up with a single method to generate the <li> element and the <a> element nested inside of it since there is largely redundant routing info. I’ve opted away from that for maximal flexibility as it locks you into a single method for producing links, but it does provide a terser inline syntax if that’s all you need to do.

Also, a lot of the basis for this code was taken from the StackOverflow question How to add active class to Html.ActionLink in ASP.NET MVC

Source Code:

You can view the full working solution on GitHub in both VB and C#

https://github.com/KyleMit/CodingEverything/tree/master/MVCBootstrapNavbar


Permalink to article - Published with markdown via stackedit.io

Bootstrap Docs Sidebar Explained

Do you really want to make a side navbar look just like the one from the Bootstrap Documentation pages? Then this is the article for you.

In addition to really liking the bootstrap library, I have to say that I really enjoy the presentational style of their documentation page. I think it’s a great idea to show off the big picture of a document, while automatically expanding each section when appropriate. It’s especially helpful for long documents that require a lot of scrolling. Unfortunately, they don’t specifically outline how their documentation pages are put together. But since they’re just delivering HTML/CSS/JS, we can reverse engineer how they put it together. Here are the results of dissecting Bootstrap’s Doc’s side nav bar.

Simple Content

This really works best with some content to scroll through, so let’ just start by making a bunch of blocks with unique ID tags, that are nested into sections, that we can visually see.

Here’s how:
Create a few blocks that look like this. Copy and paste it, but every time you see the letter A, replace it with B, C, and so on.

<section id="GroupA" class="group">
    <h3>Group A</h3>
    <div id="GroupASub1" class="subgroup">
        <h4>Group A Sub 1</h4>
    </div>
    <div id="GroupASub2" class="subgroup">
        <h4>Group A Sub 2</h4>
    </div>
</section>

Then style the blocks to give them a little bit of spacing. This is just so we don’t have to wade through hundreds of lines of lorem ipsum (yuk!).

.group {
    background: yellow;
    width: 200px;
    height: 500px;
}
.group .subgroup {
    background: orange;
    width: 150px;
    height: 200px;
}

Simple Layout

Now we need to create a two column layout for our page. We can put the sample body content on the right and the navbar on the left. We can do this with the Bootstrap Grid System, by placing both columns inside of a div with class='row' and specifying the column widths for all devices with col-xs-*. Finally when we scroll down, we want the content to freely scroll, but have the navigation bar remain in the same place, so we’ll use position: fixed to pin it to the top. It should look something like this:

<div class="row">
    <!--Nav Bar -->
    <nav class="col-xs-3">
        <div class="fixed">
            Nav Placeholder<br/>
            Stays on Top!
        </div>
    </nav>
    <!--Main Content -->
    <div class="col-xs-9">
        <section id="GroupA" class="group"></section>
        <section id="GroupB" class="group"></section>
        <section id="GroupC" class="group"></section>
    </div>
</div>

Simple Navlist

Before we even add any bootstrap, we need a bare bones list of links that will navigate to content on the page. This provides a nice tree structure, but no formatting. The links have bulky bullets in front of them and are very brightly colored.

<ul id="sidebar">
    <li>
        <a href="#GroupA">Group A</a>
        <ul>
            <li><a href="#GroupASub1">Sub-Group 1</a></li>
            <li><a href="#GroupASub2">Sub-Group 2</a></li>
        </ul>
    </li>
    <!-- Same for Group B & C -->
</ul>

Converting List to Nav

In order to make the links look more like navigation controls, and less like a list of groceries, we can use the set of Nav classes provided by Bootstrap. In order to use any nav class, you must also attach the .nav base class to that element as well. To make sure the list stays vertical, we want to also add the class .nav-stacked to each ul element.

<ul class="nav nav-stacked fixed" id="sidebar">
    <li>
        <a href="#GroupA">Group A</a>
        <ul class="nav nav-stacked" >
            <li><a href="#GroupASub1">Sub-Group 1</a></li>
            <li><a href="#GroupASub2">Sub-Group 2</a></li>
        </ul>
    </li>
    <!-- Same for Group B & C -->
</ul>

Let’s pause to look at just these changes because a lot has changed visually even though we haven’t added much code. The set of nav classes help strip out some of the default formatting associated with unordered lists and instead renders the links much like menu bars. The elements now all align all the way on the left because .nav sets padding-left: 0;. We’ve removed the underline with text-decoration: none;, removed some of the list formatting with list-style: none;, and softened the colors a bit with color: #428bca;. The nav-stacked floats all the elements to the left so they ‘stack’ on top of each other.

Formatting the Nav Bar

The final change to the markup is just to add the class bs-docs-sidebar to the top nav column div to help identify it in CSS. We can do the rest in CSS and JavaScript.
First, let’s give the navbar a little breathing room by giving it margins on the top, left, and bottom:

/* sidebar */
.bs-docs-sidebar {
    padding-left: 20px;
    margin-top: 20px;
    margin-bottom: 20px;
}

Next, we’d like to be able to apply different formating to parent level links and child links. CSS does not currently have a Parent Selector which could be used to differentiate the top level links with those nested below them. Instead, we can apply a style to all links inside of bs-docs-sidebar and then override that style for any list items that are children of two ul.nav elements.

/* all links */
.bs-docs-sidebar .nav>li>a {
    color: #999;
    padding: 4px 20px;
    font-size: 13px;
    font-weight: 400;
}

/* nested links */
.bs-docs-sidebar .nav .nav>li>a {
    padding-top: 1px;
    padding-bottom: 1px;
    padding-left: 30px;
    font-size: 12px;
}

For all links we’ll apply a grey color schema and a font-weight of 400. All links will be padded in at least 20 pixels, but those nested under two .nav elements will be indented 30px. Top level links will be slightly larger at 13px. And nested links will have much less padding on the top and bottom.

Using Scrollspy

To do the rest of the styling we’ll need to know whether a link is active. In order to do this, we can use a scroll spy on the page which will apply the .active class to the navigation list whenever a given element is scrolled into view.
Scroll spy is called on the element whose scrolling activity you want to monitor. Since you will probably be scrolling through the entire page, this should go on the body element.
The target of scrollspy is:

the ID or class of the parent element of any Bootstrap .nav component.

So we’ll target the #sidebar by passing in it’s parent: .bs-docs-sidebar

The offset represents the pixels to offset from top when calculating position of scroll. We’ll give it a running start of 40, so it can find the first nested child item of each group so that will be set as active as well.

$('body').scrollspy({
    target: '.bs-docs-sidebar',
    offset: 40
});

You are still in charge of styling any elements you would like to display. Scroll spy merely adds the active class. As of right now, it won’t look like it’s doing anything because we haven’t styled the elements yet. As a placeholder, just to see it working, let’s color active links purple. We’ll replace this with more sophisticated stuff next.

.bs-docs-sidebar .nav>.active>a {  color: #563d7c; }

Whenever an element is set to active (due to scrollspy) or is hovered or focused, we’ll apply some styles to the anchor. We’ll color it purple. We’ll make sure that it doesn’t have an underline or a grey box highlighting it. And we’ll add a purple flag on the left to help identify which items are active. To do this, we’ll apply a 2 pixel border to the left of the element.

Note: Because of the way the CSS box model works, when we add a 2px border to the left, the entire element shifts 2 pixels to the right, displaced by the border that previously took up zero pixels. One way to handle this is to shorten the padding we added by 2px every time the element is active. But I think a cooler trick is to just start off with a transparent 2px border so the object does not get resized when adding a colorful border

/* all links */
.bs-docs-sidebar .nav>li>a {
    /*add trasnparent border */
    border-left: 2px solid transparent;
}
/* active & hover links */
.bs-docs-sidebar .nav>.active>a, 
.bs-docs-sidebar .nav>li>a:hover, 
.bs-docs-sidebar .nav>li>a:focus {
    color: #563d7c;                 
    text-decoration: none;          
    background-color: transparent;  
    border-left: 2px solid #563d7c; 
}

Let’s also make active parent links have a very thick weight, and child links less so.
Remember: we’ll use the style we want for parent objects on all the links and then override it for nested links.

/* all active links */
.bs-docs-sidebar .nav>.active>a, 
.bs-docs-sidebar .nav>.active:hover>a,
.bs-docs-sidebar .nav>.active:focus>a {
    font-weight: 700;
}
/* nested active links */
.bs-docs-sidebar .nav .nav>.active>a, 
.bs-docs-sidebar .nav .nav>.active:hover>a,
.bs-docs-sidebar .nav .nav>.active:focus>a {
    font-weight: 500;
}

Collapsing Inactive SubGroups

One of my favorite features of the Bootstrap Navbar is that it automatically collapses subgroups that are not currently in view. This allows a lot of information to be available, but prevents a lot of noise when it’s not in use. To do this we’ll use the active flag on the parent group. To hide all subgroups, we’ll set display:none to all ul.nav elements that are children of other .nav elements. This will collapse all subgroups. Then we need to expand the active group by looking for a parent level nav with an .active child and set display:block on it’s child ul. So it will look like this:

/* hide all (inactive) nested list */
.bs-docs-sidebar .nav ul.nav {
    display: none;           
}
/* show active nested list */
.bs-docs-sidebar .nav>.active>ul.nav {
    display: block;           
}

And behave like this:

Wrap Up

So that’s it. You can have fun applying other styles as well. Bootstrap uses Affix to lock the navbar into place after scrolling past the header.
Also, they use media queries to collapse the navbar if the screen is below a certain size like this:

@media screen and (max-width: 500px){
    .bs-docs-sidebar {
        display:none
    }
}

The impetus for this article was actually a spice website that I was making to catalog my home spices. It uses the bootstrap side bar when space allows, but then converts into a top navbar for smaller screens. You can view the final page here:

http://kylemitofsky.com/Spices/

And you you can browse the source code here if you’re interested in how anything is done:

https://github.com/KyleMit/Spices/tree/gh-pages

Here’s the final fiddle. Feel free to play around with it, fork it, or leave me a comment below.

Update with Top NavBar:

Here’s a quick rundown of how to add a horizontal navbar to the example. The primary difficulty in adding any fixed position navbar to the top of the window is it will break all your anchor tags like so:

The first trick when adding a navbar is to displace everything on the page by the same number of pixels, that way nothing starts off hidden underneath the navbar. The standard implementation (even listed in the docs) is to just offset the entire document by placing a top margin or padding on the body element:

body { margin-top:50px; }

But as you can see from the previous example, this doesn’t solve the issue.

Why is that?

For more information, you can see my Stack Overflow answer to the question When navigating to #id, element is hidden under fixed position header, but here’s the gist of it. When the browser is told to navigate to a fragment identifier (#ID):

your browser always wants to scroll your anchor to the exact top of the window. If you set your anchor where your text actually begins, it will be occluded by your menu bar.

One way to overcome this is to make sure the content of your anchor element starts well after the element begins. To do this, we’ll need a basic understanding of the CSS box model. We’ll give the element some extra height at the top by setting the padding-top to about 50px, but since we don’t actually want each anchor element to have 50 pixels of overhead, we’ll also set the margin-top the the same amount, but negative.

Here’s an example, that hopefully makes the point more concrete:

By adding this CSS

.group, .subgroup {
    padding-top: 50px;
    margin-top: -50px;
}

We make the element grow 50 pixels taller, but ensure that the content stays in exactly the same place. Here’s a look at the example from the chrome developer tools:

PaddingMarginOffset

Now when we scroll the top of the element to the top of the window, it will start 50 pixels before the content. Here’s a full example with a working top navbar

Update with Scrollable Navbar

To make the sidebar scrollable, you can add the following CSS:

.bs-docs-sidebar > ul {
    overflow-y: auto;
    height: 100%;
}

When content overflows it’s container, there are a couple different ways to handle it in css:

overflow: visible | hidden | scroll | auto

The default is to have the content remain visible. However, this poses problems when using an element with position:fixed because you cannot simply scroll through the window to bring the visible element into view.

You can use overflow: scroll to add a scrollbar to the div, but this will always be visible, even if unnecessary, and scrollbars should be avoided unless absolutely necessary. The better option is to use overflow: auto which will provide a scrollbar only if necessary. Since we’d rather wrap long horizontal text than scroll it, we’ll only apply this to the y-axis by using overflow-y: auto.

You’ll notice once this is in place it doesn’t do anything yet. That’s because we need to tell the container how large it is so it knows when any of its contents are taking up more space that it can provide. As a test, you can just throw in height: 100px and you’ll notice that the entire contents fits into a box that is 100px tall and you can scroll to get to the rest of it.

However, we don’t necessarily know how much space we want to allow the sidebar to consume. It’s going to depend on the space available in the window and how you’re site is laid out. In the simplest form, if we alloted the entire screen height to the sidebar, we could use height: 100%.

Note: Whenever you use height: 100% in CSS, you have to next ask yourself, “100% of what?” Often this is the parent element, but fixed position elements break the layout so 100% will automatically refer to the window size. If your sidebar does not start at the top of the window, 100% height will extend past the bottom of the screen and make the scrollbar difficult to manage. You can choose a height <100% or apply your own padding to the element, instead of its parent.

Here’s a demo with a scrollable sidebar:

You can look at my spice project for a demo in production using a scrollable sidebar

Update with Affix

In the spirit of the Bootstrap’s own use of their sidebar, you can use affix to help place the location as you scroll through the page. You’ll just need to add the affix to your sidebar like this:

$("#sidebar").affix({
    offset: {
      top: 60
    }
});

And then set some styling when the .affix class is in place (bootstrap will automatically add position:fixed so we just need to set the height:

#sidebar.affix {
    top: 20px;
}

Here’s a demo with an affixed sidebar:

Insert HTML, CSS, and JS into any Web Page with a Chrome Extension

Overview

Chrome extensions have pretty good documentation and pretty good community support. Naturally, you might expect that between docs and forums that you can get a small project up and running quickly.

Unfortunately, sometimes minor simple tasks can get lost in the weeds. Documentation usually only covers the basic, small, happy flow cases and forums usually only ask about difficult, large problems. Well what about issues of medium size and complexity? Leave that to the bloggers!

Here we’ll take a look at how to create a chrome extension that uses a Content Script to change the background color of any page using jQuery.

Manifest.json

First things first. You need a way to tell chrome what your intentions are, what components come with your extension, and when they apply. To do this, we’ll use a manifest file.

The manifest file contains some JSON formatted data that Google knows how to read. There is a lot of boiler plate info that you can explore, but, for our purposes, we want to pay special attention to the content script section:

{
  "manifest_version": 2,
  "name": "Page Changer",
  "version": "0.1",
  "description": "Page Changer",
  "icons": { "16": "Icons/Logo16.png",
             "32": "Icons/Logo32.png",
             "48": "Icons/Logo48.png",
            "128": "Icons/Logo128.png" },
  "content_scripts": [
    {
      "matches": ["*://*/*"],
      "js": ["jquery.min.js", "script.js"]
    }
  ]
}

The content script must specify two things:

  1. The pages against which to run the code
  2. The external code files to run.

In this case, we’ve specified that we want to our content to run whenever the web url matches the pattern *://*/*, which is to say for all protocols, for all domains, for all pages (in other words, run everywhere).

If you just wanted to target google.com or any of it’s content pages, then you could put that there.

The second thing we’ve specified is which files to run and in which order. First we’ll load jQuery from a local copy that we deploy, and next we’ll run a file called script.js that we’ll look at in a second.

Script.js

In this simplified example, let’s say we just want to change the background color of the current page for a very obvious example of whether or not all the right components have been called. In a real world example, you might want to find all the links in the page and turn them a particular color. Or attach some code to any images on the page to allow you to easily email them. Whatever you want!

For now, let’s just run the following script which will find the body element and use the css() method in jQuery to apply the value blue to the background property:

$(function() {
	$("body").css("background","blue");
});

Note: Just so I don’t get comments about it. If this was the only change you wanted to make to the page, you can and should do this purely with CSS. The idea was to add jQuery to a page in a trivial example so you can implement your own functionality later.

Deployment

To run the extension, do the following steps:

  1. In Chrome, Open the Browser Menu
  2. Click on Tools, and then Extensions
  3. Make sure Developer Mode is checked (usually in the top right)
  4. Click Load Unpacked Extension and select the folder that contains your manfiest and extension files.

That’s it! Go to any affected page and hit refresh to see your changes applied:

Demo

To get started, you can download all the files you need to run this extension from the SkyDrive folder below.


If you’ve made changes and are happy with them, you can even deploy to the Chrome Extension Store for other people to use after getting a developer account.

Here’s a couple of extensions I’ve built for chrome, along with their source code if you’re looking for examples. Feel free to leave comments on GitHub with any suggestions or bugs using GitHub’s issue tracker.

  • Link Finder - Find all links to named anchors within the page so you can create descriptive links to content within a page
  • Copy Tabs - Creates a keyboard shortcut (Ctrl + Shift + C) which copies links for selected tabs

Upcoming: Part 2 - How to Insert HTML, CSS, and JavaScript into any page using a browser action.