如何在使用小部件工厂创建的另一个内部使用jQuery UI小部件

时间:2014-03-10 18:52:46

标签: javascript jquery jquery-ui widget

我正在尝试创建一个简单的jQuery UI小部件,用作开/关切换器。它实际上只不过是一个单选按钮组。它本身工作正常,但是如果我在页面上有多个这样的小部件,则返回的值始终是最后创建的实例的值。

我理解为什么这是 - 与buttonset绑定的更改事件引用'self',这是在创建实例时设置的,但它确实需要指向创建单选按钮和按钮集的实例。

所以我的问题是:如何修复更改事件函数,以便它可以为正确的窗口小部件实例调用窗口小部件的value()函数?

我在这里有一个(粗略写的)jsfiddle:http://jsfiddle.net/38Qwy/

代码:

(function($) {

$.widget('custom.onoff', {
    options: {
        value: 0,
        captionOn: "on",
        captionOff: "off"
    },

    radios: {},

    _create: function() {
        this.oldValue = 2;

        var self = this,
        o = self.options,
        el = self.element,
        r = self.radios,
        htmlValue = el.html();
        el.html(''); // clear html content before appending elements
        var radOn = $('<input type="radio">').uniqueId().appendTo(el),
        radOnLabel = $('<label id="lab_' + radOn.attr('id')+'" for="' + radOn.attr('id') + '">' + o.captionOn + '</label>').appendTo(el),
        radOff = $('<input type="radio">').uniqueId().appendTo(el),
        radOffLabel = $('<label id="lab_' + radOff.attr('id')+'" for="' + radOff.attr('id') + '">' + o.captionOff + '</label>').appendTo(el);

        radOn.attr('name',radOn.attr('id'));
        radOff.attr('name',radOn.attr('id'));

        $(el).buttonset();

        this.radios.htmlValue = htmlValue;

        if(parseInt(htmlValue) == htmlValue) { // if the html content of the div is 0 or 1, use that to set or reset the switch
            if(htmlValue == 0 || htmlValue == 1)
                o.value = parseInt(htmlValue);
        }

        this.radios.radOn = '#' + radOn.attr('id');
        this.radios.radOff = '#' + radOff.attr('id');
        this.radios.radOnLabel = '#' + radOnLabel.attr('id');
        this.radios.radOffLabel = '#' + radOffLabel.attr('id');
        this.radios.name = radOn.attr('id');

        $('[name='+self.radios.name+']').change(function() {
            var val = $( self.radios.radOn ).is(':checked');
            var oldval = self.options.value == 1;
            if(val != oldval)
                self.value(val);
        });

        self.value(o.value);
    },

    destroy: function() {
        var self = this;
        var r = self._radios;
        var el = self.element;

        el.button('destroy');
        $(r.radOn).remove();
        $(r.radOff).remove();
        $(r.radOnLabel).remove();
        $(r.radOffLabel).remove();

        el.html(this.radios.htmlValue);
    },

    _setOption: function(option, value) {
        $.Widget.prototype._setOption.apply( this, arguments );

        switch (option) {
            case "captionOn":
                $(this.radios.radOnLabel).html(value);
                break;
            case "captionOff":
                $(this.radios.radOffLabel).html(value);
                break;
            case "value":
                this.value(value);
                break;
        }   
    },

    value: function( newValue ) {
        if ( newValue === undefined ) {
            return this.options.value;
        }

        if (newValue === false )
            newValue = 0;

        if (newValue === true )
            newValue = 1;

        this.options.value = newValue;
        this._refreshValue();
    },

    _refreshValue: function() {
        var value = this.options.value;

        if ( this.oldValue != value ) {
            this.oldValue = value;

            if(value == 1) {
                $(this.radios.radOn).prop('checked',true).button("refresh");
            } else {
                $(this.radios.radOff).prop('checked',true).button("refresh");
            }

            this._trigger( "change" );
        }
    }

}); // widget

})(jQuery);

更新 问题解决了,新的jsfiddle在这里:http://jsfiddle.net/74B4w/

2 个答案:

答案 0 :(得分:0)

要回答标题中提出的问题,请执行以下操作:$.widget( "custom.superDialog", $.ui.dialog, {} ); Docs

现在来看看你的代码......

答案 1 :(得分:0)

简而言之,我需要做的就是在更改包含的按钮集时调用我的widget的change()函数。然后,change()函数可以读取'on'单选按钮的状态并存储新值,以及触发事件。

this._container.buttonset().change(function() {
    this._change();
}.bind(this))
.appendTo(this.element);    

工作解决方案:http://jsfiddle.net/74B4w/