Reputation: 657
I know this question has been asked several times, but all the answers confuse me, because I am unsure of how to get the coffeescript code to compile into that specified jquery code.
This is what I have so far:
pluginName = 'tagbox'
states =
none: 0
typing: 1
altering: 2
defaults =
editing: true
tags: []
class Plugin
constructor: (@element, options) ->
@options = $.extend {}, defaults, options
@_defaults = defaults
@_states = states
@state = states.none
@_name = 'tagbox'
@currentTag = $("<div class='ui-individualtag'></div>")
# this is the public method I want
setCurrentTag: (tagText) ->
@currentTag.text(tagText)
$.fn[pluginName] = (options) ->
@each ->
if !$.data(this, "plugin_#{pluginName}")
$.data(@, "plugin_#{pluginName}", new Plugin(@, options))
)(jQuery, window, document)
and then in another script, I want to be able to access the setCurrentTag method like this:
tagbox = $('#tagbox').tagbox()
tagbox.setCurrentTag("hello world")
Let me know if it will help to show what this compiles into in jquery.
Upvotes: 1
Views: 462
Reputation: 434665
Your problem is that tagbox
:
tagbox = $('#tagbox').tagbox()
will be a jQuery object and that won't have a setCurrentTag
method. You don't want to try to change this as that will break the usual jQuery chaining behavior. One way to solve this is to give the tagbox
plugin enough intelligence to parse its arguments so that you can pass a method name in:
$('#tagbox').tagbox('setCurrentTag', 'hello world')
This is the approach that jQuery-UI takes so it should be familiar to a lot of jQuery people.
All you'd need to do is modify your $.fn.tagbox
to look more like this:
$.fn[pluginName] = (options = {}) ->
if $.isPlainObject options
@each ->
if !$.data(@, "plugin_#{pluginName}")
$.data(@, "plugin_#{pluginName}", new Plugin(@, options))
else
args = Array.prototype.slice.call(arguments);
@each ->
p = $.data(@, "plugin_#{pluginName}")
p[args[0]](args[1])
Demo: http://jsfiddle.net/ambiguous/q2U7d/
Some things to note:
(options = {}) ->
) so that options
will always be there.$.isPlainObject
, if there no options then we can assume that we're doing a method call instead. This is why we want the default in 1.Array.prototype.slice.call
as a hack to convert the Array-like arguments
to a real array to make it easier to work with. We don't have to do this but it can save some confusion if we want to use Array methods (such as pop
) and we need a reference to the outer arguments
inside the @each
callback anyway: arguments
is context sensitive just like this
is in (Coffee|Java)Script.Upvotes: 2