ProgramiCo
JavaScript Web Application Development
  • Home
  • SmartJs
    • Setting up the Environment
    • Running SmartJs
  • SmartJs Blog
  • About

Click on a Select2 item to set it as Primary

8/4/2015

0 Comments

 
This exercise uses the famous library Select2 version 3.5.2 for a multi select.  It extends the default Select2 behavior by allowing the User to click any of the selected items to designate it as the "Primary" selected item.  Feedback is given by highlighting the Primary selected item in green, and displaying the Primary selected item on a separate Form row.  A hidden field is added by using a Naming Convention, so that the Primary selected item can be submitted in the containing Form along with the normal Select2 data.

Here's what we will end up with.  There is a Select2 for a list of Troops, and there is a Primary Troop selected, shown in green, and on a separate line.  We can interactively click the Select2 items to toggle the Primary Troop selection.
To explain how I did it, let us begin with the Markup:
We have a standard Html select input field defined in the Markup, where we will attach Select2.  It is declared as multiple and I have added a special class called "primary-selectable".  That way you could signal the extra code for Primary to run or not, based on the presence of this class.

Following the select we have the display for the Primary selected item.  It includes a Hidden form field to carry the selected item's ID, a place to output the Primary item's text, and a container where a message can be displayed if no Primary item is selected.

And now for the Script.

I encapsulate the Primary-selectability as this function that invokes Select2, and returns a facade which the application can use to communicate with the underlying object.  It can support any Select2 options structure which the application passes as a parameter.

It reads the Primary selected value from the Hidden field to begin, and runs its internal update function then and also when the first item is selected in the Select2, and during other change events.  It exposes a destroy method so that dynamic forms can clean up the event handlers.

In the application code, instead of directly calling Select2 now, we call this facade function with an element as the first parameter and any applicable Select2 options second.

And finally give some special styling to the Primary selected item so that it is visually distinct.  I used a gradient generator to build a green gradient similar to Select2's gray gradient it uses for item background.
I put this all together in a JSFiddle so you can play with it interactively.

  • View interactive demo on JSFiddle
  • View all code on Github Gist


Remember, this is using Select2 version 3.5.2.  There are breaking changes in version 4.0.0 so this probably is not going to work there.

I welcome your comments, please let me know if you're using the code.
0 Comments

Hosting nowjs documentation locally

1/8/2013

0 Comments

 
If you're using nowjs, you probably noticed that nowjs.com website has been down for a long time.  It had some real good and useful documentation on it, and unfortunately now that is no longer accessible.

No worries, I will show you how to host nowjs documentation locally.  It's even faster and more convenient to use when it's hosted on your own box.  You will need a local webserver like Apache.

Go to the Github site for nowjs, https://github.com/Flotype/now and download the latest copy.  If you have the Github client just use "Clone in Windows" button.  If not you can download the whole project as a Zip and unzip to somewhere on your drive.

Let's say you have a copy of the Flotype nowjs repository under C:\dev\nowjs.

Create an Apache website and point the root to the folder C:\dev\nowjs\doc\jsdoc.  Let's say you used port 204 for this new Apache site.  Then, point your web browser at:
http://localhost:204/index.html
And you should have all the goodness of the Nowjs documentation, with no dependence on their down website!

You can also get to the Getting Started, User Manual, and Best Practices pages of Nowjs through their Github site at these Urls:

https://github.com/Flotype/now/blob/master/doc/public/getting_started.md
https://github.com/Flotype/now/blob/master/doc/public/user_manual.md
https://github.com/Flotype/now/blob/master/doc/public/best_practices.md
0 Comments

KnockoutJs + jQueryMobile Slider

12/4/2012

3 Comments

 
I have been having some struggle with the jQuery Mobile slider.  It is kind of non-standard in the way that it removes the original Range input from the DOM and replaces it with its own.  The one it inserts in has the same ID as the removed one.  It's actually really tricky to get 2 way binding to work with the jQuery Mobile Slider and Knockout.  After scouring the interwebs for advice on jQuery Mobile Slider + Knockout Js, I ended up creating my own custom Knockout binding to wire up the 2 way binding.

Hide the Numeric input, okay?

Okay. We got a nice slider and the normal old text input is still left next to it.  So just add this CSS to your style sheet, prefixing with the appropriate container if you want to be more specific.
3 Comments

