Thursday, January 2, 2014

The Module Pattern In Javascript

One of the most widely used patterns in Javascript is the module pattern. The basis of this pattern is the immediate function call (after declaration) encapsulating the variables to it's function scope, so they are hidden from the outside world. The function immediately returns an object, which I like to call the interface of the module. If you are not very familiar with the basic concepts of functional programming, please read this post before going on.
Let's see the basic pattern:
var module = (function myAwesomeModule() {
    var mySecretVariable = 42;
    function mySecretFunction() {
        //something...
    }
    return {
        ifaceFunction: function() {
            //something
        },
        ifaceFunction2: function(input) {
            //something
        }
    };
}());
The properties of the returned interface object can refer to anything but most likely they are functions, which provide limited control over the module. Actually this is one way of communicating with the module, namely we tell what we want from the module through these functions.

The other way of communication is starting from inside the module. This can happen via callback functions which were set previously. You can set them by calling a function on the interface or you can pass them as the parameters of the immediately called function. You can often see the dependencies as parameters. The callback function mentioned before can be considered as a dependency, although it's not forbidden to change it dynamically later. The dependencies are often libraries like jQuery or the window object, etc. It's not only expressive, but it shortens the search in the context chain a little bit for these variables.

One interesting issue about the module pattern is revealing things from inside of it. Usually it's not a good idea to just return something from the module's function scope or pass it as a parameter to a function, because the outside world will have access to the very same things that exist inside the module. To prevent this I usually return or pass a proxy interface object as you can see in the following example:

var editorModule = (function(selectorCb) {
    ...
    element.on("click", function() {
        selectorCb({
            setBgColor: function(color) {
                element.css({"background-color": color});
            },
            setFontColor: function(fontColor) {....}
        });
    });
    ...
    return {
        toJson: function() {...},
        preview: function() {...}
    };
}(selectorCallback));

Assume that element is a jQuery object on the function scope of my module. Every time when someone clicks on the corresponding DOM element, the selectorCb is called. In this example I pass a proxy object as a parameter with two functions: setBgColor and setFontColor. This way I limited the access to the elements inside my module. If I passed element as a parameter, the user of the module could do anything with that jQuery element and that is surely not what I want. Similarly, when an interface function of your module returns something from it's closure, consider returning a proxy object instead.

Using proxy objects with the module pattern gives a great tool to your Javascript toolbox. Use it to produce beautiful, modular code with a nice, controlled way of interaction.

Sunday, December 15, 2013

What Is The Color Of A Border With No Color?

A very surprising bug appeared a few days ago in EDMdesigner. When the border width of an element was set leaving the color transparent, the border color became black. It was very strange, but I did not care that much because I had more serious problems to solve.
The next day, Roland - my co-founder - commented on the issue. When I read his answer, dozens of clouds appeared above my head with the following capital case letters in them: "WTF".

I had to realize that the color of the transparent borders are not necessarily become black. Actually, it always changed to the color of the text that could be set in the general settings part. So when I changed the color of the text in the documents, all the "transparent" borders changed to that color.


During the investigation of this issue, I realized that the program did not set the border-color property of those elements. If there is no inherited border color, then the browser (or at least in the case of Chrome and Firefox) uses the inherited color property. And since we wanted to set the text properties generally for the currently edited e-mail template, a custom style tag was generated on the fly, setting the corresponding css properties. This is the reason why it used the text color, and these are the kind of things why I find css very, very crazy and a little bit confusing.


Have you ever encountered similar things when you could not really believe what you saw at first?

Tuesday, September 24, 2013

Knockout.js - Custom Bindings


