Monday, December 15, 2014

Custom Angular Flyout

While working recently on a project I came across an issue where I had a finite amount of space and a bunch of actions that would be visible or hidden based on its current state.  I put some time into thinking how I could fit everything I needed and I thought that +90% of the time the user won't be performing any actions beyond just viewing the data so I started thinking about how to minify the amount of space my buttons took up.  I first thought about using icons, but unless they are so universal, it is typically better to just go with text.  So I thought about a button that has a popup menu.  I'm not sure if flyout is the technical term for it, but that sounded right to me so that is what I went with.  One of the benefits of this approach was if I needed to add more buttons down the road I know it won't cause any issues.  Likewise I will always know exactly how much real estate it will take up.
You could have infinite benders take up a finite space!

I knew that I wanted my angular directive to have a couple of things.  First I wanted the flyout to be driven by the developer so it can be reused over and over.  This can be easily solved with an ng-transclude directive.  Secondly, I wanted to make sure that it was smart enough to figure out where it was positioned in the window and dynamically display based on its position in the window.

The HTML for the flyout should be pretty straight forward.  An outer container, .flyoutContainer,  for the control, a container for the flyout, .flyout, and a div for the text/button to expand the flyout, .expanderContainer.  The .flyoutContainer has a couple events on it, blur and click, to figure out when to display the .flyout, and a ng-class directive to help with any styles you want to apply as well.  Here is the HTML result:
 
<div class='flyoutContainer' tabindex='0'  ng-click='click();' 
   ng-blur='lostFocus();' ng-class='{"expanded": options.isExpanded}'>
     <div class='expanderContainer' >
       {{options.display || 'Expand'}}
     </div>
     <div class='flyout'  ng-transclude ></div>
</div>

Next is the bare bones CSS to handle what we need.  We want the .flyout to be absolutely positioned, to start off hidden, and to go on top of other elements.  When the .expanded class is applied we will then want to change the visibility so the .flyout and its contents will be displayed.  The .flyoutContainer styles are pretty simple.  Change the positioning to relative so the absolutely positioned .flyout will be relative to it, and remove any outlining (unless you are into that kind of thing).  For the .expanderContainer I just added css to change the pointer to a cursor to make it explicit that it is clickable.  Here is the css:
    
.flyoutContainer{
    outline:none;
    position: relative;
}

.expanderContainer{
    cursor:pointer;
}

.flyout{
    position:absolute;
    top:auto;
    left:auto;
    z-index:1;
    visibility:hidden;
}

.expanded .flyout{
    visibility:visible;
}

Finally we come to the JS code to put it all together.  The easy part of the code is to just set the options.isExpanded appropriately based on the current state and event.  This will drive the CSS above.  The more difficult part of the code is making sure that the positioning of the .flyout is set appropriately based on where it is located in the window.  For this we pass in the $window parameter to the directive to get the window height and width.  We use the $window param instead of the window global element to make life easier for unit testing.  We can then compare those values with the getBoudingClientRect values of the .flyout to determine how much you need to update the top and left properties of it.  Here is the resulting JS:

function link(scope, element){
    scope.lostFocus = function lostFocus(){
        scope.options.isExpanded = false;
        clearFlyoutPosition();
    };

    scope.click = function click(){
        updateFlyoutPosition();
        scope.options.isExpanded = !scope.options.isExpanded;

        if (!scope.options.isExpanded){
            clearFlyoutPosition();
        }
    };
       
    function clearFlyoutPosition(){
        var $flyoutElement = angular.element
            element[0].querySelector('.flyout'));
        $flyoutElement.css('top', 'auto');
        $flyoutElement.css('left', 'auto');
    }

    function updateFlyoutPosition(){
        var flyoutElement = element[0].querySelector('.flyout'),
            $flyoutElement = angular.element(flyoutElement);

        if ($window.innerHeight < 
            flyoutElement.getBoundingClientRect().bottom){
            $flyoutElement.css('top', '-' +
                (flyoutElement.getBoundingClientRect().height ) + "px");
        }
        else{
            // set the top to the flyout container so it starts right at the bottom.
            $flyoutElement.css('top','auto');
        }

        if ($window.innerWidth < 
            flyoutElement.getBoundingClientRect().right){
            $flyoutElement.css('left', "-" +
                (flyoutElement.getBoundingClientRect().right -
              $window.innerWidth + 10) + "px");

        }
        else{
            $flyoutElement.css('left', 'auto');
        }

    }

}


Here is the end result with one flyout in the top left and one in the bottom right!




Monday, December 1, 2014

Create Your Own Angular Confirm Dialog


Modal dialogs have always been kind of iffy to use in regards to UX.  This goes 1000000x for web dialogs.  While most browsers somewhat support showModalDialog, it definitely isn't recommended to use for a lot of reasons.    I do believe that dialogs like other maligned things still have their place if used properly.

Loud Noises!
The type of dialogs I am referring to on the web are typically not traditional dialogs, but a transparent div of height/width of 100%.  You can find these types of dialogs all over the internet for all kinds of various things.  Even as I create this blog post blogger had a custom dialog to insert an image, and a hyperlink.
Blogception
So I wanted to create something that I could reuse and style easily as well as incorporate in my work.  An angular directive seemed like the right approach for this.  I ended up creating a simple confirm dialog that you could set the text for the title, detail, and buttons, as well as the confirm and cancel button callbacks.  

