Announcement

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

    Formula Builder patch

    Hello,

    We've had to develop a patch for Formula Builder. I'm not sure if the existing implementation gets broken in ways we aren't seeing by our patch. But, I'll show you an example and you can let me know.

    Use this example:
    http://www.smartclient.com/docs/8.3/a/system/reference/SmartClient_Explorer.html#offlinePrefs

    Use this sample code:
    Code:
    var ds = isc.DataSource.get("countryDS");
    
    isc.VLayout.create({
        ID:"layout",
        width:500, height:250,
        members: [
            isc.HLayout.create({
                ID:"buttonLayout",
                width:"*", height:30,
                membersMargin: 10,
                members: [
                    isc.IButton.create({
                        ID: "formulaButton",
                        autoFit: true,
                        title: "Show Formula Builder",
                        click: "countryList.addFormulaField();"
                    }),
                    isc.IButton.create({
                        ID: "stateButton",
                        autoFit: true,
                        title: "Persist State",
                        click: function () {
                            var state = countryList.getViewState();
                            isc.Offline.put("exampleState", state)
                        }
                    }),
    
                    isc.IButton.create({
                        ID: "stateButton",
                        autoFit: true,
                        title: "Persist State 2",
                        click: function () {
                            var state = countryList.getViewState();
                            isc.Offline.put("exampleState2", state)
                        }
                    })    ,
    
    ,
    
                    isc.IButton.create({
                        ID: "stateButton",
                        autoFit: true,
                        title: "Change to State 2",
                        click: function () {
                            var savedState = isc.Offline.get("exampleState2");
    if (savedState) {
        countryList.setViewState(savedState);
    }
                        }
                    })    
            ]
            })
        ]
    });
    
    layout.addMember(isc.ListGrid.create({
        ID: "countryList",
        width:"100%", height:"*",
        alternateRecordStyles:true, cellHeight:22,
        dataSource: ds,
        autoFetchData: true,
        canAddFormulaFields: true,
        canAddSummaryFields: true,
        fields:[
            {name:"countryCode", title:"Flag", width:50, type:"image", imageURLPrefix:"flags/16/", 
                imageURLSuffix:".png"
            },
            {name:"countryName", title:"Country"},
            {name:"capital", title:"Capital"},
            {name:"population", title:"Population", formatCellValue:"isc.Format.toUSString(value)"},
            {name:"area", title:"Area (km²)", formatCellValue:"isc.Format.toUSString(value)"},
            {name:"gdp", formatCellValue:"isc.Format.toUSString(value)"}
        ]
    }));
    
    var savedState = isc.Offline.get("exampleState");
    if (savedState) {
        countryList.setViewState(savedState);
    }
    
    
        isc.Canvas.getPrototype().addProperties({
            
            
            //12/10/12..added logic to clear our cached formula reference with commented logic
            //this caused issues when switching between views that shared common formula names
            //like formulaField1
            getFormulaFunction: function(_1){
                if(!_1.userFormula)return null;
                //12/10/12..comment this line
                var _2=_1.$65w;if(_2!=null)return _2;
                _2=_1.$65w=_1.sortNormalizer=isc.FormulaBuilder.generateFunction(_1.userFormula,this.getAllFields(),this);return _2
            }
    
    })

    Steps:

    1. Load example and add a formula column that adds columns B and C together. Click Persist State.

    2. Reload the page and this new view state and formula column are loaded.

    3. Edit the formula column like this: "B - C " so you are subtracting the two instead of adding them. Change the formula name as well so you can be sure you've loaded the new formula in next steps. Click "Persist State 2" to save this state into a separate offline variable

    4. Reload the page and the first view state with the "B + C" formula field loads.

    5. Click "Change to State 2" and the second view state with "B - C" loads. However, the formula has not been updated to the formula associated with State 2.

    6. I've included the proposed patch at the bottom of the code. Here it is again. Except this time I've commented out this line:

    // var _2=_1.$65w;if(_2!=null)return _2;

    Code:
            
            //12/10/12..added logic to clear our cached formula reference with commented logic
            //this caused issues when switching between views that shared common formula names
            //like formulaField1
            getFormulaFunction: function(_1){
                if(!_1.userFormula)return null;
                //12/10/12..comment this line
               // var _2=_1.$65w;if(_2!=null)return _2;
                _2=_1.$65w=_1.sortNormalizer=isc.FormulaBuilder.generateFunction(_1.userFormula,this.getAllFields(),this);return _2
            }
    7. Run this example again after applying the patch and you'll see the "State 2" formula is now displaying correctly. So, it seems that getFormulaFunction is loading an incorrectly cached version of the formula because they share the name "formulaField1" and the variable $65w is caching it. So, with the patch we ignore variable $65w and generate the function via generateFunction each time the view is loaded and that seems to solve the problem? is this a valid patch or will this create other problems we aren't seeing yet?

    #2
    This patch disables caching of the formulaFunction.
    The getFormulaFunction method is potentially run a very large number of times (for every row to get the display value for the field, to get the sorting value, etc), so the danger of disabling this caching is that you'll encounter a performance hit as the function is being recreated every time the method is run.

    If you *have* to patch an existing build, a better solution might be to clear that cached function when you know it to be stale (IE on the call to setViewState()).

    Of course we'll take a look at whether the underlying issue exists in the latest codebase and fix it there too and update this thread when we have a fix in place so you can update to a patched nightly build

    Regards
    Isomorphic Software

    UPDATE: Also please note that the sample code includes duplicated widget ID's (3 buttons called "stateButton"). This is unsupported - ID's have to be unique in the page. This is probably not responsible for the behavior you're seeing, but you should definitely give them unique IDs when testing and of course within your app!
    Last edited by Isomorphic; 11 Dec 2012, 17:10.

    Comment


      #3
      In fact we've gone ahead and made the appropriate change to our codebase, so this issue should be resolved as of the next nightly build

      Regards
      Isomorphic Software

      Comment


        #4
        Patch looks good, thank you.

        Comment

        Working...
        X