Creating custom bindings is one of the best parts of Knockout. It's very, very easy, you just have to add an object to the ko.bindingHandlers object. The name of the property on this object will be the name of the binding. All binding handlers should have two functions: init and update. There are some cases when specifying only one of the functions is sufficient. Both functions get five parameters, of which the first two are the most important. The first is the element on which the binding is applied, and the second is the value accessor function which returns the bound value (sometimes it's a value, sometimes it's an observable). You will probably use these two all the time and the other three very rarely.
The init function is called when the bindings are applied and the update function is called every time when the referred observables are changed and also right after the init function.
Let's see an example:

 <html>  
      <head>  
           <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>  
           <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>  
           <script>  
                ko.bindingHandlers.slideUpDown = {  
                     init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {  
                          var visible = ko.utils.unwrapObservable(valueAccessor());  
                          if (visible) {  
                            $(element).show();  
                       } else {  
                            $(element).hide();  
                       }  
                  },  
                  update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {  
                       var visible = ko.utils.unwrapObservable(valueAccessor());  
                       if (visible) {  
                            $(element).slideDown();  
                       } else {  
                            $(element).slideUp();  
                       }  
                  }  
                };  
                $(document).ready(function() {  
                     ko.applyBindings({  
                          visible: ko.observable(false)  
                     });  
                });  
           </script>  
      </head>  
      <body>  
           <div>  
                <button data-bind="click: visible.bind($data, !visible())">Toggle</button>  
           </div>  
           <div style="width: 500px; height: 300px;">  
                <img style="width: 500px;" data-bind="slideUpDown: visible" src="http://knockoutjs.com/img/ko-logo.png" />  
                <img style="width: 500px;" data-bind="slideUpDown: !visible()" src="http://4.bp.blogspot.com/_Gkxrvtze9SA/S36o6zcsK6I/AAAAAAAAAvs/VmtcRcGhY_E/s320/Knockout+Punch.jpg" />  
           </div>  
      </body>  
 </html>  