The first thing I started out with was the HTML for the dialog.  It should be pretty straightforward,  one container to take the entire page, one div that is centered in the middle of the page and is the height and width of whatever we desire it to be, the title, the detail, and the buttons.  Here is what that looks like: 
      
    <div class='confirm' ng-hide='!showPrompt'> 
        <div class='confirmContainer'>
            <div class='confirm-title'>{{confirmTitle}}</div> 
            <div class='confirm-detail'>{{detailText}}</div> 
            <div class='confirm-actions'>
                <button class='ok' btn' ng-click='ok()'>{{okText || 'OK'}}</button>
                <button class='cancel btn' ng-click='cancel()'>{{cancelText || 'Cancel'}}</button> 
            </div> 
      </div>
</div>

Next lets add some basic CSS for this dialog to center everything, and set the height/width appropriately.  We want the dialog to take the entire height & width of the page with a transparent background.  To center the container vertically we put the top at 50% and then set a negative margin top to move it back up.  We then put the buttons container to the bottom right of the confirmContainer.   
      
.confirm{
    height:100%;
    width:100%;
    position: fixed;
    top:0;
    opacity: 1;
    left:0;
    background-color: rgba(3, 3, 3, .25);
    z-index: 1000;
}

.confirm .confirmContainer{
    position: relative;
    top:50%;
    width:50%;
    margin: 0 auto;
    height:200px;
    margin-top: -50px;
    background-color: rgba(255, 255, 255, 1);
}

.confirm .confirm-actions{
    position: absolute;
    bottom:10px;
    right:10px;
}

Finally lets get to the directive code.  We are going to use an isolated scope to bind whatever properties we want as well as the 2 functions we want to call.  We will also bind a showDialog property on the scope that will show the dialog when it is set to true.  When we want it to hide we will then set it back to false in our button code.  Pretty easy.  Here is the whole directive:

 
.directive('confirm', function(){
    var template ="<div class="confirm" ng-hide="!showPrompt">
" + 
        "<br />
<div class="confirmContainer">
" + 
            "<br />
<div class="confirm-title">
{{confirmTitle}}</div>
" + 
            "<br />
<div class="confirm-detail">
{{detailText}}</div>
" + 
            "<br />
<div class="confirm-actions">
"+
                "<button btn="" class="ok" ng-click="ok()">{{okText || 'OK'}}</button>"+
                "<button class="cancel btn" ng-click="cancel()">{{cancelText || 'Cancel'}}</button>" + 
            "</div>
" + 
        "</div>
</div>
";
    
    function link(scope){
        scope.cancel = function cancelFunc(){
            scope.showPrompt = false;
            scope.cancelFunction();
        };
        
        scope.ok = function okFunc(){
            scope.showPrompt = false;
            scope.okFunction();
        };
    }
    
    
    return {
        template: template,
        link:link,
        scope:{
            confirmTitle: '=',
            detailText: '=',
            cancelText: '=',
            okText: '=',
            okFunction: '&',
            cancelFunction: '&',
            showPrompt: '='
        },
        restrict : "E"
    };
});

Now the dialogs in action:




Some next steps for this would be to create an even more generic dialog using ng-transclude so you can have your own picture upload dialog.  Likewise, another way I thought of using this confirm dialog was to use this in conjunction with a dialog service that had access to the rootScope.  That way you could have 1 dialog in your root page and have your service open/close that one as necessary.  

Tuesday, November 18, 2014

Custom Dropdown With Angular.

The more I get into front-end development the more I end up disliking standard HTML inputs.  I dislike them for different reasons, but my biggest issue has been the inability to style them how I need them to.  This goes especially double for new HTML 5 elements that you pretty much have to jump through hoops to get any kind of custom styling.  I already took on restyling a checkbox since it doesn't really work well for my fat fingers.  Now I am going to take on the select tag.

What styling a select feels like.
I don't really dislike the select tag.  Overall it is pretty simple and you can style most of it.  However. if you end up deciding to style it with colors of any type, then you will hate it.  You will hate it because you can't change the hover color when it is expanded.  You will hate it because you can't change the arrow/box at the end that indicates it is a drop down.  You will hate it even more because not only can these styles not be modified, but they are different per browser/OS combo.

So after googling a bit, I didn't find anything I completely liked, so I decided I would handle it myself.  I decided that since I would be using it for angular development that I would make it a directive and have it function as a select element, that can be customized.

Here is the end result.






Wednesday, October 15, 2014

Creating A Resortable Drag & Drop List With Angular JS.

I recently ran into a requirement that required a user to be able to resort a given list elements via drag and drop.  As soon as I heard about the requirement I shuddered a bit.  I had the vague memory of trying drag and drop once and it not being as intuitive as it should have been.

I started with a quick Google search to see what was out there and while there were some good starting points, there wasn't anything that was exactly what I wanted.  Pretty much all the examples I found were dragging from area A to area B like this.  Nothing showed resorting in the same list like I had hoped.  What was even a bit more dismaying was when I searched specifically for angular.js implementations of drag and drop I found that it didn't even come with directives for those events.  There were some directives that others implemented for drag and drop, but I decided I should figure it out for myself instead of trying to fiddle with other people's code.

So to get started I decided to break my angular code into 3 directives.  One for making an element, draggable, one for making an element droppable, and one for making the entire list sortable.

Three sir.

Draggable directive.

To make something draggable we want to create a directive that can be applied to any element that we want to make draggable.  So I restricted the directive to "A" for attribute, and added a link function that attached event handlers to the dragstart and dragend events.  In the dragstart event I needed to do a couple of things.  First set the data that is going to be transferred (this could be anything but I set mine to an attribute on the element ), tell the browser what type of transfer is happening, and finally I want to add a class to the element I'm dragging so I can style the element more appropriately.  In the dragend event handler I just want to remove said class.

The end result ends up looking like this:

