MongoDB Contacts Demo App

I haven’t posted in a while. Work stuff hasn’t really been post-worthy, so I was struggling to find something to post about. I realized I had an old demo I whipped up that I had never posted about, so here goes…

I wanted to play around with Mongo, and I also wanted to play around with AppHarbor, so I thought I’d make a Mongo app I could push to AppHarbor. To keep it simple, I decided to make a contacts app – you know, something super useful.

App
http://mongocontacts.apphb.com/

Code
https://github.com/timhobbs/MongoContacts

It is pretty straight-forward. Check the “about” link in the app for some more details. You can play around with the demo app, but please try to keep things PG. I know, I know…

AngularJS form serialization

I have been playing around with AngularJS, and I am falling in love! We use KnockoutJS pretty extensively in our site, and while I do like KO, I think it is better suited for small enhancements rather than larger things like we do: cart management and a ship estimator, a pretty advanced checkout page, and a school address picker. These all work okay with KO, and honestly, they would probably work much better if they were designed better. Unfortunately this work was initially farmed out to some overseas contractors, and they seem to believe in the anti-KISS pattern, if that even exists…

To begin with, I started on some demos to focus on each task. I created a small ship estimator demo, then I made a small cart demo. Again, due to a really poor design, the ship estimator (which should be the easiest thing with a whopping 3 form fields) is the worse of the 2 in the current implementation. To be fair to KO, I think if the redesign I used for the demo were what we used in our live site, KO would suffice. That being said, Angular just provides more – it is a framework after all, while KO is just a library.

The latest demo is an address form with a school picker – you enter the zip code and a list of matching schools for the zip are displayed in a select list. Once a selection is made, the form fields are populated with the school address details and the fields are set to readonly.

This all works fine, but my co-worker asked if we could then submit the form via a normal HTML form submission. That got me to wondering, so I asked Google. I found a great post on the NG Google Group. The suggestion was to use hidden inputs to store values, and offered a couple ways to do so:

A) (This)

<input type="hidden" name="someName" value="someVal">

becomes

<input type="hidden" ng-init="someName = 'someVal'" 
    name="someName" value="{someName}}">

This first option … gives you the benefit of having the value in the scope and on the hidden element constantly synchronized.

B) Write a directive for hidden input types that picks up the name and value and inserts it into the scope. This is not too hard:

app.directive('input', function() {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      if ( attrs.type === 'hidden' ) {
        scope[attrs.name] = attrs.value;
      }
    }
  };
});

This second option is nice but it won’t allow you to update the hidden field’s value if you plan to do a pure HTML form submission later (although with a little thought and $watch you could probably wire this up).

In our demo code, my co-worker and I opted for the first approach. It winds up being a bit more verbose, but it isn’t too much extra leg work and works well with the 2-way binding to keep the form values up to date.

CSS shorthand

Dustin Diaz has put together a nice guide to CSS shorthand. My personal favorite:

element {
  background: #fff url(image.png) no-repeat 20px 100px fixed;
}

Another favorite of mine is shorthand for margin/padding. I always remember the order by thinking of a clockface, but I also recently saw someone recommend “TRouBLe” (top, right, bottom, left). That may work, but I prefer the clockface (especially since that is what I have always used!)

Execute powershell script as a scheduled task

I have a little cleanup function that runs on a website that I can trigger by hitting a URL. I wanted to run that as a task, so I googled how to create the powershell script and how to setup that script to run as a task. Here are the findings:

The powershell script

$webClient = new-object System.Net.WebClient
$webClient.Headers.Add("user-agent", "PowerShell Script")
$webClient.DownloadString("http://www.website.com/")

From Otto Helweg

Setting up the task

In the Program/script, put:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

In the Add arguments (optional):
-noninteractive -nologo c:\pathtofile\powershellscript.ps1

From TechNet

CSS3 animation for Bootstrap icons

I found this great post on Elijah Manor’s blog where he animated the refresh icon. I don’t use Bootstrap on my site, but I did have the need for a refresh icon for an older post, and this would have been pretty cool. If only I had been smart enough to think of it. DOH!

If you want to skip all the specifics and just get to the payoff, here is the jsfiddle with the working animation:

ConvertCsvToList

I create a gist for a helper funtion I used recently to convert a CSV file’s contents to a typed list:

private IList<T> ConvertCsvToList<T>(IList<string> csv, string[] header) {
    var list = new List<T>();
    foreach (var row in csv) {
        var columns = row.Split(',');
        T obj = (T)Activator.CreateInstance(typeof(T));
 
        for (int i = 0; i < columns.Length; i++) {
            var h = Regex.Match(header[i].Replace("@", "_"), 
                @"(?<="")(?:\\.|[^""\\])*(?="")").Value;
            var c = Regex.Match(columns[i], 
                @"(?<="")(?:\\.|[^""\\])*(?="")").Value;
            var prop = typeof(Em.Schools.Data.Domain.Match).GetProperty(h);
            if (prop.PropertyType == typeof(int)) {
                prop.SetValue(obj, Convert.ToInt32(c), null);
            } else {
                prop.SetValue(obj, c, null);
            }
        }
 
        list.Add(obj);
    }
 
    return list;
}

