Question

TLDR;

I'm trying to bind the same way as an external handler, just on the inside of the jQuery UI Widget.

Details

For the purposes of triggering/listening to events inside a large/pluggable jQuery UI Widget, I'm attempting to use the widget element's bind and the widget's _trigger, but cannot seem to get it wired up properly.

The following code is from a coffeescript class inside the widget that has a back reference to it:

  bind: (type, fn) ->
    ### bind a callback through the widget's element ###

    # this doesn't work
    @widget.element.bind("#{@widget.widgetEventPrefix}#{type}", fn)

    # this doesn't work either
    @widget.element.bind(type, fn)

The following has no effect:

@widget._trigger('foo')

Reason

I'm binding to the wrong element. I noticed that @widget.element is not the same element that is used as the reference outside the widget e.g. @widget.element !== $('#bar').myWidget()

Summary

External listeners have no problem binding/listening the same way via the $('#bar').myWidget().bind('mywidgetfoo', () -> alert 'foo')

I'm trying to bind the same way as an external handler, just on the inside of the widget.

Question???

How should I be binding inside the widget so that both internal and external listeners are properly connected?

Was it helpful?

Solution

I FINALLY figured this out, and it was as simple as missing the fact that handlers using bind to listen are all lower case.

So here is a sample of the code I use in an internal component base class to allow components to bind and unbind against the top level jQuery UI Widget, allowing me to use an event oriented architecture that uses the same events inside and outside the widget:

class Base

  constructor: (@widget) ->

  _fullyQualifiedEventName: (type) ->
    fullyQualifiedName = "#{@widget.widgetEventPrefix}#{type}".toLowerCase()
    fullyQualifiedName  

  bind: (type, fn) ->
    ### bind a callback through the widget's element ###
    fullyQualifiedName = @_fullyQualifiedEventName(type)

    @widget.element.bind(fullyQualifiedName, fn)

    console.log "bind(#{fullyQualifiedName}, #{fn.name})"

  unbind: (type, fn) ->
    ### unbind a callback from the widget's element ###
    fullyQualifiedName = @_fullyQualifiedEventName(type)

    @widget.element.unbind(fullyQualifiedName, fn)

    console.log "unbind(#{fullyQualifiedName}, #{fn.name})"

Whether a handler on the inside is bound to the foo event with @bind('foo', fn), or externally with $('#bar').myWidget().bind('mywidgetfoo', fn), or they passed in a handler via options in instantiation {foo: () -> console.log 'options foo listener fired'}, all listeners will now be triggered with @widget._trigger('foo')

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top