directive('draggable', function(){
    return {
        restrict: 'A',
        link: function (scope, element, attributes) {
            var el = element[0];
            el.draggable = true;
            
            el.addEventListener('dragstart', handleDragStart, false);
            el.addEventListener('dragend', handleDragEnd, false);
            function handleDragStart(e){
              this.classList.add('dragging');
              
              e.dataTransfer.effectAllowed = 'move';
              e.dataTransfer.setData('data', attributes.dragData);                
                
            }
            
            function handleDragEnd(e) {
              // this/e.target is the source node.
              this.classList.remove('dragging');
            
                           
            }
        }
    }
})

What is important to note here is whatever effectAllowed property you set, will dictate certain styles like the mouse cursor, and it limits where it can be dragged to other elements that have that same effect allowed.

Likewise, for the setData attribute, you can name that whatever you like.  It is a message for you to handle later.  So if you actually have multiple sets of data to drag and drop, you can limit what accepts it by having different "types".

Droppable directive.

The droppable directive is going to be similar.  Once again I am going to limit it to be an attribute on the element and to mostly adding events to the element.  The first events that I am going to handle are dragenter and dragleave.  All I am going to end up doing with these events is adding and removing a class to the element we are dragging over so we can add an additional style to it.  Next I am going to handle the dragover event where I am going to set the dropEffect of the element to match what is in the effectAllowed above.  Finally I am going to handle the drop event in which I will grab the data specified in the draggable directive above, and call a function on the scope.

Here is what it looks like:

.directive('droppable', function(){
    return {
        restrict:"A",
        link: function(scope, element, attributes) {
            var el = element[0];
            el.addEventListener('dragenter', handleDragEnter, false);
            el.addEventListener('dragover', handleDragOver, false);
            el.addEventListener('dragleave', handleDragLeave, false);
            el.addEventListener('drop', handleDrop, false);
            
            function handleDragOver(e) {
              if (e.preventDefault) {
                e.preventDefault(); // Necessary. Allows us to drop.
              }
              e.dataTransfer.dropEffect = 'move';  
            
              return false;
            }
            
            function handleDragEnter(e) {
                // this / e.target is the current hover target.
                this.classList.add('dragover');
            }
            function handleDrop(e){
                // Stops some browsers from redirecting.
                if (e.stopPropagation) e.stopPropagation();
                var data =e.dataTransfer.getData('data');
                
                if ('function' == typeof scope.ondrop) {      
                    scope.ondrop(data, attributes.dropData , e);
                }
                this.classList.remove('dragover');  
            }
            function handleDragLeave(e) {
                if (e.preventDefault) e.preventDefault();
                this.classList.remove('dragover');  
               
            }
        }
    };
})


Reorder Directive

The reorder directive is tied to an Array object and attaches the draggable and droppable directives onto each element in the array.  I decided to make the reorder directive based on an element ("E") and enabled transclude on it allow you to style each list element yourself.  The rest of the directive creates 1 <li> element for each object in the array and implements the drop handler needed in the draggable directive.  In the drop handler I had to add an $apply call to notify the UI that changes had been made to the array and that it should be updated.

