Improving Me

code blog for my deliberate practice.

TIL => TIL: Knockoutjs

TIL: KnockoutJS Click Handler

While working on a client project for @improving I’ve learned a few things about Knockoutjs and its behavior. Most of them have been learned the hard way, by reading documentation after something didn’t work as expected.

The ko click binding was one of those things. I was trying to listen for a click event for on a checkbox and do some fancy css swapping to highlight the user’s selection. Changing the styles worked smooth as butter, but the box remained unchecked.

After several refreshes of the page, still no check in the box. The knockoutJS documentation covers this case - it is clearly noted as Note 3: Allowing the default click action The ko.click binding doesn’t pass along the actual event. In order for the event to bubble, the bound function must return ‘true’.

Now that I’ve added a return value of true to my javascript handler, the checkbox is updated as I had expected it to be from the beginning!

TIL => ReportViewer Control, Less Is More

TIL: ReportViewer WebControl => Less is More

Stop me if you’ve heard this one: “Their IT staff is going to take care of that development …” And so it was recently on a project I am developing.

A separate development activity was spun up to create the required SSRS reports which were to be hosted on a Report Server. Well the Report Server uses Active Directory accounts for authentication and authorization. The portal that I’m building essentially uses the ASP.net Membership Provider and its services.

Suddenly, I was confronted with a situation where I needed to provide access to reports hosted on a report server from my MVC application and handle security for the reports too. Enter the ReportViewer control, hosted in an ASP.net WebForm ASPX page and running remote mode SSRS reports.

I scrambled to learn how to host the ReportViewer Control and have it render reports in my application. I didn’t search long enough to find a fully baked, working sample, but was able to get a report to render based on an initial set of parameters. I was happy and smug as a bug in a rug. But then I find out that this report should page and sort and link through to other reports. Now I’m a sad panda.

For my first attempt to host the ReportViewer control, I tried to juggle the parameters and update the report URL on each request. As it turns out, I was doing that wrong and completely broke the drill-through reports, paging and searching. After about half a day of combing the Internet for the secrets to keeping the remote reports fully functioning and not finding much helpful, I started to experiment.

Here is what I ended up with in the WebForm code-behind:

wound up doing it setting the report server and report title in the OnInit method of the web-page. I also bound the selection controls to the available options for the current user and wired up the change event handlers. PostBack events that aren’t triggered by the selection controls that I added to the web form are ignored by the code behind and the httpHandler for the report viewer control handles the interaction with the SSRS server.

E*trade Has Buggy Client-side Javascript

Once a month I get a little reminder that I need to go pay my e*Trade credit card bill. Every month for as long as I can remember I’ve tried to use their user interface to pay off my current balance and been told by an error dialog that my selection is not valid.

Error Message

I have clearly selected a frequency of “One Time” and not “Once a Month” as the dialog box indicates.

Eventually I got annoyed enough that I actually took the time to investigate the form elements and javascript that are in play and found the bug in their code.

Using their “secure request” feature, I attempted to let them know that they have buggy client side validation, but was unable to include anything in the message that remotely resembled javascript. I wasn’t even able to post the word “var”. I did create a pair of jsfiddles, one with the buggy code and one with the correction and attempted to send links in a “secure communication”. No dice, hyper links aren’t allowed either.

Eventually somebody at e*Trade actually read the content of a message before picking a reply script and here is the reply that I received:

Dear Mr. Forrest,

Thank you for your message regarding our quick transfer feature.

If you are still able to replicate this issue, please call our technical support team Monday-Friday from 7:30am-7pm. est for troubleshooting. This is a miscellaneous issue and will need to be troubleshooted accordingly. We regret any inconvenience this issue may cause.

This was at the end of May. It’s the middle of August as I write this and no one at eTrade has “troubleshooted” it or fixed the problem.

Here is the form that their quick transfer uses:

This is the buggy code block within the ValidateForm function:

Since document.theForm.transfer_freq.options.value is undefined, the comparison is always going to be true regardless of the value that the user actually selected. I’m fairly certain that they intended to compare the value of the selected option, but that isn’t what that javascript is actually doing.

This is the bug fix that I implemented 4 months ago that e*Trade hasn’t bothered to correct

With a little jQuery goodness, I can actually perform the comparison that I believe was intended. Now the first part of the expression has a chance to evaluate to false.

One day I’d like to use that form and be able to click the “Current Balance” radio button and have the form submit without reminding me that I’m using a site with buggy code.

console.log Anywhere