In this example I created a binding called slideUpDown by which you can bind a Boolean value or an observable holding a Boolean value to the element. I bound two elements to the visible observable. In the second binding I bound the inverse of the returned value to the element for which I needed to make a function call, since visible is a function. (If I negated a function object, that would always be false.)
If you take a look at the update function inside the binding handler, you can see, that I call ko.utils.unwrapObservable with the value returned by the valueAccessor function. If an observable is passed to the unwrapObservable function, it fetches its value and returns it. If a simple - non-observable - value is passed as a parameter it simply returns it. (From Knockout v2.3.0 you can refer to this function as ko.unwrap as well. Read more about this version and the 3.0 beta in Steve Sanderson's blog.)
If the bound variable is changed to true, then jQuery's slideDown function will be called, otherwise slideUp.
The init function just hides or shows the element based on the bound value. It's necesarry, because in some browsers on some platforms the second image would slide up on page refresh.

Writing your own bindings is a great thing It eases your job quite a lot and your own collection of custom bindings will emerge after a while.
In the comments section, you could share with us the clever bindings you have written or you are planning to write.

Monday, September 23, 2013

Knockout.js - Extenders

One of the great things in Knockout is that you can enhance the functionalities of your observables by using extenders. A good example is when you want to force the observable's value to be an integer between a minimum and maximum value. Validating an e-mail address or an url, or just logging the value changes of the observable are also great examples.
To apply an extender to the observable, you have to use the observable's extend function, which takes an object as an argument. The object's properties will be the extenders that Knockout will look for in the ko.extenders object. If they are found, each of them will be applied to the observable.
Let's see an example:
var myIntegerObservable =
        ko.observable(0).extend({
                integer: {min: 0, max: 10}
        });
The code above means, that I want to apply an extender called integer to the observable, and this extender will get the object with the min and max properties. To create it, I have to set the ko.extenders.integer property to a function which returns an observable. Knockout will pass two parameters to this function. The first is the observable on which the extender is applied and the second is the parameter given to the observable's extend function. In our case it's the object with the min and max properties. An extender which does nothing, looks like this:
ko.extenders.dummyExtender = function(target, options) {
        return target;
};
Now let's see a real-life example, namely the integer extender, which I mentioned above:

 <html>  
      <head>  
           <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>  
           <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>  
           <script>  
                ko.extenders.integer = function(target, options) {  
                     var result = ko.computed({  
                          read: target,  
                          write: function(newValue) {  
                               var currentValue     = target()  
                               ,     newValueAsInt     = 0  
                               ;  
                               if (!isNaN(newValue)) {  
                                    try {  
                                         newValueAsInt = parseInt(newValue);  
                                    } catch (e) {  
                                         //do nothing, 0 is a good value in this case.  
                                    }  
                               }  
                               if (typeof options.min === "number" && newValueAsInt < options.min) {  
                                    newValueAsInt = options.min;  
                      } else if (typeof options.max === "number" && newValueAsInt > options.max) {  
                           newValueAsInt = options.max;  
                      }  
                      //only write if it changed  
                      if (newValueAsInt !== currentValue) {  
                        target(newValueAsInt);  
                      }  
                          }  
                     });       
                     //initialize with current value to make sure it is rounded appropriately  
                  result(target());  
                  result.incr = function incrNumeric(viewModel, event) {  
                       event.stopPropagation();  
                       var res = result();  
                       try {  
                            res = parseInt(res);  
                            result(res + 1);  
                       } catch (e) {  
                            result(0);  
                       }  
                  };  
                  result.decr = function decrNumeric(viewModel, event) {  
                       event.stopPropagation();  
                       var res = result();  
                       try {  
                            res = parseInt(res);  
                            result(res - 1);  
                       } catch (e) {  
                            result(0);  
                       }  
                  };  
                  //return the new computed observable  
                  return result;  
                };  
                $(document).ready(function() {  
                     ko.applyBindings({  
                          myNumber: ko.observable(0).extend({integer: {min: 0, max: 10}})  
                     });  
                });  
           </script>  
      </head>  
      <body>  
           <div data-bind="text: myNumber"></div>  
           <button data-bind="click: myNumber.decr">-</button>  
           <input data-bind="value: myNumber" />  
           <button data-bind="click: myNumber.incr">+</button>  
      </body>  
 </html>  

The integer extender above returns a writable computed - I stole this idea from knockoutjs.com - with a custom write method. The read method just returns what the original observable would return. The custom write method parses its input as an integer, forces this integer to be in the interval given by the options object's min and max properties. In addition it adds an incrementor and a decrementor function to the observable (incr and decr properties). This is totally valid, since functions are first-class citizens in Javascript. If you don't know much about functional programming, I recommend to read my post about functional Javascript.

In my previous post I mentioned, that if a computed's value depends on more than one observables and these observables values are updated (and changed) one after the other, then the evaluator function of the computed will be called multiple times. To avoid this, you can use the throttle extender, which delays the re-evaluation by a given number of milliseconds. If you do something similar to the following example, the evaluation will happen only once, even if multiple referred observables change:
ko.computed(function() {
        //fetching the value of lots of observables...
}).extend({throttle: 1});
Creating your own extenders is very useful, and helps you to organize your code better. The next post will be about an other way of extending the framework by writing your own custom bindings.

Friday, September 20, 2013

Knockout.js - Writable Computeds

In my first post about Knockout I wrote a few words about computeds. You can pass a function as the first parameter of their creator functions, which will always be invoked when one of the referred observables changes. Actually it's because computeds are subscribed to those variables and thus they are notified about the changes. This way it's only a one-way transformation, but luckily you can define the inverse transformation as well, by passing an object - instead of the function - as the first parameter with two properties: read and write. The function behind the write property will be responsible for the inverse transformation.

 <html>  
      <head>  
           <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>  
           <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>  
           <script>  
                $(document).ready(function() {  
                     var firstName = ko.observable("");  
                     var lastName = ko.observable("");  
                     var fullName = ko.computed({  
                          read: function() {  
                               var first = firstName();  
                               var last = lastName();  
                               if (last !== "") {  
                                    return first + " " + last;  
                               }  
                               return first;  
                          },  
                          write: function(val) {  
                               var arr = val.trim().split(" ");  
                               firstName(arr[0]);  
                               if (arr.length > 1) {  
                                    lastName(arr[1]);  
                               } else {  
                                    lastName("");  
                               }  
                          }  
                     });  
                     var vm = {  
                          firstName: firstName,  
                          lastName: lastName,  
                          fullName: fullName  
                     };  
                     ko.applyBindings(vm);  
                });  
           </script>  
      </head>  
      <body>  
           <div>FirstName: <span data-bind="text: firstName"></span></div>  
           <div>LastName: <span data-bind="text: lastName"></span></div>  
           <input data-bind="value: fullName, valueUpdate: 'afterkeydown'" />  
      </body>  
 </html>  

In the example above, the computed is bound to one input field's value. Since the update of the value happens after every keydown, the write function of the observable will be called each time you press a key and the focus is on the input field. The write function splits the input string into an array of strings, using the space character as separator and puts the first two values - if present - into the other two observables. If multiple referred observables change, then the read function will be called more than once, and such wasteful behavior should be avoided of course. I will introduce a solution for this problem in my next post.

Thursday, September 19, 2013

Knockout.js - Observable Arrays

In my last post I wrote about observables, computeds and the basic concepts of Knockout. The third main observable type is the observableArray.

Source: knockoutjs.com

Observable array is an extended version of observable. You can pass an initial array to the creator function, which will hide it into the function scope of the observable. A very neat thing in observable arrays is, that they have the usual array (or list) specific functions like push, pop, splice, indexOf, etc... Let's see an example of initializing an observable array and binding it to our view:
ko.applyBindings({
    list: ko.observableArray(["I", "am", "the", "reincarnation", "of", "Jimmi", "Hendrix."])
});
And an example view of the view model above:
<ul data-bind="foreach: list">
    <li data-bind="text: $data"></li>
</ul>
In this view we use the foreach binding to apply the part inside the element containing the foreach binding to every element of the observable array. It's posibble to apply the foreach binding to a simple array, but of course that view won't refresh if something is changed in the array behind (e.g. a new element is pushed into it).
Inside the foreach we refer to the actual element with $data. If you have objects in your array, then you don't have to use $data, it's enough to use the name of the property that you want to bind the value of to the element on the view. Observable arrays are useful only if you manipulate them, so let's see an example where you can add new elements to one.

 <html>  
      <head>  
           <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>  
           <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>  
           <script>  
                $(document).ready(function() {  
                function stringListVM() {  
                     var list = ko.observableArray(["I", "am", "the", "reincarnation", "of", "Jimmi", "Hendrix", "."]);  
                     var newElem = ko.observable("");  
                     var allowAdd = ko.computed(function() {  
                          return newElem() !== "";  
                     });  
                     function add() {  
                          if (allowAdd()) {  
                               list.push(newElem());  
                               newElem("");  
                          }  
                     }  
                     add.allow = allowAdd;  
                     return {  
                          list: list,  
                          newElem: newElem,  
                          add: add  
                     };  
                }  
                var vm = stringListVM();  
                ko.applyBindings(vm);  
                });  
           </script>  
      </head>  
      <body>  
           <ul data-bind="foreach: list">  
                <li data-bind="text: $data"></li>  
           </ul>  
           <input data-bind="value: newElem, valueUpdate: 'afterkeydown'" />  
           <button data-bind="click: add, enable: add.allow">Add</button>  
      </body>  
 </html>  

In the example above I'm using a separate observable (newElem) to store the new element's value. As you can see it can be bound to the value of an input element and in my example the value is updated after each keydown.
If you click on the add button, then the add function is invoked and inserts the value of the observable into the observable array, if it's not an empty string. This is decided via getting the latest value of the allowAdd computed.
I also refer to this computed by the allow property of the add function, through which the add button can be enabled or disabled via the enable binding. I find this way of constructing view models very handy and self-explanatory.

Removing items from observable arrays is also very frequent. You can use the remove function for that. I find that function extremely useful, because it's possible to pass a predicate or a value to it and the appropriate elements will be removed.

You can find the enhanced example to demonstrate the remove function on GitHub. The only difference between that and the previous example is that there is a removeElem function on the view model. It looks like this:
function deleteElem(elem) {
    list.remove(elem);
}
And I put a click binding to the li elements inside the foreach binding:
<li data-bind="text: $data, click: $parent.deleteElem"></li>
Inside the foreach binding, $data always refers to the actual element, so if we want to refer to something in the parent context, we have to use $parent. The deleteElement function gets the actual element as its first parameter. Binding context is a very important topic, you can read more about that here.

Wednesday, September 18, 2013

Knockout.js - Observables and Computeds

Yesterday I presented on a meetup about Knockout which is an MVVM library written in Javascript. I'll try to write my posts about this library based on the feedbacks I got after the presentation, hopefully making everything clear to the reader.



With Knockout it's very easy to totally separate the UI (the views) and the presentation logic (the view models). View models are actually models of the views. For example if you have a Boolean variable in your view model called visible, which probably encodes whether some part of the UI is visible if its value is true, BUT it says nothing about the state transition, namely when the value changes from true to false or vice versa. The simplest case is obviously when the referred part of the UI just disappears but it could slide up or fade out as well. These things are coded in the view via data-bindings. The view models are introducing a new abstraction layer, where the small details, like how things disappear really do not matter. Knockout does not deal with the model, the communication and modification can be implemented in the way you like. (And it's not necessarily stored in some remote DB, for example it can be the LocalStorage as well.)

