Site Meter
 
 

Introducing Knockout, a UI library for JavaScript

Knockout is a JavaScript library that makes it easier to create rich, desktop-like user interfaces with JavaScript and HTML, using observers to make your UI automatically stay in sync with an underlying data model. It works particularly well with the MVVM pattern, offering declarative bindings somewhat like Silverlight but without the browser plugin.

So, what distinguishes this from all the other similar-sounding JavaScript libraries? (I blogged about an MVC/templating system for JavaScript back in 2007, Microsoft has suggested a data linking system for jQuery, and Google’s full of MVC-on-the-client toolkits.)

Well, Knockout combines some different ideas that open up very powerful possibilities:

  • Automatic dependency tracking: At the heart of Knockout is a system of observable variables and other variables computed as functions of them. For example, if you have firstName and lastName and then define fullName by concatenating these together, the framework knows that whenever either firstName or lastName changes, it must re-evaluate fullName. You don’t have to configure this – it’s inferred from your code execution, even if you have chains of observables referencing other observables.
    This makes it easy to build sophisticated view models in which changes to a few key properties automatically ripple out to all other affected parts of the model.
  • Declarative bindings: By adding a data-* attribute (part of the HTML 5 spec, and works fine in older browsers, including IE 6) you can quickly bind appearance and behaviour in your HTML to properties on a view model. For example, you can write <span data-bind="text: fullName"></span>, and then the element will display the value in your model property as text, automatically updating if any of the underlying data changes. Besides text, I’ve included a range of commonly useful declarative bindings (e.g., visible, click, and css), and you can easily plug in custom ones.
  • Nested templates: When you have a rich structure of view model data to display, it makes sense to display it using a template to keep your code simple. Knockout handles this easily by letting you bind a DOM node to a template and some data. Whenever either changes, the template gets re-rendered and your UI is updated. You can use data-bind attributes from inside templates (referencing any variable in scope at that point during template execution, such as foreach loop variables) to concisely add further interactivity. Plus, you can bind to templates from within templates, creating chains of nested templates. Because of how dependency tracking works, if the underlying data changes, Knockout knows it only needs to re-render the innermost templates affected by the change, so it’s efficient. Knockout uses the jquery-tmpl template engine by default, but you can plug in another template engine if you prefer some other template syntax.

These features together, combined with following the MVVM design pattern, mean you can apply sophisticated UI behaviours in a clean, concise, and organized way. It’s also possible to combine custom bindings and templates to create reusable controls (or plugins).

Extremely Trivial Example

OK, code. You could set up a view model as follows:

<script type="text/javascript">
    var myViewModel = {
        personName : ko.observable("Bert") // Initial state
    };
</script>

Then, you could bind it to an HTML UI as follows:

Enter your name:
<input id="source" data-bind="value: personName, valueUpdate: 'keyup'" />
 
<div data-bind="visible: personName().length > 5">
    Wow, what a long name you have.
</div>

Now, the text box will take its value from personName, and will automatically update its value whenever personName changes. The binding is two-way, so when you type into the text box, this updates personName.

The DIV with the “what a long name” message will be made visible whenever the name length exceeds 5 characters, and hidden otherwise. By referencing an observable value in a binding, you’ve implicitly set up notifications.

But I can just do that with jQuery!

Yes, we all love jQuery! It’s a fantastic replacement for the hideous DOM API we had to work with before.

The point of Knockout is not to replace jQuery – I expect most people who use Knockout will use jQuery too. The point is to make it easy to have one coherent underlying data model and then bind your UI to that. Change the data model and the UI changes, and vice-versa. That way, you don’t get complicated event handlers that have to update loads of different parts of the DOM to keep the UI up-to-date; instead, when you just change the underlying data model, you know all the affected UI gets updated. This also makes client-server interactions much easier: when saving data, you don’t have to try to scrape the current state off a load of DOM elements – you’ve already got it in a clean model. Likewise when loading data from the server and wanting to update the DOM to match – just push it into the data model and the UI is updated. It’s the MVVM pattern, much beloved of Silverlight developers.

A More Detailed Tutorial

Right, getting beyond “hello world” but still keeping things simple, let’s make a simple list editor. This will demonstrate some of Knockout’s core features – observables and bindings (though we’ll ignore templating for now – you can learn about that from other examples).

