0

I'm trying to create a list in qooxdoo Mobile that has a checkbox on the side of each item (like in Android's settings menu). I have now extended from list and wrote my own provider and renderer. The files can be found below. Furthermore, a live example of my current progress can be seen here: Example Page

Now what's the status? As you can see, the checkboxes aren't being displayed – but they are there (check the DOM). Overwriting the CSS to display the native checkboxes actually displays them, but the framework boxes just don't show up. My question being: How to solve this? I really think this is worth solving as I believe this would be a contribution many people can benefit from.

Edit: I have already tried wrapping the checkbox in a container, it didn't change anything either.

Files:

qx.ui.mobile.list.CheckBoxList: (on pastebin.org)

qx.Class.define('qx.ui.mobile.list.CheckBoxList', {
    extend : qx.ui.mobile.list.List,

    // overridden
    construct : function (delegate) {
        this.base( arguments );

        this.__provider = new qx.ui.mobile.list.provider.CheckBoxListItemProvider( this );
        if ( delegate ) {
            this.setDelegate( delegate );
        }
    }    
});

qx.ui.mobile.list.provider.CheckBoxListItemProvider (on pastebin.org)

qx.Class.define('qx.ui.mobile.list.provider.CheckBoxListItemProvider', {
    extend : qx.ui.mobile.list.provider.Provider,

    members : {
        // overridden
        _createItemRenderer : function () {
            return new qx.ui.mobile.list.renderer.CheckBoxListItemRenderer();
        }
    }
});

qx.ui.mobile.list.renderer.CheckBoxListItemRenderer (on pastebin.org)

qx.Class.define('qx.ui.mobile.list.renderer.CheckBoxListItemRenderer', {
    extend : qx.ui.mobile.list.renderer.Abstract,

    // overridden
    construct : function () {
        this.base( arguments, new qx.ui.mobile.layout.HBox().set( { alignY: 'middle' } ) );
        this._init();
    },

    members : {
        __title : null,
        __subtitle : null,
        __checkbox : null,
        __leftContainer : null,

        getTitle : function () {
            return this.__title.getValue()
        },

        setTitle : function (title) {
            this.__title.setValue( title );
        },

        getSubTitle : function () {
            return this.__subtitle.getValue();
        },

        setSubTitle : function (subtitle) {
            this.__subtitle.setValue( subtitle );
        },

        getValue : function () {
            return this.__checkbox.getValue();
        },

        setValue : function (checked) {
            this.__checkbox.setValue( checked );
        },

        _init : function () {
            this.__leftContainer = this._createLeftContainer();
            this.add( this.__leftContainer, { flex: 1 } );

            this.__title = this._createTitle();
            this.__leftContainer.add( this.__title );

            this.__subtitle = this._createSubTitle();
            this.__leftContainer.add( this.__subtitle );


            this.__checkbox = this._createCheckBox();
            this.add( this.__checkbox );
        },  

        _createLeftContainer : function () {
            return new qx.ui.mobile.container.Composite( new qx.ui.mobile.layout.VBox() );
        },

        _createTitle : function () {
            var title = new qx.ui.mobile.basic.Label();
            title.addCssClass( 'list-itemlabel' );

            return title;
        },

        _createSubTitle : function () {
            var subtitle = new qx.ui.mobile.basic.Label();
            subtitle.addCssClass( 'subtitle' );

            return subtitle;
        },  

        _createCheckBox : function () {
            var checkbox = new qx.ui.mobile.form.CheckBoxListCheckBox();

            return checkbox;
        },

        // overridden
        _applyShowArrow : function (value, old) {
            return;
        },

        // overriden
        reset : function () {
           this.__title.setValue( '' );
           this.__subtitle.setValue( '' );
           this.__checkbox.setValue( false );
        }
    },   

    // overriden
    destruct : function () {
        this._disposeObjects( '__title', '__subtitle', '__checkbox', '__leftContainer' );
    }
});

qx.ui.mobile.form.CheckBoxListCheckBox (on pastebin.org)

qx.Class.define('qx.ui.mobile.form.CheckBoxListCheckBox', {
    extend : qx.ui.mobile.form.CheckBox,

    members : {
        // overridden
        _onAppear : function () {
            // we purposely don't call this.base( arguments ) because it would create a label that we don't need
            qx.event.Registration.removeListener( this, 'appear', this.__onAppear, this );
        }
    }
});
Ingo Bürk
  • 19,263
  • 6
  • 66
  • 100

1 Answers1

1

The checkbox problem was solved with: af5abf92837255b6b60d30832a63d2a07cd7ae42

Here are some snippets I use for using the checkbox inside a List:

The model of the list is a qx.data.Array which contains several data beans "newGameModelObject" which has a property "checked".

If you change the "checked" property, the list should automatically re-render because of the "changeBubble" event. For firing the "changeBubble" event, the data bean has to include the mixin "MEventBubbling", and the property apply method has to be "_applyEventPropagation"

qx.Class.define("newGameModelObject",
{
  extend : qx.core.Object,
  include : [qx.data.marshal.MEventBubbling],

  properties :
  {
    checked :
    {
      check :"Boolean",
      init : false,
      apply : "_applyEventPropagation"
    }  
  }
});

And here is the list's configureItem part I used:

 this.__list = new qx.ui.mobile.list.List({
        configureItem : function(item, data, row)
        {
          [...]

          var checkBox = new qx.ui.mobile.form.CheckBox(data.getChecked());
          checkBox.addListener("changeValue", function(evt){
            var item4change = self.__list.getModel().getItem(row);
            item4change.setChecked(evt.getData());
          });

          item.addToButtonContainer(checkBox);
        },

        createItemRenderer : function() {
          return new renderer.Button();
        }
      }
 );

You have to create the checkBox on configureItem and add it into the ButtonContainer. Then you have to listen to "changeValue" event on it and change the checked state of the row item. Now the model updates itself and triggers a re-rendering of the list >> the checkbox displays the new state.

Hope that helps to finally solve your problem.

Greetz Christopher

czuendorf
  • 853
  • 6
  • 9