Massive and multiple arguments

I thought that Massive would simple let me do something like this:

table.Delete(where: "Pin_Added = @0 and Pin_Schools <> @1", 
             args: new { pinAdded, pinSelected });

That would be slick! But I get something more like this:

lettering-kaboom

It turns out that that fancy anonymous object doesn’t get parsed. I tried to grab some of the fancy tricks from the MVC source code, like this:

RouteValueDictionary result = new RouteValueDictionary();

if (htmlAttributes != null) {
    foreach (PropertyDescriptor property in 
    			TypeDescriptor.GetProperties(htmlAttributes)) {
        result.Add(property.Name.Replace('_', '-'), 
        		property.GetValue(htmlAttributes));
    }
}

return result;

But that did not work. I found this post on DataChomp that solved my woes:

object[] args = { pinAdded, pinSelected };
table.Delete(where: "Pin_Added = @0 and Pin_Schools <> @1", args: args);

Horizontal Rule using CSS3 Gradient

I love all the little tricks you can perform with CSS 3. I saw this nice horizontal rule on MLSsoccer.com:

mls

The CSS is pretty simple:

hr {
	background: #ababab;
	background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/
		Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9Ij
		EwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3Bl
		Y3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2
		VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5
		MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3
		RvcC1jb2xvcj0iI2ZmZmZmZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBv
		ZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iI2FiYWJhYiIgc3RvcC1vcGFjaXR5PSIxIi
		8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmZmZmYiIHN0
		b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMC
		IgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ct
		Z2VuZXJhdGVkKSIgLz4KPC9zdmc+);
	background: -moz-linear-gradient(left,#ffffff 0%,#ababab 50%,#ffffff 100%);
	background: -webkit-gradient(linear,left top,right top,
		color-stop(0%,#ffffff),color-stop(50%,#ababab),color-stop(100%,#ffffff));
	background: -webkit-linear-gradient(left,#ffffff 0%,#ababab 50%,#ffffff 100%);
	background: -o-linear-gradient(left,#ffffff 0%,#ababab 50%,#ffffff 100%);
	background: -ms-linear-gradient(left,#ffffff 0%,#ababab 50%,#ffffff 100%);
	background: linear-gradient(to right,#ffffff 0%,#ababab 50%,#ffffff 100%);
	filter: progid:DXImageTransform.Microsoft.gradient(
		startColorstr='#ffffff',endColorstr='#ffffff',GradientType=1);
	margin: 20px 0;
}

You can just swap the #ababab color for whatever color you’d like to change the gray, but of course that would not change out the encoded image. Personally, I would just get rid of the embedded image and let browsers that don’t support CSS gradients to use the fallback solid color.

OMGWTFIIS?!?!

scream and shout

I am working on some automation to allow a large zip file to be uploaded, extracted, parsed, etc. While working locally, things worked fine. Once I pushed to our dev server, it all fell apart.

The file is 30MB – I did not really think that was too large, but apparently there is a nice, hidden gem in IIS – an artificial limit of 30MB. It was driving me nuts because I could upload a bunch of other zip files, but not the one I needed to. That led me to think it had something to do with the size, and lo and behold that is it.

I found the magic google incantation to find a post on IIS7 file upload size limits. This post gives a great overview about the silliness that exists, and a nice site-level solution:

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="524288000"/>
    </requestFiltering>
  </security>
</system.webServer>

A commenter outlines a solution using the IIS7 snap-in, but I am okay with the web.config method. For completeness, here are the steps:

  1. Open IIS7 snap-in
  2. Select the site to enable large file uploads
  3. Double click “Request Filtering” in the main window
  4. Right-click the dialog window and select “Edit Feature Settings”
  5. Modify the “Maximum allowed content length (bytes)

So, at least I got everything working, but I sure wasted a whole bunch of my time before I found this…

photo by: mdanys

EF and “dynamic” data

We use EF for our e-commerce website, and we have the need to get some data out in the form of reports. Ideally I’d like to be able to basically write up a report query and have the data come out on the other side. However, with EF it isn’t necessarily that simple.

I really don’t want to have to go through all the ceremony of creating models, mapping classes, services, etc. I’d like to keep it pretty simple with a service that can give me back the data I want, then I can use it in a Google Chart or a jQuery datatable or something on the client side. I want the server-side to be basic, and then I can focus on the client-side to give a rich report experience.

I did a quick search and came up with a couple of interesting options. The first is a way to dynamically query views. It sounds very interesting, but it looks like it isn’t quite what I am looking for. The post leaves things a little open-ended, but it looks like the views he is querying already have all the strongly-typed stuff needed and the code just performs dynamic queries against those static objects. I could be wrong though as there is not concrete example of how it is used, just the theory behind all the dynamic wackiness going on.

The next option looks a little more like what I am looking for – it returns a dynamic object using SqlQuery. The code in the post is a little verbose for my taste, but a commenter converted the code into an extension, and I like that idea a lot better. I put his code into a gist.

After looking into the options, I think that maybe the notion that I have to stick with EF is just holding me back. I am very familiar with Massive and have used it and enjoy using it. It is a single class file, and maybe it is just the thing I need to get this report data out of my database easily – which is the idea behind Massive!