Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Overloaded CanvasItem can't getValues()

    I wanted to use some of the ListGrid functionality in a FormItem so I created a FormItem that uses a ListGrid instead of a NativeSelectItem. However, when I put this into a DynamicForm and call DynamicForm.getValues(), I get empty values for these ListItems regardless of what is selected. On the other hand, if I call ListItem.getValue() I get the value just fine. Any idea what I'm doing wrong? My code follows:

    Code:
    // EditableCanvasItem: overloaded CanvasItem with editable values
    isc.ClassFactory.defineClass("EditableCanvasItem","CanvasItem");
    isc.EditableCanvasItem.setProperties({
        shouldSaveValue:true,isEditable: function() { return true; }
    });
    
    // ListItem: overloaded CanvasItem to display a ListGrid as a list box
    isc.ClassFactory.defineClass("ListItem","EditableCanvasItem");
    isc.ListItem.addProperties({
        init: function() {
            this.valueIndex={};
        
            this.canvas=isc.VLayout.create({
                width:"100%",height:"100%",
                members:[
                    isc.Label.create({contents:this.title,autoFit:true,wrap:false}),
                    this.list=isc.ListGrid.create({
                        width:"100%",height:"100%",showHeader:false,canDragSelect:true,
                        fields:[
                            {name:"value",visibility:"hidden"},
                            {name:"displayValue",width:"100%"}
                        ]
                    })
                ]
            });
    
            this.Super("init",arguments);
        },
        getValue: function() {
            var selectedRecords=this.list.getSelection();
            
            var values=[];
            for (var iRecord=0;iRecord<selectedRecords.length;iRecord++) {
                values[iRecord]=selectedRecords[iRecord].value;
            }
            
            return values;
        },
        setValue: function(value) {
            this.list.deselectAllRecords();
        
            if (isc.isAn.Array(value))
                for (var i=0;i<value.length;i++)
                    this.list.selectRecord(this.valueIndex[value[i]]);
        },
        getValueText: function() {
            return this.getValue().toString();
        },
        setListData: function(data) {
            var listData=[];
        
            for (var iValue=0;iValue<data.length;iValue++) {
                if (data[iValue].DisplayValue)
                    listData[iValue]={value:data[iValue].Value,displayValue:data[iValue].DisplayValue};
                else
                    listData[iValue]={value:data[iValue].Value,displayValue:data[iValue].Value};
                    
                this.valueIndex[data[iValue].Value]=iValue;
            }
            
            this.list.setData(listData);
        }
    });

    #2
    Hi ledfini,

    Nice job getting that far.

    The missing piece is that items are intended to notify their forms when values are changed. You can use the selectionChanged() notification on the ListGrid to call setValue() on the form itself (accessible as item.form).

    Note that this will cause the form to call setValue() on your item in turn. You need to ensure this is a no-op and the value remains unchanged - one way to do so is to set a flag which causes your item to ignore a call to item.setValue() during your call to form.setValue().

    This can also be done slightly more cleanly by calling the unfinalized and undocumented FormItem.saveValue() - see widget/form/FormItem.js if curious about that.

    It would be great if you could post your final code, as you've built this as a component others can reuse.

    Comment

    Working...
    X