To get started, create an HTML file that references knockout.js or knockout-min.js and define a simple view model class. In JavaScript, any function can act as a class constructor. The following one has a single property which represents the items in a list.

<html>
<head>
    <script type="text/javascript" src="knockout.js"></script>
</head>
<body>
    <script type="text/javascript">
        var listEditorViewModel = function () {
            // ko.observableArray lets you track changes to a collection of things
            this.allItems = ko.observableArray(["Apple", "Banana", "Cherry"]);
        };
    </script>
</body>
</html>

Next, let’s display the list on the screen. You can do that by creating an HTML <select> element and binding its contents to a model property using Knockout’s options binding:

<div>List items:</div>
<select multiple="multiple" data-bind="options: allItems"></select>
<script type="text/javascript">
    var listEditorViewModel = function () {
        ... as before ...
    };
 
    ko.applyBindings(document.body, new listEditorViewModel());
</script>

If you open this in a browser, you’ll see the list items:

image1 

What about letting the user add some more items to the list? Update the view model class so that it has another property for tracking the new item a user is adding, and add a method that pushes the new item into the array:

var listEditorViewModel = function () {
    // ko.observableArray lets you track changes to a collection of things
    this.allItems = ko.observableArray(["Apple", "Banana", "Cherry"]);
 
    // ko.observable tracks a single item. The initial state here is an empty string.
    this.itemToAdd = ko.observable("");
 
    this.addItem = function () {
        this.allItems.push(this.itemToAdd());
        this.itemToAdd(""); // After adding an item, reset itemToAdd to an empty string
    }
};

Next we need to add some UI elements and bind them to these new model members.

<form data-bind="submit: addItem">
    Add item:
    <input data-bind="value: itemToAdd" />
    <button type="submit">Add</button>
</form>

That will do it! Now when the user edits the text box, its value automatically goes into the itemToAdd observable because of the value binding. When they submit the form, this invokes addItem() because of the submit binding. In turn, this updates allItems in the view model, and this automatically causes the on-screen list to be updated because its collection of options is bound to that model property. With Knockout, you don’t have to remember which parts of the UI to update following an event – you just change properties on the underlying view model, and anything bound to those properties will be notified and updated.

image2

Next thing, we might want to let the user remove items. We should let them select multiple items at once, then have a “remove” button that removes them all. First, we need to know what the user has got selected, so add a new view model property to represent selection, and bind it to the HTML element using Knockout’s selectedOptions binding.

<select multiple data-bind="options: allItems, selectedOptions: selectedItems"></select>
var listEditorViewModel = function () {
    // ... leave the rest as before ...
    this.selectedItems = ko.observableArray([]); // Initially select nothing
};

Now you can read selectedItems to see what items are selected, and if you write a value to that observable, it will change what’s selected in the UI.

To let the user remove their selected items, add a button and bind clicks on it to a method on the view model:

<button data-bind="click: removeSelected">
    Remove selected items
</button>
var listEditorViewModel = function () {
    // ... leave the rest as before ...
 
    this.removeSelected = function () {
        this.allItems.removeAll(this.selectedItems());
        this.selectedItems([]); // Reset selection to an empty set
    }
};

That’s great – now the user can remove one or more items from the list. But it doesn’t make sense for them to click “Remove selected items” if they haven’t got anything selected. Let’s make the button enabled only when at least one item is selected:

<button data-bind="click: removeSelected, enable: selectedItems().length > 0">
    Remove selected items
</button>

Easy! You can use arbitrary JavaScript expressions in bindings. If your bindings reference one or more observables, they’ll be re-evaluated automatically any time those observables change. So now the “Remove” button becomes enabled or disabled depending on whether anything is selected.

image3

What if you wanted to let the user sort the items into alphabetical order? Again, you could do this by adding a method to the view model and binding a new button to that method. Alternatively – just to show you that you can use function literals in bindings – here’s a standalone way to do it:

<button data-bind="click: function() { allItems.sort() }, enable: allItems().length > 1">
    Sort
</button>

I’ve made this button enable only when there are at least two items (it’s pointless to “sort” a single item). Notice that selection is retained, because we didn’t change selectedItems.

image4

