Knockout Binding for Disabling Form Elements

I am falling (hard) in love with KnockoutJS. I am going to start posting little tidbits here.

I am currently working on a search feature that retrieves the search results via an AJAX request. When the user submits the search form, I am providing visual feedback in the form if a "spinner". Additionally, I decided that I would like to disable the form until the AJAX request is complete.

This is very easy to accomplish using a custom binding with Knockout.

Custom Binding

ko.bindingHandlers.disableForm = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        var disabled = ko.utils.unwrapObservable(valueAccessor());
        $(element).find(":input").each(function () {
            var el = $(this);
            if (disabled) {
                el.data("__disabled", el.prop("disabled"));
                el.prop("disabled", true);
            } else {
                el.prop("disabled", el.data("__disabled"));
            }
        })
    }
}

View Model

var searchModel = function() {
  this.results = ko.observableArray();
  this.searching = ko.observable(false);

  this.search = function(form, event) {
    this.searching(true);
    var $form = $(form);
    $.ajax({
      url : $form.attr("action"),
      type: $form.attr("method"),
      data: $form.serialize(),
      dataType: "json"
    }).done(function(json) {
      this.results(json);
    }).always(function(json) {
      this.searching(false);
    });
  }
}

View

<form data-bind="disableForm: searching, submit: search" action="/search" method="get">
  User Email: <input type="text" name="email"><br>
  User Phone: <input type="text" name="phone"><br>
  <button type="submit">Search</button>
</form>

<div data-bind="visible: searching">
  <img src="//nontalk.s3.amazonaws.com/ajax-loader.gif"> Searching...
</div>

<ul data-bind="foreach: results">
  <li data-bind="text: name"></li>
</ul>

How to make Html.ValidationSummary look like Twitter Bootstrap alert blocks

I love using Twitter Bootstrap (.less edition) in my web asp.net mvc web applications. It makes life so much easier.

Today I wanted to find a way to style the output from the Html.ValidationSummary html helper method look like the alerts in Twitter Bootstrap.

Here’s how to do it without modifying the bootstrap source code (found in alerts.less). Just create an additional rule in another .less file and add something like the following.

.validation-summary-errors {
  .alert;
  .alert-error;
  .alert-block;

  & > span:first-child {
    .alert-heading;
    #font > .sans-serif(14px, bold, @baseLineHeight);
  }

  & > p,
  & > ul {
    margin-bottom: 0;
  }
  & p + p {
    margin-top: 5px;
  }
}

File download not working in Google Chrome Frame?

I recently received a bug report that file downloads do not work when using Google Chrome Frame and that it works just fine in all other browsers. I spent a lot of time trying to figure out the problem to no avail.

It turns out that we were sending the wrong MIME type.

Content-Disposition: attachment; filename=MyFile.csv 
Content-Type: text/plain

We should have been sending this.

Content-Disposition: attachment; filename=MyFile.csv 
Content-Type: text/csv