简体   繁体   中英

How to create customized list item with checkbox?

I've created a qooxdoo list with customized items containing checkbox and label. My problem is: when I check the check box, it gets bigger which gives an ugly user experience. Also when I check some first items and scroll down, I see many items checked which should be unchecked by default.

Here's the code that someone can paste into play ground for qooxdoo :

 // Create a button var button1 = new qx.ui.form.Button("click to see list!", "icon/22/apps/internet-web-browser.png"); // Document is the application root var doc = this.getRoot(); // Add button to document at fixed coordinates doc.add(button1, { left : 100, top : 50 }); var popup; // Add an event listener button1.addListener("execute", function(e) { if (!popup) { popup = new myApp.list(); } popup.placeToWidget(button1); popup.show(); }); /* * class: list inside popup. */ qx.Class.define("myApp.list", { extend : qx.ui.popup.Popup, construct : function() { this.base(arguments); this.__createContent(); }, members : { __createContent : function(){ this.set({ layout : new qx.ui.layout.VBox(), minWidth : 300 }); //prepare data var zones = []; for (var i=0; i<100; i++){ zones.push({"LZN" : "ZONE " + i, "isChecked" : false}); } var lstFences = new qx.ui.list.List(); this.add(lstFences, {flex : 2}); var delegate = { createItem : function() { return new myApp.customListItem(); }, bindItem : function(controller, item, id) { controller.bindProperty("isChecked", "isChecked", null, item, id); controller.bindPropertyReverse("isChecked", "isChecked", null, item, id); controller.bindProperty("LZN", "LZN", null, item, id); } }; lstFences.setDelegate(delegate); lstFences.setModel(qx.data.marshal.Json.createModel(zones)); lstFences.setItemHeight(50); } } }) /** * The custom list item */ qx.Class.define("myApp.customListItem", { extend : qx.ui.core.Widget, properties : { LZN: { apply : "__applyLZN", nullable : true }, isChecked : { apply : "__applyChecked", event : "changeIsChecked", nullable : true } }, construct : function() { this.base(arguments); this.set({ padding : 5, decorator : new qx.ui.decoration.Decorator().set({ bottom : [1, "dashed","#BBBBBB"] }) }); this._setLayout(new qx.ui.layout.HBox().set({alignY : "middle"})); // create the widgets this._createChildControl(("isChecked")); this._createChildControl(("LZN")); }, members : { // overridden _createChildControlImpl : function(id) { var control; switch(id) { case "isChecked": control = new qx.ui.form.CheckBox(); control.set({ padding : 5, margin : 8, value : false, decorator : new qx.ui.decoration.Decorator().set({ width : 2, color : "orange", radius : 5 }) }); this._add(control); break; case "LZN": control = new qx.ui.basic.Label(); control.set({allowGrowX : true}); this._add(control, {flex : 2}); break; } return control || this.base(arguments, id); }, __applyLZN : function(value, old) { var label = this.getChildControl("LZN"); label.setValue(value); }, __applyChecked : function(value, old) { var checkBox = this.getChildControl("isChecked"); console.log(value, old); checkBox.setValue(value); } } }); 

There are two problems here:

The first one is the fact that by creating the checkbox as a subwidget via _createChildControlImpl makes the checkbox loosing its appearance (in sense of qooxdoo theme appearance) leading to the lost minWidth attribute which makes the checkbox having a width of 0 when unchecked and a width which is needed to show the check mark when it's checked. The solution here is to add an appearance to the myApp.customListItem class like this:

properties : { appearance: { refine : true, init : "mycustomlistitem" } } and afterward add a corresponding appearance to your theme: appearances : { "mycustomlistitem" : "widget", "mycustomlistitem/isChecked" : "checkbox" } You could also add all the styling you've done when instantiating the checkboxes (orange decorator etc.) within the appearance definition.

The second problem is that you've defined only a one way binding between the checkbox subwidget of the custom list item and its "isChecked" sub widget. You need a two way binding here, thus if the value of the property "isChanged" changes it's value it prpoagates that to the checkbox and vice versa.

I've modified your playground sample accordingly by creating the missing appearance on the fly and by creating a two way binding between the checkbox and the list items “isChecked” property. Note that I've created the list directly in the app root for simplicity:

https://gist.github.com/level420/4662ae2bc72318b91227ab68e0421f41

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM