{"id":594,"date":"2009-04-23T21:12:36","date_gmt":"2009-04-24T03:12:36","guid":{"rendered":"http:\/\/bililite.nfshost.com\/blog\/?p=594"},"modified":"2009-04-23T21:12:36","modified_gmt":"2009-04-24T03:12:36","slug":"improving-jquery-ui-widget-getterssetters","status":"publish","type":"post","link":"https:\/\/bililite.com\/blog\/2009\/04\/23\/improving-jquery-ui-widget-getterssetters\/","title":{"rendered":"Improving jQuery UI widget getters\/setters"},"content":{"rendered":"<p>Right now UI widgets need to explicitly declare \"getter\" functions (methods that return information about the widget rather than manipulate it) with <code class=\"language-javascript\">$.ui.widget.getter = 'gettermethod1 gettermethod2'<\/code>. The reason is that most jQuery plugins are chainable: <code class=\"language-javascript\">$(selector).widget('method').css('color','blue')<\/code> executes <code>method<\/code> on each element matched, then <code>css('color','blue')<\/code> on each element. Some plugins and some uses of plugins instead return information about the first element selected, so they cannot be chained, like <code class=\"language-javascript\">$(selector).css('color')<\/code>. For normal methods, the widget code creates a plugin that automatically executes the method named on each element matched, then returns the jQuery object to allow chaining. It uses the <code>getter<\/code> list to determine which methods should pass their return value from the plugin instead, and only operate on the first element matched.<\/p>\r\n<p>This is inelegant, and makes <a href=\"\/blog\/extending-jquery-ui-widgets\/\">my subclassing code<\/a> less useful, since the <code>getter<\/code> list cannot be extended easily, only copied or replaced.<\/p>\r\n<p>This is due to be improved in jQuery 1.7.2 (or at least it's in the <a href=\"http:\/\/dev.jqueryui.com\/browser\/trunk\/ui\/ui.core.js#L230\">latest nightlies<\/a>): any method that returns <code class=\"language-javascript\">this<\/code> is a \"regular\" method that, when used as a plugin, should be chainable. Any method that returns anything else is a \"getter\" that returns that value when used as a plugin.<\/p>\r\n<p>Thus, in the <a href=\"http:\/\/bililite.nfshost.com\/blog\/understanding-jquery-ui-widgets-a-tutorial\/\">widget tutorial<\/a>, we no longer need the line <code class=\"language-javascript\">$.ui.green4.getter = \"getLevel\";<\/code> and <code class=\"language-javascript\">getLevel<\/code> remains unchanged, but <code class=\"language-javascript\">setLevel<\/code> needs to be changed to:\r\n<pre><code class=\"language-javascript\">    setLevel: function (x) {\r\n        var greenlevels = this._getData('greenlevels'); \r\n        var level = Math.floor(Math.min(greenlevels.length-1, Math.max(0,x))); \r\n        this._setData('level', level); \r\n        this.element.css({background: greenlevels[level]}); \r\n        return this; \/\/ note new return value\r\n    }, \r\n<\/code><\/pre>\r\n<p>I think this will be an improvement, even if it means rewriting all my widgets. I would rather have used a return value of \"<code>undefined<\/code>\" as the flag for a chainable method, since that would not require rewriting regular methods, and getters that intentionally return <code>undefined<\/code> should be few and far between. But no one asked me.<\/p>","protected":false},"excerpt":{"rendered":"Right now UI widgets need to explicitly declare \"getter\" functions (methods that return information about the widget rather than manipulate it) with $.ui.widget.getter = 'gettermethod1 gettermethod2'. The reason is that most jQuery plugins are chainable: $(selector).widget('method').css('color','blue') executes method on each element matched, then css('color','blue') on each element. Some plugins and some uses of plugins instead [&hellip;]","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,5],"tags":[],"_links":{"self":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/594"}],"collection":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/comments?post=594"}],"version-history":[{"count":7,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/594\/revisions"}],"predecessor-version":[{"id":601,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/posts\/594\/revisions\/601"}],"wp:attachment":[{"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/media?parent=594"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/categories?post=594"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bililite.com\/blog\/wp-json\/wp\/v2\/tags?post=594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}