NodeJs new version doesn't support standard nowjs or mongodb npm modules (on Windows)

11/7/2012

0 Comments

 
I noticed that the default version of NodeJs to download off their site is like version 0.8.14 right now.  This unfortunately does have some issues with some npm nodules that are relevant to SmartJs.

Try using an older version of NodeJs, like version 0.6.19 or so, and it should work fine with npm modules now and mongodb.  When I run with the new version I get errors like:

  • The specified procedure could not be found
  • native module is not a valid Win32 application
  • Error: cannot find module 'xxx'
  • no build will be attempted as binaries are prepackaged


In order to get these npm modules fully working, you also need to make sure you are using the 32 bit version of NodeJs, even if you are running on a 64 bit system.

I would like to hear from anybody in the Comments, if you are successfully running these npm modules in a newer version of NodeJs, or on 64 bit NodeJs, specifically on Windows.
0 Comments

Building a jQuery Mobile SPA in Phonegap

10/19/2012

0 Comments

 
This post continues to answer "what is SmartJs".  In this article we look at the J and the S.  How is the SmartJs framework Single Page Application UI implemented with jQuery Mobile? Read on to find out...  

UI Frameworks; pick one

I have tried a few frameworks for developing a mobile application UI.  The the number one reason to love jQuery Mobile over things like Sencha Touch or Titanium Appcelerator, is that it allows the UI to be written in pure Html and Css.  For me, other UI frameworks violate separation of concerns, when they make me compose my UI inside JavasScript files.  That is why we have Html and Css, to build the UI.  The especially strange feeling is when they make me use proprietary JavaScript objects to build UI's.  It reminds me of a Telerik or Infragistics library kind of control I've encountered several times in the .Net world. Almost always, these would end up being trickier to integrate with when you wanted something special.

Other things I like about jQuery Mobile are:
  • It looks good
  • It has a great code generator in Codiqa
  • It has a great theme generator in Themeroller
  • It has a rich set of widgets
  • It is compatible with jQuery
  • It is easy to bind to Knockout Js
  • It is being actively developed and improved
  • Just like everything else in SmartJs it is free, free, free

Codiqa UI; WYSIWYG Generator for jQuery Mobile

It can be daunting when you look at jQuery Mobile Html markup.  There seem to be a lot of attributes that one needs to know to get the proper effects.  Enter Codiqa UI to get you quickly started without having to write a single tag of that Html.  If you hit the jQueryMobile homepage, there is a free demo of Codiqa where you can actually do quite a bit without ever even needing to open an account.  Just drag and drop your UI elements and then customize them for your app.  Then hit "Inspect Code" and copy and paste the generated source code into your app's html view file.  From there it's easy to add some Knockout bindings to the Html to connect it to your ViewModels.

Bootstrapping jQuery Mobile and Phonegap

A good deal of work and research has gone into properly bootstrapping the SmartJs SPA and getting all of the libraries to work together cleanly.  The startup sequence looks something like this:

  1. index.html includes Cordova directly.  Cordova has its own built-in AMD implementation that registers itself as a module named "cordova".
  2. index.html then uses the regular RequireJs method to get to the app/main.js module
  3. Inside main.js we require jQuery and jQuery Mobile first
  4. We use jQuery to attach an event handler to document to handle the ready event.  This seems to be good enough to begin using jQuery Mobile
  5. In the case of a mobile-targeted build configuration, we attach an event handler to the deviceready event that will be fired when Cordova has initialized.  According to Phonegap documentation, a Phonegap app "shouldn't do anything" until this is received.

In different situations the events can be received in different orders.  So we need a flexible solution that works independently of timing.  The SmartJs main.js file shows how this can be done.

Click here to view the SmartJs main.js bootstrap file on github.

Keeping the Knockout-bound jQm Listview updated

When binding a jQuery Mobile Listview to a Knockout ViewModel, Knockout is going to come along and regenerate the Html whenever the underlying ViewModel changes.  When that happens, jQueryMobile needs to be notified that the listview should be refreshed.  That's because jQueryMobile does some post-processing to the normal <ul> and <li> markup of a list to turn it into a super special jQueryMobile list.

But how do we cleanly separate that concern from the ViewModel?  We surely don't want to have to call a function that manually updates the View each time we update the ViewModel.  Fortunately, we have the Knockout binding handler concept which is perfectly suited for the task.