That’s a fair bit of functionality in just a few lines of code. As I explained earlier, the benefit of Knockout and the MVVM pattern is that it scales very well in complexity – you don’t have to track how one part of the UI affects another; you just manipulate your view model and all affected parts of the UI change on their own. For example, in the preceding tutorial, removing items can make the ‘Sort’ button become disabled, but we didn’t have to write any explicit code in a ‘Remove’ click handler to make that happen.

To build on this knowledge, see the online demos of other examples (arranged in order of increasing sophistication) and look at their HTML source code to see how it’s done.

Requirements, Licensing, and Browser Support

Knockout is written in pure JavaScript, so it has no server-side requirements at all. Your web application can be written in ASP.NET MVC, PHP, Ruby on Rails – whatever.

The core of Knockout doesn’t depend on any other JavaScript library. However, the default template engine, jquery-tmpl, obviously depends on jQuery. If you don’t like that you can plug in another template engine, but I expect most people will be using jQuery anyway.

Regarding browser support, I’ve designed and tested it to work with IE 6 – 8, Firefox 2 – 3.6, and current versions of Chrome, Safari (verified on Windows and iPhone), and Opera. I fully expect it to work with older versions of Chrome, Safari, and Opera, but haven’t tried it – there’s only so much browser installation one person can bear… There’s a good set of automated specifications (BDD-style, written using JSSpec) so you can run these on any browser/platform to get a good sense of what features are working. Hopefully all of them :)

I’m releasing this project under the Ms-Pl license (an OSI-approved license). Some of my other code is licensed in the same way, so this keeps things simple for me, and it means you can use the library in any commercial or non-commercial project.

Where do I go from here?

For more details, examples, source, and downloads, see the project’s homepage at http://knockoutjs.com