My current assingment for Improving Enterprises has me writing much more client-side javascript. I’m not a javascript ninja, so I lean on the console window to confirm that the script is doing what I expected it to do. This approach works great until I view a page in IE, which has no clue what “console” means and acosts me with script error popups.

This finally got annoying enough that I started looking for a universal solution. Stack Overflow to the rescue. Just so I don’t have to search high and low for it again, I put a gist on github where it’s easy for me to find again.

Now while I’m testing things in different browser while developing the scripts, I don’t have IE complaining about a script error.

Doesn’t Play Well…

I’ve been working on some “prototypes” for a new Improving client. One of our UX people told us to use Twitter Bootstrap and don’t look back.

These prototypes are for a data entry focused application, so we’ve been using the Autocomplete Combobox to help speed things along. I tried to also use the bootstrap-buttons plugin in conjunction with it, but the buttons weren’t working as expected.

I changed the markup to load the button plugin prior to the jquery ui script and the radio buttons looked and behaved as expected, but the auto complete comboboxes looked funky and were no longer acting like text boxes and default to select boxes. When I switched back to loading the jquery ui first, the comboboxes resumed their normal operation.

Lacking the time to get to the very bottom of why these two scripts weren’t playing nice together, I used a lifeline and got advice from a UX buddy. I was pointed toward the button sets jquery ui. After changing the markup to use the button sets, everything was playing nicely together.

Adding CoderWall Badges

I’ve picked up a few badges via CoderWall and I wanted to include them on the blog with the rest of the information in the right side column.

CoderWall has instructions under the sub heading “Official blog badge” that detail how to interact with their web api for retrieving badges. My main investigation was how and where to include these snippets within the octopress templates.

The comments included in the Octopress _config.yml were quite helpful. This was exactly the guidance that I needed.

excerpt from _config.yml
1
2
3
# list each of the sidebar modules you want to include, in the order you want them to appear.
# To add custom asides, create files in /source/_includes/custom/asides/ and add them to the list like 'custom/asides/custom_aside_name.html'
default_asides: [asides/recent_posts.html, asides/github.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html, asides/googleplus.html, custom/asides/coder_wall.html]

So, I was off to the ‘custom/asides/’ folder to add a ‘coder_all.html’ file. Inside this file, I pasted the snippet from the CoderWall api page, updating it to use my user id.

I ran thru ‘rake generate’ and ‘rake preview’ to see my changes in the browser. I was rewarded with absolutely nothing. Sad Panda. So I looked at the Chrome debug console and found the jQuery was not defined.

The internets have taught me to include my script tags near the end of my mark up, I removed the script tag from my aside template. Since Octopress has a footer.html template, I opened that up to include my script tags, ensuring that the jQuery tag was before the CoderWall js file.

script tags
1
2
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://coderwall.com/javascripts/jquery.coderwall.js"></script>

One more time thru the ‘rake generate, rake preview’ dance and… TA-DA! At the bottom of the Aside column I now have CoderWall badges.

Fixed Navigation Bar With Twitter Bootstrap

Twitter Bootstrap has many very interesting features available. I really liked their fixed sub navigation menus for the feature pages. As you scroll past the subnavigation, it docs with the top of the scroll window and stays there. It also enables click navigation to other feature sections.

I wanted to have the same functionality for my own html pages, so I started digging around. Looking at the page source, I saw an include for “/js/application.js”, which is included in the github source project, but is not part of the downloaded assets. At the top of the file is this nice disclaimer:

Disclaimer
1
2
3
// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
// IT'S ALL JUST JUNK FOR OUR DOCS!
// ++++++++++++++++++++++++++++++++++++++++++

But I discovered that it is not JUST junk, there is a processScroll function that is just what I’m looking for:

Scroll function and handler wiring
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// fix sub nav on scroll
   var $win = $(window)
   , $nav = $('.subnav')
      , navTop = $('.subnav').length && $('.subnav').offset().top - 40
      , isFixed = 0

   processScroll()

   $win.on('scroll', processScroll)

   function processScroll() {
      var i, scrollTop = $win.scrollTop()
      if (scrollTop >= navTop && !isFixed) {
        isFixed = 1
        $nav.addClass('subnav-fixed')
      } else if (scrollTop <= navTop && isFixed) {
        isFixed = 0
        $nav.removeClass('subnav-fixed')
      }
   }

This wires the processScroll() function to the window scroll event and toggles the navigation element based on where it rests relative to the viewport. The idea being to add the ‘subnav-fixed’ CSS class to keep the element within the viewport.

Attached to the body tag was the first bit of markup that I needed to see:

Page Markup
1
<body data-spy="scroll" data-target=".subnav" data-offset="50">