Below is SmartJs's binding handler for the purpose of refreshing the jQuery Mobile Listview.  To re-render other jQuery Mobile widgets after dynamically adding content, a binding handler should be created for each kind of widget, because currently jQuery Mobile's widgets each have their own "unique" way of refreshing themselves that you will need to research.
0 Comments

Real Time Communications in a JavaScript Mobile App

10/1/2012

0 Comments

 
This post continues to answer "what is SmartJs".  In this article we look at the R and the T.  How does SmartJs implement Real Time communications? Read on to find out...

Network Events are Events too

In SmartJs a number of network communication channels are available:

  • Client->Server
  • Client->Client
  • Server->Client
  • Client->Group
  • Server->Group

All of them use the same Publish/Subscribe model to loosely couple the interactions.  In fact in SmartJs I go so far as to call it a Virtual Pubsub because an event could be Published on one device and consumed by other devices.

Underneath, there are two modules that are handling the communication infrastructure.  One is the proxy for Server on the client-side and the other is the proxy for Client on the server-side.  SmartJs was designed to allow these two modules to be able to swap out with other real time library implementations, or even plain Ajax.

Implementing Open-Closed Principle in the SmartJs client-server Interface

In the SmartJs client's proxy module for the Server we have the implementation of the function:
  • nowjs.eventServerToClient

This is where information is received from the server, and it is wired directly up to a Publish.

In this same module we find that the client calls the server using this function:
  • nowjs.eventClientToServer

It provides a callback which runs when the event is processed.  It is never the responsibility of the callback to handle any resultant data.  It is only there to provide success or failure feedback in the case where that is possible.  For example,  when attempting to create a new Topic, it will return a failure in case that Topic name is taken.  But if the Topic name is not taken, a separate message will come back Published containing the new Topic's data.  This is an example of SRP applied to a functional interface.

Similarly the server implements:
  • nowjs.eventClientToServer

This is where the information sent by the client arrives to the server.  There it is separated into data or group handling and further separated within the data or group handlers.

The server makes calls to connected clients using the function:
  • nowjs.eventServerToClient

It is the data structures passed through these functions that determines the routing and handling.  The functions themselves are open to extension while remaining closed to modification.

The dataContext and groupContext modules provide segregated interfaces to the server functionality.  These populate the traffic "kind" attribute with "data" and "group", respectively. Conceivably, other new modules could be developed that make use of the server proxy conduit, without ever needing to change the server module.  This is a great example of OCP.

Hacking nowjs to reference socket.io locally

This last bit is to show a bit of hackery I put together that allows nowjs's reference to socket.io to resolve to the client's /lib folder instead of the default of being network served by the nowjs host.  There are a few reasons you might want to do this, mostly I guess involving testing and efficiency.  Follow this recipe for the hack:

  1. While viewing your nowjs site in Google Chrome, hit F12 to bring up your Developer Tools and switch to Sources view.
  2. Find socket.io.js listed under your server's name or IP and click it to view it.
  3. Right click it and choose Save As... and save it to your app's /lib folder or equivalent.
  4. Apply the Hack to your copy of now.js as shown in this SmartJs checkin.
  5. Re-run your app, being sure to clear the Js cache
  6. You should now see the socket.io.js listed under /lib in Chrome's Developer Tools Sources tab

Todo: better AMD support for locally hosted socket.io.js so it will be built by r.js correctly.
0 Comments

JavaScript MVVM DI with AMD and Pub/Sub

9/30/2012

0 Comments

 
This post continues to answer "what is SmartJs".  In this article we look at the M and the A.  How does SmartJs demonstrate the MVVM pattern?  And what does AMD have to do with it? Read on to find out...

M is for MVVM

My favorite part of MVVM is the data binding.  Update a data structure, and the UI automatically changes.  That is like magic.  The benefits are tremendous.  A necessary part of MVVM is an event driven system.  When you think about it, MVVM is well suited to the job of rapid application design in a connected world.  But how to pull it off correctly?  Fortunately we have some some great libraries like Knockout and RequireJs to provide the abstractions we need.

Organic Design

