Google Groups

Re: Using Knockout with jQuery UI Widgets


Sleighter Apr 14, 2011 10:52 AM
Posted in group: KnockoutJS
Thanks for sharing this. It wasn't sufficient for a recent problem I
had, so I thought I'd share a work-around that I used for the jQueryUI
problem and hopefully I can get some suggestions for improvements from
you.

I wanted to use jqui tabs/accordion widgets on an observable
collection. However, jquery wasn't automatically making new elements
part of the tabs/accordion widget. My first thought was to subscribe
to the collection changed event and re-trigger the widget with $
().accordion(). The problem is that the subscription event fires
before the template is rendered, so this still doesn't make the new
element part of the widget. Then, I found the livequery plug-in
(http://docs.jquery.com/Plugins/livequery) which triggers an event
when any new element matching your selector is rendered.

I set up the call as :
$("#accordion-list > DIV").livequery( function() { $("#accordion-
list").accordion('destroy').accordion(); } );

It seems criminally inefficient, but when KO adds an element to the
accordion list, livequery will trigger recreation of the accordion
widget on the, now larger, collection. It still has a problem of
showing the unstyled element for a moment before the accordion is
rebuilt.

Fiddles, For your pleasure:
Without the live-query fix (new elements are not part of the widget):
http://jsfiddle.net/sleighter/q9ZGE/
With the livequery fix (new elements are added to the widget):
http://jsfiddle.net/sleighter/s5tEG/

Cheers,
Sleighter

On Apr 14, 2:48 am, Jehu <marco.mich...@gmail.com> wrote:
> Great stuff! Thank you for sharing with us.
>
> Have you used it - say - with a 'sortable' unordered list? can't
> firure out, how to change the sorting in the viewModel after dropping
> the item.
>
> On 27 Mrz., 20:39, Mike Edmunds <medmu...@gmail.com> wrote:
>
>
>
>
>
>
>
> > I recently joined a project that makes extensive use of jQuery UI Widgets --
> > not just the standard ones, but also its own custom ones as a general
> > architecture for holding view-layer code.
>
> > We're adding Knockout to the mix and wanted to create a single, reusable
> > binding for UI widgets. Since several other people here seem to be working
> > with jQuery UI, I thought I'd share what we've come up with. Comments and
> > feedback are very much welcome, and please feel free to use this in your own
> > projects.
>
> > Here's the Knockout custom binding code:https://gist.github.com/889400.
> > Here's a fiddle with some
> > demonstrations:http://jsfiddle.net/medmunds/4Xjtq/
>
> > This simple example attaches the jQuery UI datepicker widget to an input
> > field, with all of datepicker's default options:
>
> > <input id='deadline' type='text' data-bind='jqueryui: "datepicker"' />
>
> > You can also pass jQuery UI options in the binding -- and the real power
> > comes from using Knockout observables in those options. Here's a
> > slightly-more complex example that does just that (and also uses KO's
> > 'value' binding for the contents of the input field):
>
> > <input id='search'
> >      data-bind='jqueryui: { widget: "autocomplete",
> >                               options: { source: searchCompletions(),
> >                                            delay: 500 } },
> >                      value: searchString' />
>
> > In this example, searchCompletions would be a ko.observableArray in your
> > viewModel, used to provide the possibilities for jQuery UI's autocomplete
> > widget. The options are not only passed to the UI widget at creation time,
> > but they're also updated on the widget whenever they change. So long as
> > searchPossibilities is a Knockout observable, whenever you update
> > searchPossibilities in your viewModel, they're automatically updated in the
> > autocomplete widget. (The fiddle above includes a version of this example:
> > switching the 'category' will change the autocompletions for the 'product'
> > field using a ko.dependentObservable.)
>
> > We've been working with this for a couple of weeks now. Some observations:
>
> >    - This approach seems to work well with jQuery UI Widgets that are
> >    designed to enhance existing HTML with little additional code (e.g., button,
> >    buttonset, datepicker, autocomplete).
> >    - I think it's less attractive for some of the other jQuery UI Widgets.
> >    E.g., the example fiddle includes a slider bound to a ko.observable value,
> >    but I think the code in that binding is particularly ugly and really doesn't
> >    belong in the HTML. For real-world use, I'd probably want to create a custom
> >    KO binding specifically for the slider to hide all of this.
> >    - The code hasn't been extensively tested (and we haven't tried all of
> >    the jQuery UI Widgets), so I'm sure there are bugs lurking. E.g.,
> >    autocomplete seems to have a weird interaction with KO's value binding if
> >    you use the mouse in the autocomplete menu -- but it works fine if you use
> >    the keyboard (and, oddly, datepicker doesn't have the same problem).
> >    Draggable seems to work, but resizable doesn't. Etc.
>
> > Also, one big caveat: the jQuery UI Widgets created this way will never get
> > destroyed. This may or may not be a problem for you. (It is for us, as we're
> > using them inside some deeply-nested foreach templates that get updated
> > frequently, meaning Knockout is constantly creating and deleting DOM
> > elements with these widgets attached. Our current solution involves
> > modifying Knockout to call a new 'destroy' method in custom bindings, so
> > that code's not included here. Perhaps some of you will have ideas for a
> > better approach.)
>
> > We're really impressed with both Knockout and the community around it. I
> > hope some of you find this helpful.
>
> > - Mike