jQueryUi Dialog Search using knockoutjs


This is a followup to a post I wrote about using a jQueryUi dialog as a popup search with a filter. I decided to convert the example to use knockoutjs for the data bindings. The following is what I came up with.

Markup:

</pre>
<div id="SearchDialog">
<div class="SearchTitle">
<div class="SearchTitleText">Search Friends</div>
<div class="SearchTitleFilterButton">Filter:
 <input class="SearchFilter" type="text" data-bind='value: filter, valueUpdate: "afterkeydown"' />
 <button class="SearchButtonClose"></button></div>
<div class="SearchClear"></div>
</div>
<div class="SearchContent" data-bind="foreach: filteredFriends"></div>
<div data-bind="visible: filteredFriends().length == 0">No Results</div>
</div>
<pre>

In the above note the new data-bind attributes which knockoutjs uses to perform its magic. It now handles both updating of the DOM and the keyboard events which trigger the filtering.

The Javascript:


        $(function(){
            $('#SearchDialog').dialog({
                    width: 500,
                    create: function () {
                        //Get a reference to jquery ui generated element

                        var widget = $(this).dialog('widget');
                        //Get a reference to content div
                        var dialog = $(this);
                        //Delete the default jquery ui title bar
                        widget.find('.ui-dialog-titlebar').remove();

                        //Remove the default padding values for the popup
                        widget.css('padding', 0).find('.ui-dialog-content').css('padding', 0);

                        //Use jquery ui styling for our new titlebar
                        $('.SearchTitle',dialog).addClass('ui-widget-header');

                        //Position title elements
                        $('.SearchTitleText',dialog).css('float','left');
                        $('.SearchTitleFilterButton',dialog).css('float','right');
                        $('.SearchClear',dialog).css('clear','both');

                        //Create a close button and allow it to close the popup
                        $('.SearchButtonClose',dialog).button({
                            icons: { primary: 'ui-icon-close' },
                            text: false
                        }).css('width', 16)

                        .click(function () {
                            dialog.dialog('close');
                        });

                    }

            });

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

                self.friends = ko.observableArray([]);
                self.filter = ko.observable("");
                self.select = function(n){
                    alert('Hello I am ' + n);
                };

                self.filteredFriends = ko.computed(function() {
                	var filterText = self.filter().toLowerCase();
                	return ko.utils.arrayFilter(self.friends(), function(item) {
                   			return filterText.length < 1 || item.toLowerCase().indexOf(filterText)!=-1
               	    });

               }, self);

                //Load Json when model is setup
                self.dummyCompute = ko.computed(function() {
                    $.getJSON("friends", function(data) {
                    		self.friends(data);
                 	 });

                }, self);
            };

            ko.applyBindings(new friendsModel());

        });

In this example I decided to show how the data can be populated using ajax so I added a special computed observable which has the effect of loading the json array once the model is bound. Here is the java servlet code which returns the json data.


public class FriendList extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		String[] friends = new String[] {"John","Bob","Jones","Tessa","Anna","Casper","Ed","Francis","Greg","Hanna","Ivan"};
		Gson gson = new Gson();
		String jsonString = gson.toJson(friends);
		resp.setContentType("application/json");
		resp.getWriter().print(jsonString);
	}

}

If you are wondering why I am using java it is because my samples are hosted in google app engine. The live example for this post can be found here. Also, the non ajax example using knockoutjs can be found here.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s