I tend to think of software design from the GUI inward.  The UI can be quickly designed with prototyping tools like Codiqa.  I like that the prototype is easy to change in the design phase, but it isn't wasted effort.  The prototype becomes the starting point for the UI markup that can be bound with Knockout.  With a little practice, it becomes easy to extrapolate UI concepts into ViewModel data structures.   The system begins to design itself.  When the ViewModel is designed, we will have a clear sense of the upstream persistence and connectivity needs that need to be built into the underlying model.  In turn, the Server side development is very focused, delivering only the functionality needed, without wasted effort.

MVVM and MVC; Different tools for different jobs

When we talk about MVVM there is always the question of MVVM versus MVC.  My work in MVVM has been in Windows Client software which is event driven and relies on XAML to ViewModel binding.  Working with Knockout was an intuitive transition.  In a Single Page Application we are again able to present a real-time event-driven desktop-like experience to the user.  So for me, MVVM was a natural choice.

My personal experience with MVC has been in the context of the request/response paradigm.  When we evolved from Asp.Net postbacks to MVC I rejoiced.  .Net Postbacks are an artificial construct, while MVC felt more free and more like Cold Fusion Fusebox fuses, that I already knew about.  MVVM doesn't make much sense in a request/response flow.  But so doesn't MVC make sense to me for an event driven SPA.

RequireJs-> AMD-> DI-> MVVM-> Knockout-> UI

How do we combine these ingredients to concoct the architecture we need?  SmartJs uses RequireJs to implement Asynchronous Module Definition.  We get modules that have RequireJs injecting the Dependencies for us.  Each module is isolated, it knows only of its own dependencies.  Indeed it has its own namespace, so artificial container constructs like "self" become unnecessary.  The need to be composed with specific other implementations disappears, which allows us to write stub dependencies to facilitate unit testing.  There is no overriding controlling global authority available to the app.  And why should there be?  The ViewModel exists to serve the event driven application.  With a proper system of Publication and Subscription, events will propagate throughout the system and cause the appropriate changes.

So our AMD modules have their Dependencies Injected with RequireJs's define.  The ViewModel modules will be injected with a Knockout reference so that they can invoke the observableArray, computed, and other Knockout goodies.  We take the output from Codiqa and add some straightforward Knockout binding tag attributes, add in a rich system of published and subscribed events, and the application comes to life with behavior of its own.  And here we have the MVVM pattern.

Events happen; Pub and Sub

Most SmartJs modules are injected with a Pubsub reference that they can use to Subscribe to events that interest them.  The Pubsub module also provides a simple publish() method that will send out events to the local client only.  The Server module provides a publishGroupEvent() method that publishes virtually to all clients connected to the same nowjs group.

In an interactive SPA, events will be initiated by the UI, and that is a perfect application of Knockout's computed.  In the setter (write) of the computed, we implement a wrapper pattern around an observeable backer property.  But additionally we can run any application logic we want which generally is going to lead to a Publish of some sort.  The perfect example is in the flow that takes place when a user starts typing in the chat room.

Where'd the model go?

It's all too easy in JavaScript to just return a data structure from a method.  In a properly designed and maintainable system we must organize the model declarations so that they can easily be found and referenced.  When I wrote SmartJs I found myself asking, now what is the exact name of this model's column again?  And I would have to look everywhere in the code to find where it had been instantiated, often as a difficult-to-find anonymous type in a ViewModel.

So to save the hassle and headache, the Schema module was born.  And a lot of familiar concepts like Validation seem to belong there.  Having a clear sense of the data model in a JavaScript application is the exception rather than the rule.  But SmartJs attempts to give derivative works a place to build and maintain a data model that is easy to reference and therefore, should be hard to mess up :)
0 Comments

S is for SOLID

9/26/2012

0 Comments

 
The year is 2012 and we have acronyms of acronyms of acronyms.  The word SmartJs is itself an acronym, the first letter of which is the first word of an acronym, which is itself composed of acronyms.  

This post aims to discuss SOLID principles and, in particular, demonstrate their usage in the SmartJs framework.

Background of SOLID

Please take a look here for some background on SOLID principles.  It is rather heavy reading so Wikipedia's article may be easier to digest.  We have been studying SOLID at our work and it has had a profound influence on my ability to formalize how I think about software development.

S = SRP; Single Responsibility Principle

