Handling input maxlength using knockout

I set out to handle maxlength with the following goals:

  • Set maxlength on an input field. That took about 10 seconds.

This wasn’t sufficient however. It had two problems:

  1. This prevents the UI from going over the maxlength, but not code. I preferred a solution that did both.
  2. Once the maxlength is reached, there is no indication of why the next character typed is ignored. I wanted the textbox to flash red.

So I decided to do the following:

  1. Have knockout handle the max length and not have maxlength in the html.
  2. Have knockout change the css style for 3 seconds.

Knockout allows for something called extenders. I quickly saw extenders as the way to solve my problem. I followed the documentation and modified the example for my needs. I used Plunker to develop this solution and have a working model here:

http://plnkr.co/edit/9SZzcIPUSwWjBttHDQ64

My extender is as follows:

ko.extenders.maxLength = function (target, maxLength) {
    var result = ko.computed({
        read: target,
        write: function (val) {
            if (maxLength > 0) {
                if (val.length > maxLength) {
                    var limitedVal = val.substring(0, maxLength);
                    if (target() === limitedVal) {
                        target.notifySubscribers();
                    }
                    else {
                        target(limitedVal);
                    }
                    result.css("errorborder");
                    setTimeout(function () { result.css(""); }, 500);
                }
                else { target(val); }
            }
            else { target(val); }
        }
    }).extend({ notify: 'always' });
    result.css = ko.observable();
    result(target());
    return result;
};

Now, as you see, I set the css to errorborder, then I remove it 500 milliseconds (1/2 second) later. In order to make this work, I need an errorborder css style. Here is my first quick stab at that.

.errorborder {
  outline: none;
  border: 2px solid red;
}

.errorborder:focus {
  outline: none;
  border: 2px solid red;
  border-color: red;
  box-shadow: 0 0 3px red;
}

The user will see the border of the text box go red for half a second as they try to type more. Having validation text pop-up saying that maxlength has been reached can be done with this as well, but is probably not necessary. This red border should be sufficient visual feedback.

Leave a Reply

How to post code in comments?