Here is the directive:
directive('reorder', function () {
    return {
        restrict: 'E',
        transclude: true, 
        scope: {
            list: '='
        },
        template: '
  • ', link: function (scope, element) { scope.ondrop = function resort(dragIndex, dropIndex, event){ if (dragIndex == dropIndex){ return; } scope.$apply(function(){ dragIndex = Number(dragIndex); // grab element to move var elementToMove = scope.list[dragIndex]; // remove the element scope.list.splice(dragIndex, 1); // insert the element scope.list.splice(Number(dropIndex), 0, elementToMove); }); }; } }; });


    Here is the end result:
    Cheers!




    Wednesday, September 24, 2014

    Restyling the checkbox.

    When you start to work on webpages that need to function well in other devices, you start to learn that certain native HTML elements aren't really made for touch.  When using a mouse, you can be pretty precise with your mouse movements and your clicking.  However, when you attempt to touch something, smaller elements will cause the user to miss often.  There are some good articles on the interwebs on the recommended size of elements that will require touch, including some guidelines from Microsoft.  One of the elements that I have been getting frustrated with recently is the check box.  My fingers had a rough time clicking them on a tablet device.

    This episode is almost 20 years old.

    So I decided to come up with something that would be easier for a user with a touch interface to use, but still act as a check box.  Like most of my element redesign, I wanted to avoid using any JavaScript and rely on solely on CSS.  Taking a look around the web and other places I decided to settle on an on/off switch looking element.

    The first thing we want to define is the button HTML.  First we define a container element for the class.  We are going to use this element as the container and anchor for everything inside it.  Next, we add a checkbox (because we still want to use the functionality of the checkbox for binding, form submitting, etc.  I then added a "background" element that would span the entire width and change based on the input being checked or unchecked (I'll get to this more later).  Lastly, we add a few elements to give it the "switch" feel.  That is a label for "On", "Off", and label that is going to act as the "slider" for the switch.  Our HTML is going to look like this:

    <span class='toggleContainer'>
            
        <input class='toggleInput' type='checkbox' id='chk'></input>
        <span class='background'></span>
        <label class='slider' for='chk'></label>
        <label class='on' for='chk'>On</label>
        <label class='off' for='chk'>Off</label>
    
    </span>
    

    So you might think it is odd that I am using labels for these elements, especially for the "slider".  The reason that I do this, has to do with the "for" property of the label.  By clicking on the label, it will click the element for you.*

    So now that we have our structure designed we need to style everything to turn it into a toggle button.  First we will style the container.  We are going to use this to determine the size of everything.  So we need to set the position it to be relative to give us an anchor for all the child elements, set overflow to hidden so nothing flows out of  the container, and finally just set a nice border.

    .toggleContainer{
        border: 1px solid white;
        border-radius:6px;
        display:inline-block;
        width:50px;
        height:20px;
        position: relative; 
        overflow:hidden;
    }
    


    Next, lets style the check box.  We really just want to make it invisible, and not effect the rest of the HTML.
    .toggleInput{
        position: absolute;
        opacity: 0;
    }
    

    Now we want to style the on, off, slider, and background.  I include these all together because they all need two styles each.  One for checked and one for unchecked.  So let's start with the first state which is unchecked.  For the background we are going to set it as the entire width and height of the container (including the border radius), and set the background-color for when the we are unchecked which I will set to red.  I am going to also set the transition of the background color which will give a smoother transition feel.

    .toggleContainer .background {
        position: absolute;
        width: 100%;
        height: 100%;
        border-radius: 6px;
        background-color: red;
        opacity: 0.2;
        -moz-transition: background-color .3s;
        -webkit-transition: background-color .3s;
        transition: background-color .3s;
    }
    

    The slider will be defaulted to the left side of the toggle, with the on element hidden off the left, and the off displayed to the right of the slider.  Instead of just hiding the elements, I want to make it look smoother by moving objects to the left and right.  So I added a transition to the elements below.

    .toggleContainer .toggleInput ~ .slider {
        position: absolute;
        width: 45%;
        height: 100%;
        content: "";
        background-color: white;
        border-radius: 6px;
        display: inline-block;
        z-index: 1;
        left: 0;
        -moz-transition: left 0.3s;
        -webkit-transition: left 0.3s;
        transition: left 0.3s;
    }
    
    .toggleContainer .toggleInput ~ .off, .toggleContainer .toggleInput ~ .on {
        width: 50%;
        position: relative;
        z-index: 10;
        display: inline-block;
        overflow: hidden;
        height: 100%;
        top: 50%;
        margin-top: -8px;
    }
    
    .toggleContainer .toggleInput ~ .on {
        left: -50%;
        float: left;
        -moz-transition: left 0.3s;
        -webkit-transition: left 0.3s;
        transition: left 0.3s;
        color: green;
    }
    
    .toggleContainer .toggleInput ~ .off {
        right: 0;
        -moz-transition: right 0.3s;
        -webkit-transition: right 0.3s;
        transition: right 0.3s;
        float: right;
        color: red;
    }
    
    
    Now that we have a default style, we need to add styles for when the element is checked.  To do this we can use the :checked css selector and apply the styles that we want to change.  Mostly we want to move everything to the right which gives the appearance of a switch being moved.  The only exception is the background which we will change from red to green.

    .toggleContainer .toggleInput:checked ~ .background {
        background-color: green;
        -moz-transition: background-color 0.3s;
        -webkit-transition: background-color 0.3s;
        transition: background-color 0.3s;
    }
    
    .toggleContainer .toggleInput:checked ~ .slider {
        left: 55%;
        -moz-transition: left 0.3s;
        -webkit-transition: left 0.3s;
        transition: left 0.3s;
    }
    
    .toggleContainer .toggleInput:checked ~ .on {
        left: 5px;
        -moz-transition: left 0.3s;
        -webkit-transition: left 0.3s;
        transition: left 0.3s;
    }
    .toggleContainer .toggleInput:checked ~ .off {
        right: -50%;
        -moz-transition: right 0.3s;
        -webkit-transition: right 0.3s;
        transition: right 0.3s;
    }
    
    


    Here is the end result:
    I think the best way to use this would be to create a widget, directive, or whatever your JS framework supports. With a little bit of extra JS you can add some additional classes such as a class to the entire module and style the entire element differently.

    *If you are putting this on the web, you should really think about accessibility.  Having those extra labels for one input might confuse some screen readers, and by extension your users.  A couple of extra click handlers for the labels won't kill anyone. 

    Tuesday, September 16, 2014

    Using Iconic Fonts



    One of the new things I've started incorporating in my development is the use of iconic fonts.

    No No No!

    I'm talking about fonts that have icons in their character set like font awesome, batch icons, ico moon, and many many more.

    So why would you use a font with icons in them instead of just images?  Well there are a lot of really good reasons, that other blogs talk about, really well so I will summarize my thoughts and what I have learned.


    1. Really easy to use.
    2. You can style them like you would a normal font (color size etc.)
    3. You load them 1x.
    4. Pretty much all browsers support them.

    But wait, what about accessibility and users that might need to use screen readers?  Won't using these trip them up?
    Dr. Says No.
    Well, not if they do it right.  If an icon font is working correctly it will use the Private Unicode character range.  So it won't trip up the reader.

    So now that we have established the reasons of why to use them, we need to see how to use them.

    First thing you need to do is load the font via CSS as follows:
    @font-face{
        font-family:Batch;
        src:url('https://googledrive.com/host/0B4QQSpfhQZN5bFZ1ckV4QTRPb2s/batch-icons-webfont.eot');
        src:url('https://googledrive.com/host/0B4QQSpfhQZN5bFZ1ckV4QTRPb2s/batch-icons-webfont.eot?#iefix') format('embedded-opentype'),
            url('https://googledrive.com/host/0B4QQSpfhQZN5bFZ1ckV4QTRPb2s/batch-icons-webfont.woff') format('woff'),
            url('https://googledrive.com/host/0B4QQSpfhQZN5bFZ1ckV4QTRPb2s/batch-icons-webfont.ttf') format('truetype'),
            url('https://googledrive.com/host/0B4QQSpfhQZN5bFZ1ckV4QTRPb2s/batch-icons-webfont.svg#batchregular') format('svg');
        font-weight:normal;
        font-style:normal;
    }
    



    Next you use that character in your html.  
    .batch {
        font-family:"Batch"; /*or whatever you've decalred your font name as*/
        font-size:16px;
        line-height:1;
        
    }
    
    
    Super easy!


    That is nice, but I want to be awesome.  I want to have a button that does X (settings, cancel, ok, etc) and I don't want to have to have that code everywhere I have an ok button.  I just want to to have my class know about the font and character.

    You can be that awesome.  We can use the ::before and ::after pseudo-elements to do that.
    .before::before{
        font-family:"Batch";
        content: "\f000";
    }
    


    That is awesome! But you know, after thinking about it, I don't want my content in my css it doesn't feel right. I still think pseudo elements are sweet though. Good News! You can still use them and even use the 'data-' attributes as well. Just put the character code in a data attribute of your choice, and add the following class.
    .data::before{
        font-family:"Batch";
        content: attr(data-icon);
    }
    

    Here is the final output of everything!
    view the tif file.


    Wednesday, August 20, 2014

    Making Some Progress

    I just started on a new project recently and one of the things on the page I was working on was displaying progress bars in different colors.  The progress bars need to display an indeterminate state and after talking with a co-worker we thought making it look like KITT from Night Rider was the best (and most awesome) way to display that.


    Is that you Mr. Feeny?
    Because of a lot of my work being done on the canvas, and to have communication being done with web sockets, I am only supporting modern browsers for this app.  I knew there are a ton of new elements in HTML 5 and one of my personal goals is to become better at writing semantically correct html.  A quick look through the elements, and I found the <progress> tag.  Even better, it comes with an indeterminate state and is supported in the browsers I care about.  My next requirement was just to style the progress elements different colors based on their states.  I thought this is going to be easy.  All I need to do is add some classes to set the color and I'm done!


    So after a quick search I find out you pretty much can't do anything to style a progress element.  Which made me think...  how do you expect people to use this element if they can't make it look how they need it to?

    I was determined to use CSS only to get this to work and make my page semantically awesome.  I found some sites like this that show you how to clear out the native browser appearance and add your own.  So I started with that and then added my own classes to style them how I needed.  A lot of CSS later, I came up with the following:

    .progressContainer{
        position:relative;
        width: 100px;
    }
    
    progress{
      height:5px;
      border:0;
      appearance: none;
      -moz-appearance: none;
      -webkit-appearance: none;
      width:100% !important;
     
    }
    
    progress.connected::-webkit-progress-value{
      background: green;
    } 
    progress.connected::-moz-progress-value{
      background: green;
    }
    progress.connected::progress-value{
      background: green;
    }
    progress.connected::-webkit-progress-bar{
      background: green;
    } 
    progress.connected::-moz-progress-bar{
      background: green;
    }
    progress.connected::progress-bar{
      background: green;
    }
    progress.connected:not([value])::-webkit-progress-bar{
      background:green;
    }
    progress.connected:not([value])::-moz-progress-bar{
      background:green;
    }
    progress.connected:not([value])::progress-bar{
      background:green;
    }
    

    With the lower half repeated for each class that I wanted, I was almost done. While verbose, I was able to style the progress as necessary. The only thing left was to get KITT to work. After some quick thinking I figured I would use a ::before pseudo element and animate it.
    @-webkit-keyframes knightRider {
       0% {
     left: 0%;
          }
     
      50% {
     left:100%;
            margin-left:-10px;
          }
      100%{
     left:0%;
          }
    }
    @keyframes knightRider {
       0% {
     left: 0%;
          }
     
      50% {
       left:100%;
            margin-left:-10px;
          }
      100%{
     left:0%;
          }
    }
    
    progress.searching::before{
      content:"";
      background-color:blue;
      width:10px;
      height:5px;
      position: absolute;
      animation: knightRider 2s infinite linear;
      -webkit-animation: knightRider 2s infinite linear;
    }
    
    A quick refresh of my fiddle and BOOM it was working.  Now I just need to make sure it is working in Firefox which should be just a formality, right?  Wrong!  Only webkit browsers support ::before and ::after on progress for some bizzaro reason.  So I ended up adding a hidden div next to the progress bar that would use the animation from above and only show up when a specific class is added to the progress bar.

    See the Pen Progress by Andy (@andyjmeyers) on CodePen.




    Finally some progress...

    Friday, August 8, 2014

    Beyond The Wall (Proxy)

    North of the Wall, things are different. That's where the children went, and the giants, and the other old races.
    Nowadays a lot of development resources are managed via a package manager. While this makes life a lot easier almost all of the time, it can be a little bit of a headache if you aren't set up like everyone else is. When I first started out at Motorola, I had a rough time getting some of these to work. I finally realized that it had to do with me being behind the company proxy.  So here is what you need to do to get a couple things to work if you are behind a company proxy so hopefully someone else doesn't have to go through what I did.

    1. Bower
    Open up your bower config file (.bowerrc) and add the following lines:

      "proxy":"http(s)://server:port/",
      "https-proxy":"http(s)://server:port/"

    2. Git 

    Open up your .gitconfig file and add the following lines:

    [http]
        proxy = http(s)://server:port/
    [https]
        proxy = http(s)://server:port/

    3. NPM

    I believe these get stored in the .npmrc file, but npm recommends you set them via command line with these commands.

    npm config set proxy http(s)://server:port npm config set https-proxy http(s)://server:port

    Your .npmrc file then looks like this:

    proxy =http(s)://server:port
    https_proxy = http(s)://server:port


    *The image above is copyrighted by HBO

    Saturday, August 2, 2014

    Testing Angular Directives That Repeat With Transclude

    The title is a bit of a mouthful, but recently I was writing a unit test for an angular directive I was working on.  The directive's purpose is to flatten a binary tree and display all of the leafs in a list.  A demo of the working code is here: JS Fiddle.

    Here is the actual directive:
    .directive('flattenTree', function () {
    
        return {
            restrict: 'E',
            template: "<li ng-repeat='node in tree' ng-transclude></li>",
            transclude: true,
            scope: {
                root: '='
            },
            link: function (scope) {
                scope.tree = [];
                var index = 0;
                var queue = [];
                queue.push(scope.root);
                while (queue.length != 0) {
                    var node = queue.shift();
                    if (node['left']) {
                        queue.unshift( node.right, node.left);
                    } else {
                        scope.tree.push(node);
                    }
                }
      
            }
        };
    
    });

    When writing the tests I wanted to validate a few things.

    1. If the root node is null then it doesn't display anything
    2. That the root node is traversed correctly and all leaf nodes are displayed in order
    3. That each node has a corresponding <li> tag and the html in the transclude is displayed for each one.

    Here is what I came up for my test that is written with Jasmine.

    My setup code in which I grab the angular objects that I need to run the tests.
    var $compile,
        $rootScope;
    
    // Store references to $rootScope and $compile
    // so they are available to all tests in this describe block
    beforeEach(inject(function(_$compile_, _$rootScope_){
    
      // The injector unwraps the underscores (_) from around the parameter names when matching
      $compile = _$compile_;
      $rootScope = _$rootScope_;
    
    }));
    
    

    And my 3 tests.  Each test consist of 3 parts.

    1. Setting up the data and the template I want to use (always using <flatten-tree> since that is my directive).
    2. Compiling the template and calling $digest to make the angular magic work.
    3. Validating the result & DOM with the jqlite that comes with angular.

    it('replaces the element with null when empty', function() {
        // Compile a piece of HTML containing the directive
        var template = "<flatten-tree><span>{{node}}</span></flatten-tree>";
        var element = $compile(template)($rootScope);
    
        // fire all the watches, so the scope expression will be evaluated
        $rootScope.$digest();
    
        // Check that the compiled element contains the templated content
        expect(element.children().length).toBe(0);
    });
    
    it('replaces the element with a single li when one node', function() {
    
         $rootScope.node = "foobar";
        var template = "<ul><flatten-tree root='node'><span>{{node}}</span></flatten-tree></ul>";
        // Compile a piece of HTML containing the directive
        var element = $compile(template)($rootScope);
        // fire all the watches, so the scope expression will be evaluated
        $rootScope.$digest();
    
        // Check that the compiled element contains the templated content
        expect(element.find("li").length).toBe(1);
        expect(element.find("span").length).toBe(1);
        expect(element.find("span").text()).toBe("foobar");
    });
    
    it('traverses the tree and replaces the element with a list', function() {
    
        $rootScope.node = {
            right:{
                right:1,
                left:2
            },
            left:{
                right:{
                    right:3,
                    left:4
                },
                left:{
                    right:5,
                    left:6
                }
            }
        };
    
        var template = "<ul><flatten-tree root='node'><span>{{node}}</span></flatten-tree></ul>";
    
        // Compile a piece of HTML containing the directive
        var element = $compile(template)($rootScope);
    
        // fire all the watches, so the scope expression will be evaluated
        $rootScope.$digest();
    
        // Check that the compiled element contains the templated content
        expect(element.find("li").length).toBe(6);
        expect(element.find("span").length).toBe(6);
    
        var spanElements = element.find("span");
        for (var i = 0; i < spanElements.length; i++) {
               expect(spanElements[i].innerText).toBe((i+1).toString());
        }
    });
    
    
    
    Easy as pie!

    Monday, July 7, 2014

    HTML 5 Canvas Zoom

    Pretty much since my first day at Motorola I have been working with HTML 5 canvases.  I have been mostly working on creating a charting framework from scratch because the existing frameworks don't perform well enough.

    Without going into too much detail, one of the newer pieces of functionality that I added was the ability to zoom into a section of the chart by dragging your mouse over a given area.  JS Fiddle Link.  

    The first challenge was to figure out where on the canvas the mouse event is happening.  All of the mouse events (move, down, etc) use the same event object so I created a helper function that would get the current coordinates from the current event object.
    function getCursorPosition(e) {
        var totalOffsetX = 0;
        var totalOffsetY = 0;
        var canvasX = 0;
        var canvasY = 0;
        var currentElement = e.target;
        do {
            totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
            totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
        }
        while (currentElement = currentElement.offsetParent)
        canvasX = e.pageX - totalOffsetX;
        canvasY = e.pageY - totalOffsetY;
        return {
            x: canvasX,
            y: canvasY
        }
    }
    The crux here is to make sure to keep getting the offset of the each element because the parent might not be the window.  Another thing I ran into with the mouse events was since I was handling the mousedown and mouseup events I had to add a flag on mousemove to indicate whether or not if the mouse action was a click event or not.

    The next piece of logic is the actual zoom function.

    function zoom(point1, point2) {
        var canvas = document.getElementById('myCanvas');
        var translation = {
            x: point2.x,
            y: point2.y
        };
        var canvasMax = {
            x: point1.x,
            y: point1.y
        };
        if (point1.x < point2.x) {
            translation.x = point1.x;
            canvasMax.x = point2.x;
        }
        if (point1.y < point2.y) {
            translation.y = point1.y;
            canvasMax.y = point2.y;
        }
        currentTranslation.x += 1 / canvasScale.width * translation.x;
        currentTranslation.y += 1 / canvasScale.height * translation.y;
        canvasScale.width = canvasScale.width * canvas.width / (canvasMax.x - translation.x);
        canvasScale.height = canvasScale.height * canvas.height / (canvasMax.y - translation.y);
        drawPicture();
    }

    In he function I choose the upper left hand point of the rectangle as the points of the translation.  I then figure out what the position should be based on the current zoom.  Next we have to figure out the new scale based on the current scale, and the size of the rectangle that we selected.  Once we have generated the scale and translation we can just plug them in our paint function.

    While this code gave me a good start on what I needed, the actual implementation for the charting functionality is a bit more complicated due to having to scale the numbers on the graph without actually scaling the axis canvas.  

    Saturday, July 5, 2014

    New Job At Motorola

    I wanted to write a post about my new job at Motorola Solutions (the part not bought by Google/Lenovo), but I figured by waiting for about about a month into the new job I would have a better perspective and not have as many emotions about the transition (also I've been pretty lazy about it).  After being somewhere after 8 years and seeing it grow from 11 people to 100 it is hard not to have many emotions.  My new job title at Motorola Solutions is Sr. Software Engineer, but I am going to be a front end developer.  This alone is a pretty big change.  After being focused mostly on the .Net platform and full stack development most of my career, I am going to be doing mostly UI work in JavaScript and Java for some older front-ends.  There will also be a sort of a UX/UI component to this position which I am looking forward to as well.

    I'll start off by talking about why I was looking to leave Sonoma Partners after 8 years.  Overall I will look fondly at my time there.  I have met a lot of really awesome people who I hope to keep in touch with and some that left before me that I already do.  I also got to do some things that I wouldn't have been able to do in other jobs like manage people, leadership stuff, and manage project teams.  While everyone has different priorities for what they look for in a job (upward mobility, security, salary, day to day, etc.), I would say the biggest things that I was looking for were the following: move away from the Microsoft stack, go back to more of an IC role, learn new skills, and do more interesting things to push my boundaries.  While these were the main factors, they weren't the only.  In the end my good days were outweighed by the bad and I needed to do something new and get a new perspective.

    So far the new job is going really well and I don't have any regrets about the decision I have made.  I have learned a ton of new things since I have started, and already done some really cool things.  In one month I have picked up the following technologies and use them on a daily basis:  angular, node, bower, protobuf, yeoman, selenium, grunt, jasmine, web sockets, canvas, sass, and more.  I find myself being really engaged on a daily basis, have the day go by a ton quicker, and most importantly being excited about work that day.  Besides the actual work improvement I have also started to get into shape since they have an onsite gym there.  Since I have started there I have hit the gym every day (was able to watch the world cup :) ), or played ultimate frisbee.


    I hope to start to get back to blogging more often.  I have some really interesting things that I have worked on that I hope to blog about.  I may also blog about the actual job hunting process which was interesting as well.  I probably won't be doing much more Ruby stuff for a while, but there will be plenty of new and interesting things to talk about as well.

    Saturday, May 24, 2014

    Knockout Trees and Fancy CSS buttons.

    For the past couple of weeks I have been working on some pages using knockout.js that have a fairly complicated UI.  A few of the elements in the pages don't look or function like standard HTML elements and there are a lot of lists that could contain lists (essentially a tree).  While I would have loved to use angular for this, I ended up going with Knockout mainly due to there being a lot more familiarity with that framework throughout Sonoma (myself included) and there was a short turnaround time.

    I put together a quick demo of some things that I thought were interesting on this JS Fiddle.

    To create a tree like structure, I defined a JS constructor function Node that will act as typical tree node containing a Label and a list of children nodes.  I created a function on the Node to add a child to make view cleaner and I had my objects defined.  I applied bindings to the "root" node and I had a pretty standard data tree.

    In my HTML view I created a "template" for each node so whenever a new node was created I automatically use that template.  In each template I needed to expose 2 actions.  The first one is a button that would add a child Node to the current Node.  That button just calls the prototype function that was defined previously.  The second button is to remove the current Node from the ObservableArray that it is currently in.  To do that I knew that the parent scope would be the parent node (a new scope is created for each template), and that I could remove it from the collection using the Remove method on the array.  Finally I put a check on there to make sure that the $parent isn't equal to the $root so the root node never gets removed.

    For the buttons I ended up changing their styles to look dramatically different.  For the delete buttons I just wanted them to display as a "X" icon so I changed the background of the button to the image, removed the border and changed the cursor to a pointer to make it more obvious.  The other thing I had to do was to remove the focus outline of the button.  To do that I added an :active pseudo selector to remove the outline that is added.

    For the Add buttons I wanted to display text as well as an image so I needed to do a little more work.  First, I added an underline to the text and changed the color to make it more apparent that this was clickable.  I then applied the same styles ass the delete button except for the background image.  For the image I added a a ::before selector to put an image before the button.  Now those images will be displayed with the button and are clickable just as if they were part of the button itself.  I also don't have to remember to add that image if I need to add a similar looking button elsewhere in my application, which would be pretty likely.


    Thursday, April 3, 2014

    Application-Wide JavaScript Autocomplete for Rails

    For my skills application site I wanted to add some more front-end JS code, but wanted to start with something simple.  So the first thing I could think of that was pretty easy to do was adding an autocomplete to a couple of the search boxes.  The search boxes allowed  you to search based on the skill name.  Unfortunately there are over 1500 skills.  So making sure that you query the right skill is hard to do.

    To create the autocomplete I decided just utilize jQuery UI's autocomplete control.  For my initial pass I decided to not use the service based approach and go with a static source of values.  To access these values I decided I would put the list of values in a data attribute on the actual autocomplete control itself.  The JavaScript would just then pull those values from that attribute.

    Here is what I came up with:

      <%= text_field_tag :skills, params[:skills], :id=> 'skills_autocomplete',
            :data => {:skills =>  SkillTotal.retrieve_skills() } %> 
    <% content_for :javascript do %>
      <script type='text/javascript'>
        $(document).ready(function(){
          $("#skills_autocomplete").autocomplete({
            source: $("#skills_autocomplete").data("skills")
          });
        });
      </script>
    <% end %>

    It ended up working out pretty well, however in my form JS I was querying the control by its ID.  Every time I needed an autocomplete I would essentially have this code on each one of my views.  I decided that this was good, but I could do better.  I wanted to make it more DRY.

    I created a global.js file where I would put an on load function and set up the autocomplete so I didn't have to put it on each form.  Instead of going by the ID, I went by a class as well.  In the end it looked like this:

    <%= text_field_tag :skills, params[:skills], :class=> 'autocomplete',
            :data => {:autocomplete_data =>  SkillTotal.retrieve_skills() } %>
    (function(global){
        global.App = global.App || {};
        global.App.autocomplete = function(){
            $(".autocomplete").each(function(){
                var field = $(this);
                field.autocomplete({
                    source: field.data("autocomplete-data")
                });
            });
        };
    }(this));

    $(document).ready(App.autocomplete);
    I soon found out that my code wasn't working.  A little bit of digging and this has to do with the turbolinks gem which is included by default with Rails.  A little more digging and I now my JS looks like this and is running on multiple pages.

    (function(global){
        global.App = global.App || {};
        global.App.autocomplete = function(){
            $(".autocomplete").each(function(){
                var field = $(this);
                field.autocomplete({
                    source: field.data("autocomplete-data")
                });
            });
        };
    }(this));

    $(document).ready(App.autocomplete);
    $(document).on('page:load', App.autocomplete);



    Wednesday, March 26, 2014

    Setting up a daily task on Heroku

    When I set out to create the Skills App site, one of the main things I wanted to figure out was how to scrape the data on a daily basis and automatically insert into the database, preferably at the same time each day. I started out with some quick googling while I was developing the app, but nothing obvious stood out. There were a couple of ways that seemed to be repeated on how to get data into a rails app. One was having a rake task, and the other one was via a seed file. I wasn't sure what to do so I tabled it, and decided that it would be one of the first things that I figure out after the initial deploy.

    After the deploy, my good friend Scott Parker, who makes awesome dragon games, gave me some feedback on the site after reading my initial post.  He suggested that I take a look into using rake and the scheduler add-on for Heroku. I took a look at rake and played around with it a bit. I also found a useful railcast about it which helped me figure out what I needed to do.


    So I took the majority of my scraper code and put it into the rake task and tested it locally to make sure it was working, then I set up the scheduler to run around midday, uploaded all of the data I have been collecting every day and anxiously waited to see if it would automatically add today's data.



    Success!  Data from today!

    Enjoy the site and please feel free to reach out to me with feedback, feature requests, or anything else.  For those that have given me feedback, I really appreciate it and hopefully I will implement your features soon!


    Monday, March 24, 2014

    Deploying to Heroku

    When I deployed my Skills Compiler rails app the other day, I ran into a few issues deploying to Heroku that were worth mentioning.  
    1. Deploying from a folder that is not the root.

      As stated on the Heroku website:
            Heroku apps expect the app directory structure at the root of the repository. If your app is inside a subdirectory in your repository, it won’t run when pushed to Heroku.
      I knew there had to be a way around this. As someone that has created lots of project structures in their career, I typically don’t put the main app in the top folder. I have found that you can paint yourself in a corner by doing that. When I create a project, I want to include everything that is necessary for it, which could mean other apps, documents, or whatever.

      I ended up finding this site:
      https://coderwall.com/p/ssxp5q that had the same issue and solved it by pushing a subtree. It is as simple as this command:

      git subtree push --prefix subfolder heroku master

    2. Make sure your git ignores are correct.

      When I pushed to Heroku using the command above, nothing ended up working.  The console logs weren't much help (just kept giving me generic errors), and when I used the console to list the files, everything appeared to be copied over correctly.  After some digging I realized that none of the rails commands were working on Heroku.  I eventually found an error that pointed me to an issue with something missing from the bin folder.  I found that because I was using the default .gitignore file from GitHub with a few altercations, that the /bin folder was globally ignored due to .Net & (I believe) Java.  After a few modifications to the .gitignore file I finally got my site up and running on Heroku.




    Sunday, March 16, 2014

    Skills Application

    I have been working on this application for a few weeks now, and I am finally ready to release version 1.0 of it.  The site, Skills Compiler , (I suck at naming) was inspired by a few things, but these in particular. I wanted to teach myself a new language, I wanted to do some more general web development, and finally I was inspired a bit by the Passionate Programmer: Creating a Remarkable Career.  If you haven't read the book, I definitely recommend it.  In the book, one of the points it makes is keeping up with latest trends making sure your skills are up to date, and it kind of inspired me to think about ways of finding the trends in the development community, which is something I personally wanted to improve on.  

    All of this combined with my curiosity started me down the path of creating this app.  The app displays data that I have scraped from the Careers 2.0  in a few different ways.  The app displays the totals per day, as well as the overall totals for a given tag.  A tag is counted when it is listed for a given position.  For example, this position by Sonoma Partners for a Salesforce Developer would add 1 to the daily count for Java, visualforce, apex-code, soql, and JavaScript for each day the job is listed.  

    Obviously this is just a small snapshot of the jobs that are out there because it currently only looks at one site, however there are still some interesting things that you can gather from a month and a half worth of data.

    Wednesday, February 19, 2014

    CSS Solar System

    In my quest to expand my HTML/CSS I stumbled across this exercise at Codeacademy that showed you how to create a simple animated solar system using only CSS.  I completed the exercise and added a bit more to it as well.  I took his example and expanded upon it to include all of the planets, a few moons, and some rings around some planets.  After I added a couple planets I knew that there was a pattern emerging and decided to use SASS to make my CSS cleaner, as well as it gave me an excuse to use it.