SmartJs contains many examples of The Single Responsibility Principle.  Most obviously, AMD provides a language construct that encourages modular software design.  Each module of SmartJs is designed to do one thing only.  Indeed, during the organic construction of SmartJs, several modules were born when the code in a parent module began to do more than one thing.

But more than the modules themselves, the SRP was built right into the functionality at a fundamental level.  The most clear example of this is the interface to the Server module.  Although the interface exposes public methods that provide data persistence services, the function calls to Server are designed to begin the process only, and report back success or failure.  They never return a model representing the result of persistence, that is consumed by the caller.  In cases where a model is the result of a persistence operation, that model data always follows as a separately published application event.

The design and enforcement of rules like this took awhile to evolve.  By adhering to SRP, this design pattern doesn't seem difficult to work with, but rather a joyful reminder that SRP can be very helpful when correctly applied.  The application components must always remember that, for example in a list operation, the command to list will not be immediately followed by a list of results.  It is only a command to start the process, and a separate e.g. topic.list event will be present in the system a short time later with the contents of the requested data.  This allows an opportunity for all the components of the  application to respond equally and independently to the presence of new data and events in the ecosystem.

O = OCP; Open Closed Principle 

The Open Closed Principle can be hard to pull off, especially in a project that is evolving quickly.  It can be hard to have the foresight to know where OCP will eventually be needed.  Sometimes a switch statement is a good place to look for a place to implement OCP.

I think JavaScript makes OCP a lot easier than C# because there is never a type conversion that needs to be done.  Any object and any number of parameters can be passed to a function in any order, so Extensibility is rather built in.  It can be a fine line to walk.

The best example of OCP I can think of in SmartJs is the conduit from the client to the server.  It is boiled down to one function to call from client to server, and one function to call from server to client.  Everything goes through this narrow pipe, and the pipe itself does not require any maintenance when new functionality is added to the application.

Two modules use the Server functionality, dataContext and groupContext.  These wrap the Server in convenient methods, extending the Server's usability without requiring modification.  These two demonstrate OCP and ISP well, since new functionality could be added to the system without ever needing to change server.js.  The data conduit is truly open for extension, and closed for modification, making it a breeze to add interesting new realtime functionality.

L = LSP; Liskov Substitution Principle 

SmartJs demonstrates LSP when it passes around a Knockout observeableArray as if it was an array, to the Validation module.   Validation pushes errorMessages onto it as if was an array, never knowing or caring that the array is bound to the UI.

I = ISP; Interface Segregation Principle

Similar to SRP, modules in SmartJs are designed to do one thing.  They return only the minimum necessary interface that other modules will need.

When a model in the system needs to be used for two different purposes, SmartJs will use two different ViewModels, each with their own UI binding and public interface.  This prevents having a catch all interface that is cluttered and violates SRP.

DataContext and groupContext modules also provide segregation of the Server interface.  Their interfaces are specific to data and group kinds of functionality respectively.  New group functionality could be added to the groupContext without needing to change the server's interface.  This results in a system that is less brittle overall.

D = DIP; Dependency Inversion Principle

The best for last.  I really think this is my favorite.  It is the reason that AMD is so wonderful.  It is what separates MVVM from MVC.

AMD allows modules to have dependencies fed to them at run time.  There is no composition root.  There is no Controller to call for help.  There is only the View and the ViewModel, their binding, and events in the system which encourage things to happen.  When model properties are changed, the user interface automatically udpates through binding.

Modules never have to know or care how their dependencies are fulfilled.  They call an interface and have an expected result.  Therefore, DI makes it easy to perform Unit Testing, by allowing the building of stub objects that fulfill the dependency interfaces without doing any real work.

I have a good deal of background working in MVVM in XAML/WPF for Windows app development.  One thing that makes this pattern possible in that world, is Unity Controller.  MVVM without a DI container is a lost cause.  MVVM with a DI container is a pure pleasure to develop.

Therefore, implementing MVVM in JavaScript is correctly done using AMD and RequireJs provides this ability flawlessly.

Next post...M is for MVVM 
0 Comments

    About the Author

    Picture
    Hugh Anderson is a web frontend developer in Tennessee who loves JavaScript and C#. 

    View my profile on LinkedIn

    Archives

    August 2015
    January 2013
    December 2012
    November 2012
    October 2012
    September 2012

    RSS Feed

Powered by Create your own unique website with customizable templates.