I created a repo called knockout-playground on GitHub, I put some example code there, and will put the new examples there later, so you can play around with them easily. In this post I cover the first example and will write about the remaining examples in the subsequent posts.

The frame of my examples in the simple_examples folder is the following:
<html>
    <head>
        <script src="http://code.jquery.com/jquery-1.10.1.min.js">
        </script>
        <script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js">
        </script>
        <script>
            $(document).ready(function() {
            });
        </script>
    </head>
    <body>
    </body>
</html>
When I'm talk about the Javascript part, imagine it in the callback above, and when I'm talking about the HTML and data-binding, then that's of course in the body of this frame.

In Knockout you can find everything in the object called ko. Any object with properties can be a view model. The root view model will be the one which is passed to the applyBindings function as a parameter:
var vm = {
  testVar1: "This is a string",
  testVar2: 42
};
ko.applyBindings(vm);
After this you can bind things in your HTML to the properties of the view model:
<div data-bind="text: testVar1"></div>
<input data-bind="value: testVar1" />
<div data-bind="text: testVar2"></div>
<input data-bind="value: testVar2" />

In the example above I used text and value binding. The text binding puts the binded variables value to into the element as text, the value binding sets it as the value attribute. One of the great thing about Knockout is that there are 2-way bindings if you use observables. This means if you change something on one of the views, it changes the values in the view model behind it and every view will be notified about the change. Thus it implements the observer pattern this way. After you put your values into observables in your view model and the user changes something in the input fields (and presses enter) the other parts of the view binded to that variable, will be updated automatically:
var vm = {
  testVar1: ko.observable("This is a string"),
  testVar2: ko.observable(42)
};
ko.applyBindings(vm);
As you can see, the creator function of observables is on the ko object as well. You can pass a parameter to it which will be the initial value of the observable. This creator function returns a function - that is your observable - and the value of the observable is hidden inside the function scope of the observable. If you want to fetch the value, you have to call your observable without parameters, and if you want to set the value, you have to pass a parameter to this function.

