Knockout Repeat plug-in

I had a request to display the newest items added at the top of the table, but in the data storage, the newest items needed to be added at the bottom. The built-in foreach binding in knockout does not have an order option. It always traverses the observable array from 0 to the last item. So, I needed to figure out another option for building the table. One option, using only built-in knockout functionality, was to create a second array and using the reverse function on the array to recreate the second array whenever the first array was updated. I just saw too many possible problems with that and, having 2 copies of data, they were liable to get out of sync.

I searched for options on Stackoverflow and found a Repeat plug-in that had been created by Michael Best. It works similar to foreach, but it does have a reverse option which would do what I need. There are some differences in how they work. The main difference is the context that has scope within the loop. In “foreach”, the context changes to the observable array. So, if I specified “foreach: payments”, within the loop, I would just use “amount”. While using the repeat binding, the context stays with the original parent object. So, if I specified “repeat: {foreach:payments, reverse:true}”, within the loop, I would use “$item().amount” to access properties of the object stored in the observable array.

The differences are very minor, but the functionality provided is quite beneficial. This is a plug-in I highly recommend.

Have a Happy Thanksgiving.

Knockout.js Select bindings

Knockout.js is versatile in how you can bind to HTML SELECT inputs. Most of the examples show bindings to simple arrays, but there is a lot more functionality available. The tricky part is knowing where to look. You might think to look for a select binding, but you actually want to look at the documentation for the options binding.

Let me show you an example. Instead of having a simple array of single values to bind to, you want to have an array of objects.

var invlist = [{"id":"PGT_MUM-A","desc":"Decorative pot red mum","combodesc":"A - Decorative pot red mum","price":"25.00","altid":"A"},
{"id":"PGT_MUM-B","desc":"Refill pot red mum","combodesc":"B - Refill pot red mum","price":"20.00","altid":"B"},
{"id":"PGT_MUM-C","desc":"Decorative pot white mum","combodesc":"C - Decorative pot white mum","price":"25.00","altid":"C"},
{"id":"PGT_MUM-D","desc":"Refill pot white mum","combodesc":"D - Refill pot white mum","price":"20.00","altid":"D"}];

In this example, we have inventory items that have an id, description, price and some additional fields. Here is the way the HTML SELECT would look:

<select id="zSaleItem" data-bind="value:currItem, options:invlist, optionsValue:'id', optionsText:'combodesc', optionsCaption:'Item Number'"></select>

In the data-bind, we still specify the value which ties to the field in the viewmodel that this input field is bound to. The rest of the data-binding creates all of the options to be in the select. The first field is “options” which links the array holding all the options to be used to populate the select. In this example, it is “invlist” which is the sample array shown above. The next field is “optionsValue”. This tells the binding what property of the object in the array to place in the value mapped to the viewmodel after a selection is made. “optionsText” specifies the property to be displayed as the text value of the option in the select. When there is not a value selected, you use “optionsCaption” to specify what to display. In this case, it is “Item Number”. Other examples could be “Choose”, “Select”, etc.

I have found this gives a lot of flexibility in defining how you want the SELECT to display and function.

Random Thoughts

Some random thoughts for now. I am going to try and start posting regularly. I have added a calendar reminder to make sure I don’t get busy and forget.

I recently opened a Bitbucket account. I chose Bitbucket over Github because Bitbucket will give you private repos as part of the free plan. I have started integrating it with my daily workflow and it is easier and less intrusive than I thought. I also started using Source Tree, which is a free Git client from Atlassian. That may be why using Bitbucket has been so easy. Atlassian also has a set of Git tutorials that helped with the learning process.

I am still using Knockout.js for some work projects. I enjoy using it. The 2-way data binding really makes things simple to work with. One update that I made in 15 minutes would have taken about 2-3 hours if everything was coded by hand. The documentation has been helpful and anything I haven’t found in the documentation I have been able to figure out with help from Stack Overflow.