The navigation div tags contained the rest of the information:

Navigation markup
1
2
3
4
5
6
7
<div class="subnav">
      <li><a href="#labels">Labels</a></li>
      <li><a href="#badges">Badges</a></li>
</div>
<!-- along with page sections with matching id values -->
<section id="labels">label information</section>
<section id="badges">badge information</section>

By annotating the body tag with the data- attribute of “data-spy”, identifying sectional elements with id value and including the Scrollspy JavaScript plugin, we are able to synchronize the active menu item with the section that is topmost within the viewport.

Now on my // TODO: list is to trick up the blog template to keep it’s top navigation bar fixed along the top…

Everything Old Is New Again

I spent some time over the weekend dragging along old posts from my tumblr blog that deal with programming. I didn’t bother with the instagram pictures or the four square checkins. After a few failed attempts to get the tumblr posts where the were suposed to be, I opted to stash them in a working directory and move them by hand.

Now all of my <scarcasm>glorious code related posts</sarcasm> are in one place, it’s time to dust up some posts about my shiny new play things Twitter Bootstrasp Octopress and Markdown. Stand by for more intesting things in the very near future.

That Was Easy

Taking the Octopress plunge

Last night I took the plunge and set up octopress to host a blog on github using github pages. The documentation on octopress.org is impeccable. My only hic-up was not fully understanding that I need to run

1
2
rake generate
rake deploy

after committing and pushing from my source branch.

Now to have some fun learning markdown and how to style this so that it doesn’t look like everyone else’s octopress blog

Programming & Barriers to Entry

A fellow learner has posted “Programming & Barriers to Entry”. Cori has much to say in this article concentrated around command line tools, vim and Ruby. I’d like to comment on some of the perceptions and share my own opinions.

Command Line

I picked up on some discord with regard to this type of interaction.

…Intellisense (or lack thereof).  Ctrl-spacebar is my friend. It’s what I’ve grown to love. Typing /?—>enter—>up-arrow—>space—>command-I-really-need is a bit of a PITA. It feels like a clunky waste of time.

Aren’t these the same type of interaction? CTL+Space pops up a list of available commands, arrow up/down to select and hit enter to paste that text into the window. Granted Intellisense is more polished and will show all of the overloads, but I honestly have a difficult time understanding the difference.

Git Immersion was very helpful for ramping up quickly with Git. Git is just a plate full of awesome. I can get tons done with four basic commands after I can Alt+Tab to  my bash shell:

1
2
3
4
5
6
7
git checkout -b working_branch #separates my code from the herd.

git status #to see all of the files that I've modified since my last checkin. 

git add . #readies them to be committed to the local repository.

git commit -m ‘checkin comment’ #stores them away. 

I don’t have to right-click anything! Since I’m working locally, I’m not at the mercy of a flaky connection to a central server. When I want to diff files, that happens locally too.

I’ve got BeyondCompare set up so in the bach shell I can use

1
git difftool 

and then roll through all of the files that I’ve changed and it’s pretty snappy.

1
gitk all

Shows the entire history of the repository

1
gitk filename

Will do the same for a single file.

There is a git gui as well as Tortoise Git to go along with Caleb’s favorite.

VIM

It is a very powerful text editor. It really is language agnostic and enables development in a huge variety of languages. Visual Studio, not so much. I started fooling with VIM when I started doing the Ruby Koans. I stumbled through the help tutorial a few times over several months and got the hang of using VIM for navigating documents with the home row keys and pattern matching searches. I try to use it when I’m not doing .net development, but I’m still staying in the shallow end of the pool. I’m still much more comfortable navigating a C# project with Resharper/CodeRush inside VS than I think I’ll ever be with VIM, but VS has a 10 year head start.

Ruby and Macs

There seems to be a strong correlation between Macs and Ruby developers among Hack Club attendees. Many of the folks who attend do own Macs. Improving Enterprises, my employer and sponsor of many wonderful user groups, has an amazing employee purchase plan for computers and many of the consultants take full advantage of that benefit. Several of the Macs at Hack Club are running Windows 7 in native mode and many more are running Windows 7 via VMWare Fusion of Parallels.

I’d hazard a guess that Greg Vaughn is in the minority and using Ruby in OSX. Amir boots to Windows natively via BootCamp and I believe does all of his Ruby development under Windows. I’ve installed Ruby 1.9 in my VMWare instance and use Growl For Windows and a ruby command prompt for SpecWatchr when I’m deliberately practicing BDD through the beauty of NSpec. Ruby in this group is more about learning something new since most of the crew work in .net for paychecks.