In this example, if you type something into the input fields, you have to press enter to update the value of the observable. Sometimes you might want it to be updated after each keydown. You can do it in this way:
<input data-bind="value: testVar1, valueUpdate: 'afterkeydown'" />
There are lot of cases when you have to create some new values based on one or more other variables (observables). In Knockout you can do it via computeds, these are actually observables and their value is computed by a callback specified by the programmer. It invokes the given callback function when you initialize the computed and every time when a referred observable's value is changed. It stores the computed value in it's function scope, so when you fetch it, it just returns this value.
function testVM() {
  var firstName = ko.observable("");
  var lastName = ko.observable("");
  var fullName = ko.computed(function() {
    return firstName() + " " + lastName();
  });
  return {
    firstName: firstName,
    lastName: lastName,
    fullName: fullName
  };
}
ko.applyBindings(testVM());
Here, the fullName is computed concatenating the other two observables' value with a space between them. From now on, you can bind this on your view as well:
<div data-bind="text: firstName"></div>
<div data-bind="text: lastName"></div>
<div data-bind="text: fullName"></div>
<input data-bind="value: firstName" />
<input data-bind="value: lastName, valueUpdate: 'afterkeydown'" />
You can find this example on GitHub. Feel free to play around, and drop me a mail or comment if you have questions. In the next post I will write about the second example, that's about observable arrays.

Share It