Create Custom KnockoutJS Binding For Enter Key Press

Today I had to add an event to an input box that when the user hits enter on the keyboard, it would call a JavaScript function. However, it’s pretty easy to do with a onkeypress=”” but it still uses a lot of other JavaScript and jQuery. I wanted to do this with using a custom KnockoutJS binding for the enter key so lets take a look at the mark up first.

//Field for typing. enterKey is the name of the custom binding.
<input id="name" data-bind="value: name, enterKey: addName" /> 

//This is the button for if they click instead of enter.
<input id="addName" type="button" data-bind="click: addName" value="Add" /> 

Take notice that in the first line and in the second like they are both pointing to the same function addName. Now lets take a look at the custom binding called enterKey.

// Custom Binding
ko.bindingHandlers.enterKey = {
  init: function (element, valueAccessor, allBindings, data, context) {
    var wrapper = function (data, event) {
      if (event.keyCode === 13) {
        valueAccessor().call(this, data, event);
      }
    };
    ko.applyBindingsToNode(element, { event: { keyup: wrapper } }, context);
  }
};

The cool thing about this customer knockoutjs binding is that you could pass it any function to call. All you would have to do in the markup is data-bind="enterKey: aDifferentFunction" and it would work the same. This obviously works great if you have multiple instances where you would like to check the enter key press and do a certain function without having to do a ton of checking of what’s calling what.

This was answered by Dennis on StackOverflow when I asked how to convert javascript onkeypress to knockoutjs to call on enter.

How to find an element in an observable array in KnockoutJS

How to find an element in an observable array in KnockoutJS is not that hard of a task.  This is assuming that the two items you are comparing are a reference to the same item.  This is more of a custom comparison function to compare a value in an array to some other value.  To complete this we will use the ko.utils.arrayFirst from KnockoutJs.

Take a look at the following Javascript:

var match = ko.utils.arrayFirst(myObservableArray(), function(item) {
    return someValue.name === item.name;
});

Essentially what is happening here is that knockout is combing through the myObservableArray and looking for a match on name. If it finds a match then it returns that object as match. (Just wait, it’ll make sense). If it doesn’t find anything, then match is returned as undefined.

Here is the second part that deals with the match logic:

if (!match) {
  myObservableArray.push(someValue);
}

If match has a value to it and you apply the ! operator the outcome is false.

If match is undefined and you apply the ! operator the outcome is true.

So overall all, if our someValue does not exist in our myObservableArray, then we add it.


Error Messaging Using KnockoutJS Observable Applying CSS

When doing error messages in an application I like to use KnockoutJS Observable to apply a css class to an input box to color it red meaning it’s required. The concept is quite simple really. You have an observable for the field.

self.FirstNameValidation = ko.observable('');

The point is when your validation fails, you add a message to the observable.

if(self.FirstName() == ''){
      self.FirstNameValidation('First Name Is Required');
}

So now that we have our observable set with an error message we can add a data-bind event to the input box to apply a css class to it.

<input id="firstName" data-bind="value: FirstName, css: { 'validationerror': FirstNameValidation() }">

Looking at the example above, the css class ‘validationerror’ will be added to the input box if there is a value in FirstNameValidation(). Simple way to add a visual cue to an input element that something is missing.

KoGrid with KnockoutJS Simple Grid Set Up

Recently we took a look at implementing KoGrid which utilizes KnockoutJS.  This is a brief set up that I go going by pulling a data set from our controller.  First let’s look into the JavaScript and how all this happens.  Let’s look at the document initialization method first.

$(function () {
    var $scvm = new ConfigsViewModel();  //Create New Instance of our ViewModel
    $scvm.LoadConfigurations();  //Calls the load function in our ViewModel
});

This is all pretty straight forward.  So let’s take a bit deeper look into the ConfigsViewModel().  In here we will create our observableArray() and load our data.

var ConfigsViewModel = function () {
var self = this;

    //#region Observables
    self.ConfigurationsMin = ko.observableArray();
    //#endregion

    self.LoadConfigurations = function () {
        $.post("/Config/Search", function (data) {
            var viewModel = {
                ConfigurationsMin: ko.observableArray(JSON.parse(data))
            };

            //Activates knockoutjs so the browser knows what to do with data-bind in markup html.
            ko.applyBindings(viewModel); 
        });
    };
};

Here you can see the LoadConfigurations function that gets call when the dom loads.  Within this function it’s doing an Ajax post which returns a serialized result.


JavaScriptSerializer s = new JavaScriptSerializer();
string json = s.Serialize(results);

return json;

Since we are serializing the results we do a quick JSON.parse which will split the data out into a JSON object that the grid will recognize.  This is all relatively simple and gets a start to pull data back.  Now let’s look at the mark up of the grid.

Here is the whole mark up and we will dig into it.

<div id="table_words" class="someStyles" data-bind="koGrid: { 'data': ConfigurationsMin }">
</div>

There are a few key points for this intro into KoGrid.  First, you can see using the data-bind element we are signaling koGrid which has an element called data.  Here we assign data with the observableArray of ConfigurationsMin.  If you remember, we created and applied our data to this object. ConfigurationsMin: ko.observableArray(data).  This is the bare bones of KoGrid and knockout; but it gets a grid up and running with doing an Ajax call to get some data to populate the grid with.


StackOverflow Profile