53 Responses to Introducing Knockout, a UI library for JavaScript

  1. Very nice work! I’ve been pondering whether or not to bring my Caliburn.Micro Silverlight library to Javascript. I think you just provided me with a solid databinding foundation to work with and the final bit of encouragement I needed :) Looking forward to working with this.

  2. Torkel

    Very nice. Been thinking about doing something similar for a while, will try it when I get back from vacation :)

  3. Steve

    how does this ‘observablearray’ differ from the Rx (reactive extensions) javascript capability ?

    I was going to say, it would really rock if you used that the covers :)

    http://channel9.msdn.com/posts/Charles/Introducing-RxJS-Reactive-Extensions-for-JavaScript/

  4. Steve

    Steve – I’m very familiar with Rx for JavaScript, having recently used it heavily on a big project, and in fact aspects of the design of Knockout are made with my Rx experiences in mind.

    The key difference between Knockout’s implementation of the observer pattern and Rx’s is that Knockout automatically infers the associations and dependencies between observables from regular procedural code without you having to specify them up front though a special functional API. I wanted Knockout to use regular procedural/imperative-style code as it’s more familiar and approachable for most developers.

    Another difference is that Rx is optimised for composing streams of events without state. At first I was enthusiastic about this and its functional purity, but after some time it felt increasingly like I was jumping through awkward hoops and had to invent extra ways to simulate state to manage UI commands efficiently. That’s why, in Knockout, all observables can be treated as stateful – for example you can always read their latest value (which is cached, by the way – it doesn’t recompute until the underlying data changes).

    Rx goes further than Knockout into advanced ways of composing event streams, whereas Knockout goes further than Rx into UI development, letting you bind its observables to HTML DOM elements and templates and manipulate them any way you want. Rx is great at what it does but turned out not be be exactly how I wanted to build rich UIs – hence the design of Knockout.

  5. Steve

    Very good – thank you for taking the time to explain that. I am impressed and even more so that you have investigated Rx as a part of thinking through this framework.

    I’m a huge fan of jQuery and use it on all my asp.net mvc applications as well

    I look forward to seeing some more samples – (I was thinking editable grid!).

    Side note: I see your latest edition mvc book is out – I own the first one and I’m excited to read about mvc 2.0.

    It’s interesting to see Rob posting here, as just this morning I was watching his ‘how to build your own mvvm’ video from mix (yes, I’m behind) – and I kept thinking… we need this in asp.net mvc 2.0

    Thanks again – and I plan on looking into this more.

    PS. Let me add, in these examples – I am constantly looking for a good solution to a editable/pagable/sortable solution on my apps. Currently I make use of the mvccontrib with ajax baked in – I’d like to see about using a solution such as this instead.

  6. Steve

    One quick question here – and maybe this will inspire a new post:

    Obviously I mentioned asp.net mvc 2. I assume that if I want to use this i could simply have and actionresult that returns Json(mydata) and then on page load of the page pass the Model to the observablearray ?
    ie.

    var listEditorViewModel = function () {
    // ko.observableArray lets you track changes to a collection of things
    this.allItems = ko.observableArray();

    (hopefully that is visible in the comments!

  7. Steve

    It didn’t show up – I’m asking to pass the model to the array..

    ie. ko.observableArray(servertag= Model endservertags)

  8. sorry, I went ahead and posted a sample of what I’m talking about – mostly to try out what I was asking from you :)

    http://blogger.forgottenskies.com/?p=638

    Basically retrieving the json from a action and using it within the page.

    Great stuff Steve – I’m impressed! I had used some jTemplate usages before and I really like what you have done here – very elegant!

  9. Pingback: The Morning Brew - Chris Alcock » The Morning Brew #636

  10. I like it!

    I’ve been pretty enamoured with WPF/Silverlight over the last few years, but Knockout might be enough to persuade me to give rich javascript a go!

  11. This projects looks great. I’m trying it out right now.
    How would you implement a master-detail style UI?

  12. David Fauber

    Very cool, been playing with this all morning and think I may be able to use it to rewrite a problem page that’s really heavy on server side nightmares!

  13. Einar

    This looks really good!
    Tried on my app, and it worked really well, except I could not get checkboxes to work.
    Did some digging in the code, and as far as I can see the reason is that there is not ko.bindingHandler for the “checked” attribute.
    I got it to work by adding a ko.bindingHandlers.checked object, and re-using most of the ko.bindingHandlers.value object, with some minor modifications to the init and update functions.

    Or perhaps I’m doing something wrong, do you have an example where it works against checkboxes (or radiobuttons for that matter).

    Thanks!

    Einar

  14. Pingback: Editing a variable-length list, Knockout-style « Steve Sanderson’s blog

  15. Bassam Basaamd

    It’s really nice way to do binding to html controls width javascript, but is it possiple to bind a table html control too? how?

    Regards

  16. Thanigainathan

    Very very nice. Looking for one like this.

  17. Hi Steven
    This looks fabulous, and exactly what is needed in this space.

    I’ve been working on something very similar using Script# (and the ScriptFX framework that was built using it). More specifically, trying to bring a number of SilverlightFX mvvm ideas for use with HTML/script. Will be interesting to look into Knockout more deeply!

  18. I just heard about Knockout on DNR. Sounds like Carl and Richard were not as excited about the automatic dependency tracking as they should be. This is powerful stuff.

    I’m the author of Update Controls, an automatic dependency tracking library for .NET. It works in Windows Forms, WPF, and Silverlight. I’m going through your code now to compare implementations of the core algorithm. If you’d like to compare notes, please get the code from http://updatecontrols.codeplex.com.

    Where Knockout has “observable” and “subscribable”, Update Controls has “Independent” and “Dependent”. You’ll find both of these classes in the core library, so you can ignore all of the XAML and Forms stuff. These share a common component called “Precedent”, which is how it solves the same problem as “depentendObservable”.

    I like what I see so far. I’ll let you know if I find any ideas that can flow from one implementation to the other.

  19. Mickey

    Hi!
    I could not get the very first example to work until I added the following line:

    ko.applyBindings(document.body, myViewModel);

    and also put the JS code in “onload” handler.

    Very beautiful library.

    I am looking forward to some tutorials involving ASP.NET MVC with Knockout.

    Thank you!

  20. HB

    Wow, this is really cool. I haven’t dug into the source yet, but I really like the way it works from the (developer) user side – really easy to get stuff done.

    I almost got into WPF a few years ago (project fell through), never got into Silverlight, but I can definitely get some use out of Knockout.

  21. Pingback: Knockout « Keep clicking!

  22. very interesting — thanks Steven.

  23. Mickey

    Hi!

    When I want to bind to “click” in template – how can I pass a parameter to the function:
    {{each(i, sc) $data}}

    ${ sc.id }
    ${ sc.productId }
    ${ sc.name }
    ${ sc.dateCreated }

    {{/each}}

    Here I want to pass current object or current object’s Id to the viewModel.toggleSelect() function.
    I tried: data-bind=”click: function() { viewModel.toggleSelect(${this}); }”
    and data-bind=”click: function() { viewModel.toggleSelect(${{this}}); }”
    but it does not work and throws exception.
    Also I see that there is preventDefault always called. How can I enable default action?

    Thanks

  24. Mickey

    Hi!

    When I want to bind to “click” in template – how can I pass a parameter to the function:
    {{each(i, sc) $data}}
    <tr id=”${ sc.id }”>
    <td><input type=”checkbox” name=”sc_${ sc.id }” id=”sc_${ sc.id }” data-bind=”click: function() { viewModel.toggleSelect(?); }” /></td>
    <td>${ sc.id }</td>
    <td>${ sc.productId }</td>
    <td>${ sc.name }</td>
    <td>${ sc.dateCreated }</td>
    </tr>
    {{/each}}

    Here I want to pass current object or current object’s Id to the viewModel.toggleSelect() function.
    I tried: data-bind=”click: function() { viewModel.toggleSelect(${this}); }”
    and data-bind=”click: function() { viewModel.toggleSelect(${{this}}); }”
    but it does not work and throws exception.
    Also I see that there is preventDefault always called. How can I enable default action?

    Thanks

  25. Steve

    Hi Mickey. The default template engine uses a variable called $data to refer to the “current” object, so you probably want a binding as follows:

    data-bind=”click: function() { viewModel.toggleSelect($data) }”

    Note that the variable is just called $data, not ${data}.

  26. Steve

    Oh, and about default actions – if you get the latest version of Knockout from http://github.com/SteveSanderson/knockout/tree/master/build/output/, you can allow default actions to proceed by explicitly returning true from your click/submit handlers.

    Link and form navigation actions are prevented by default because it’s unusual to want to allow them when the link/form is really just a UI for manipulating your view model.

  27. Mickey

    Hi, Steve.

    I think $data in my case is referred to the array of items, but I need to call viewModel.toggleSelect with current item in “each” loop, which is “sc”.

    I changed the template to:

    <tr id=”${id}” class=”jstree-draggable”>
    <td><input type=”checkbox” name=”sc_${id}” id=”sc_${id}” data-bind=”click: function() { supplyChainViewModel.toggleSelect($data); return true; }, checked: $data.isSelected ” /></td>
    <td>${id}</td>
    <td>${productId}</td>
    <td>${name}</td>
    <td>${dateCreated}</td>
    </tr>

    And the HTML to:
    <tbody data-bind=”template: { name: ‘scTemplate’, foreach: selectedFolderSupplyChains }”></tbody>

    now “$data” is the current element and it works.

    Also I downloaded your latest version, as you suggested, and the default action is working as I expect.

    Thank you very much!!!

  28. Kaung

    Hi Steve,

    How do I add a new child to an existing parent? My initial data is from the server.

    //Here’s an example.
    var initialData = [{"Name":"John","Children":[{"Age":22,"Name":"Steve"}]},{“Name”:”Bob”,”Children”:[{"Age":12,"Name":"Luke"}]}]
    var viewModel = {
    parents : ko.observableArray(initialData),
    addParentAndChildren : function (){
    this.parents.push({“Name”:”Scott”,”Children”:[{"Age":22,"Name":"Steve"}]});
    },
    addChild : function (){
    //Add new child to an exisitng parent and updating the UI.
    }

    };

    Do I have to do something like your templating example?
    var person = function (name, children) {
    this.name = name;
    this.children = ko.observableArray(children);

    this.addChild = function () {
    this.children.push(“New child”);
    }.bind(this);
    }

    Thanks,
    Kaung

  29. Mickey

    Hi, Steve

    I have another question/issue:

    I have something like folder view. Click on folder in folder tree fills table with folder items. Clicking on different folders (thus reconstructing the table) causes IE to grow in memory. (I have several hundreds records for some folders).

    Is this expected behavior of the browser or is there a memory leak?

    Also – is there some kind of caching in template plugin?

    Thank you in advance.

  30. This is great Steven!

    FYI, I was trying the Templating example found on knockoutjs.com and noticed that the radio button doesn’t work in IE7.

  31. Steve,

    Looks great. Had been working with crude data linking of my own before in a rel attribute but this beats it hands down.

    Going to try and start using it. Would second suggestion of putting link to google groups from knockoutjs.com

    Colum

  32. Pingback: Was Dave a Genius? « Invalid Cast

  33. Daniel

    Very nice work. I really like the idea and I can’t wait to build something with it :D

  34. Hi Steve,

    In relation to Mickey’s comments, I’m also using the templating feature and experiencing the same memory leak; it looks like the injected anonymous code is not being disposed.

    Cheers,

    Karl

  35. Pingback: Enterprise RIA Javascript MVC Thoughts? « Tales from a Trading Desk

  36. Tad

    Cool library, looks really useful.

    Found a bug on one of the live examples. I haven’t had a chance to figure out how deep the problem is:

    http://knockoutjs.com/examples/betterList.html

    press “sort”
    then add something, “foo”
    press “sort” again… doesn’t get sorted…

    -Tad

  37. Jacob

    Steve,
    This is really awesome, and I’m playing with for a while now.
    But I have a question: I have a single object then its properties are not getting updated automatically?
    Here is the code:

    var person = { FirstName: “Jacob”, LastName: “Wakeem” };

    var personDataView = {
    FirstName: ko.observable(person.FirstName),
    LastName: ko.observable(person.LastName),
    Save: function (t) {
    service.SavePerson(person);
    },
    };

    ko.applyBindings(personDataView);

    There are two text boxes that bound to FirstName and LastName and a save button like this:

    Save

    I insert new values in the textboxes, and click Save.
    In the Save function in ViewModel, the person object is not updated with the new values. And I need to set them manually.
    Is this the right behavior? Or I’m missing something?

  38. Nathan Bain

    Tad

    Try Adding “Foo” instead of “foo”.

    The sorting takes Casing into account.

  39. Pingback: Knockout.js 1.2.0 released « Steve Sanderson’s blog

  40. You share many helpful ideas! Perhaps I should think of trying to do this myself.

  41. Pingback: Los Vocalino | TV Comments

  42. Pingback: First On-Set Photo of ‘American Reunion’ Boys | TV Commenter

  43. Pingback: Earning Your Degree Online ? Article Xplosion | Claddagh

  44. Pingback: Music, Mattress Factory, Mini Golf Radio Round Up for June 17 | agerogeti

  45. Hey,

    I have recently been recruiting for a knockout and sproutcore contract role and have therefore been emersing myself in this new framework.

    The role is utilising knockout to be written in asp.net and MVC. It is a very exciting 18 month project and my client would like someobody that has a genuine interest in the knockout framework and from looking at the above I can see why!

    It is a 6 month contract in the south of 2ndgland and the pay is exceptional. There is an excellent chance of extension so please contact myself on t.kelly@cmputerfutures.com or call on. +44 (0) 1179103333

    I hope potential this opportunity is of interest!

  46. Quick correction on the above, the email address is t.kelly@computerfutures.com

  47. Pingback: Editing Variable Length Reorderable Collections in ASP.NET MVC – Part 3 | Ivan Zlatev

  48. Pingback: Historia powstania JS « Wiadomości o technologiach IT

  49. Pingback: Dla mnie bomba « Wiadomości o technologiach IT

  50. Jordan

    coming from Silverlight to ASP.NET this will be very useful (Meanwhile Pro ASP.NET MVC 3 Framework) has also been very useful :)

  51. Really nice article. I also have a tutorial that takes this a step further by performing CRUD operations on the database. URL: http://www.colourblendcreative.com/c/using-knockout-js-to-perform-crud-operations-ajax-in-asp-net/

  52. it is very interesting to watch C#/.NET/ASP/SL people trying to port themselves into the HTML/JS paradigm. All together with life long “unqestionable” truths like:

    1.
    class is a good thing
    2.
    This is “much better” :
    this.allItems = ko.observableArray(["Apple", "Banana", "Cherry"]);
    this.itemToAdd = ko.observable(“”);

    Than this:
    this.allItems = ko.observable(["Apple", "Banana", "Cherry"]);
    this.itemToAdd = ko.observable(“”);
    3.
    there is a science behind Rx

    Sadly all false … And also sadly very visible in WinJS, or BUILD demos where speakers are presenting code on stage with document.getElementId() , everywhere …

    This all might be not very important, but more seriously Google is watching. And notices general inability to produce modern HTML5/JS solutions.

    Thanks …