Announcement

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

    [13] ListGrid - Fieldstate vs viewstate

    Hi there,
    we have a problem with the ListGrid in the latest Smartclient 13-Build
    We have used the fieldStateChanged when the viewState of the ListGrid changed, but this method contains no sort information. So we changed to the viewStateChanged which includes the sort information. We thought that the viewStateChanged behaves otherwise the same as fieldStateChanged. But with the viewStateChanged we have the problem that the resizing of the columns does not behave in the same way as fieldStateChanged. With the viewStateChanged only the width of the last adjusted column is passed to the viewState. The width of columns that have been modified before will not be passed to the viewStat.
    Is there any possibility to get both information, the sort information and the resizing of the colums like in fieldStateChanged in the viewState?


    Sidenote: We are removing the "selected" and "open" attributes from the viewstate.
    Also we do calculate the absolute widths of the colums to a percentage-width for each field.
    Code:
    function viewStateWithPercentageWidths(usePercentage, viewState, gridName) {
        var grid = isc.Canvas.getById(gridName);
        var gridWidth = grid.getWidth();
        if (usePercentage) {
            viewState = viewState.replace(/\"width\":(\d*(\.\d*)?)/g, function (s, aWidth) {
                var percentageWidth = "\"width\":";
                if (aWidth != "") {
                    percentageWidth = percentageWidth + "\"" + ((parseInt(aWidth) / gridWidth) * 100) + "%\"";
                }
                return percentageWidth
            });
        } else {
            viewState = viewState.replace(/\"width\":\"(\d*(\.\d*)?)\%\"/g, function (s, aWidth) {
                var realWidth = "\"width\":";
                if (aWidth != "") {
                    realWidth = realWidth + Math.ceil((parseFloat(aWidth) * gridWidth) / 100)
                }
                return realWidth
            });
            viewState = "(" + viewState + ")"
        };
        return viewState
    }
    viewStateChanged -> only the last width but with sorting
    Code:
    viewState: {
       "field":[
          {
             "name":"fieldOne",
             "autoFitWidth":false
          },
          {
             "name":"fieldTwo",
             "autoFitWidth":false
          },
          {
             "name":"fieldThree",
             "autoFitWidth":false,
             "width":"43.10776942355889%"
          }
       ],
       "sort":{
          "sortSpecifiers":[
             {
                "property":"fieldOne",
                "direction":"ascending"
             }
          ]
       },
       "hilite":"[No Hilites]",
       "group":"[No Grouping]",
       "showFilterEditor":false
    }
    fieldStateChanged -> no sorting but all widths
    Code:
    viewState: {
       "field":[
          {
             "name":"fieldOne",
             "autoFitWidth":false,
             "width":"4.385964912280701%"
          },
          {
             "name":"fieldTwo",
             "autoFitWidth":false,
             "width":"34.08521303258145%"
          },
          {
             "name":"fieldThree",
             "autoFitWidth":false,
             "width":"34.21052631578947%"
          }
       ],
       "sort":"[No Sorting],"hilite":"[
          No Hilites
       ]","group":"[
          No Grouping
       ]","showFilterEditor":false}
    Best regards

    #2
    Hi SimonF,

    you have grid = isc.Canvas.getById(gridName). Can't you just call grid.getViewState()?

    Best regards
    Blama
    Last edited by Blama; 24 May 2023, 02:12.

    Comment


      #3
      hi SimonF

      Can you show the setup for your ListGrid? No need for data - in particular, we're interested in your state-changed handlers and any settings related to field-width or auto-fitting at the grid or field level, which can affect viewState content.

      thanks

      Isomorphic Support

      Comment


        #4
        Hi there,
        I had to isolate the problem: therefore I needed some more time.
        Here you can see the problem again in the gif. calling the method getViewState() does return different values after "fieldStateChanged" and "sortChanged".
        In both cases the widths of all columns should be in the viewstate
        Click image for larger version

Name:	001.gif
Views:	170
Size:	74.0 KB
ID:	270268

        I'm aware thats not pretty code, but you can reproduce this behaviour with this code:
        Code:
        var step = 0
        function viewStateWithPercentageWidths(usePercentage, viewState, gridName) {
            var grid = isc.Canvas.getById(gridName);
            var gridWidth = grid.getWidth();
            if (usePercentage) {
                viewState = viewState.replace(/\"width\":(\d*(\.\d*)?)/g, function (s, aWidth) {
                    var percentageWidth = "\"width\":";
                    if (aWidth != "") {
                        percentageWidth = percentageWidth + "\"" + ((parseInt(aWidth) / gridWidth) * 100) + "%\"";
                    }
                    return percentageWidth
                });
            } else {
                viewState = viewState.replace(/\"width\":\"(\d*(\.\d*)?)\%\"/g, function (s, aWidth) {
                    var realWidth = "\"width\":";
                    if (aWidth != "") {
                        realWidth = realWidth + Math.ceil((parseFloat(aWidth) * gridWidth) / 100)
                    }
                    return realWidth
                });
                viewState = "(" + viewState + ")"
            };
            return viewState
        }
        function drawAndSetViewState(gridName) {
            var grid = isc.Canvas.getById(gridName);
            grid.Super("draw");
            if (typeof(grid.percentageViewState) != "undefined") {
                var viewState = viewStateWithPercentageWidths(false, grid.percentageViewState, gridName);
                console.log("Setting viewState: " + viewState);
                grid.setViewState(viewState);
                grid.percentageViewState = undefined
            }
        }
        function logViewState(gridName, sourceString){
            var grid = isc.Canvas.getById(gridName);
            var viewState = JSON.stringify(eval(grid.getViewState()));
            viewState = viewState.replace(/\"selected\":\[.*?\],/g, '');
            viewState = viewState.replace(/\"selected\":\[.*?\]/g, '');
            viewState = viewState.replace(/\"selected\":null.*?,/g, '');
            viewState = viewState.replace(/\"selected\":null.*?/g, '');
            viewState = viewState.replace(/,\"open\":\"\[.*?\]\"/g, '');
            viewState = viewState.replace(/\"open\":\"\[.*?\]\"/g, '');
            viewStatePercentage = viewStateWithPercentageWidths(true, viewState, gridName);
            canvas = step%2==0?canvas1:canvas2;
            step++;
            const output = viewState.replace(/("width":\d+)/g, '<span style="background-color: yellow">$1</span>');
        
            canvas.setContents("<span style='font-size:1.5rem'><b>"+sourceString+":</b>"+output+"</span>");
        
        }
        isc.VLayout.create({width:820, height:600,"members": [
        isc.ListGrid.create(
                             {
                                 "autoDraw": true,
                                 "ID": "theGrid",
                                 "selectionUpdated": function (p1, p2) {
                                 },
                                 "selectionChanged": function (record, state) {
                                 },
                                 "width": "100%",
                                 "height": "60",
                                 "canHover": true,
                                 "hideUsingDisplayNone": false,
                                 "hoverWidth": 200,
                                 "leaveScrollbarGap": true,
                                 "selectionType": "multiple",
                                 "canEdit": false,
                                 "alternateRecordStyles": true,
                                 "autoFitWidthApproach": "both",
                                 "showFilterEditor": false,
                                 "selectionProperty": "isSelected",
                                 "canGroupBy": false,
                                 "saveCriteriaInViewState": false,
                                 "useAdvancedCriteria": false,
                                 "canShowFilterEditor": false,
                                 "allowFilterWindow": false,
                                 "canSaveSearches": false,
                                "percentageViewState":"{\r \"hilite\": \"[No Hilites]\",\r \"group\": \"[No Grouping]\",\r \"field\": [\r \r {\r \"width\": \"20%\",\r \"autoFitWidth\": false,\r \"name\": \"fieldOne\"\r },{\r \"width\": \"20%\",\r \"autoFitWidth\": false,\r \"name\": \"fieldTwo\"\r },\r {\r \"width\": \"60%\",\r \"autoFitWidth\": false,\r \"name\": \"fieldThree\"\r } \r ],\r \"showFilterEditor\": false\r}",
                                 "draw":function(){drawAndSetViewState("theGrid")},
                                 "sortChanged": function (p1) {
                                     logViewState("theGrid","sortChanged")
                                 },
                                 "fieldStateChanged": function () {
                                     logViewState("theGrid","fieldStateChanged")
                                 },
                                 "groupStateChanged": function () {
                                     logViewState("theGrid","groupStateChanged")
                                 },
                                 "initialSort": [{
                                         "property": "fieldEight",
                                         "direction": "descending"
                                     }
                                 ],
                                 "fields":
                                 [{
                                         "name": "fieldOne",
                                         "title": "fieldOne",
                                         "type": "text",
                                         "width": 400,
                                         "canEdit": false,
                                         "canSort": true,
                                         "canGroupBy": false,
                                         "escapeHTML": true,
                                         "shouldPrint": true,
                                         "editorProperties": {
                                             "escapeHTML": true
                                         }
                                     }, {
                                         "name": "fieldTwo",
                                         "title": "fieldTwo",
                                         "type": "text",
                                         "width": 200,
                                         "canEdit": false,
                                         "canSort": true,
                                         "canGroupBy": false,
                                         "escapeHTML": true,
                                         "shouldPrint": true,
                                         "editorProperties": {
                                             "escapeHTML": true
                                         }
                                     }, {
                                         "name": "fieldThree",
                                         "title": "fieldThree",
                                         "type": "boolean",
                                         "width": 200,
                                         "canEdit": false,
                                         "canSort": true,
                                         "canGroupBy": false,
                                         "escapeHTML": false,
                                         "shouldPrint": true,
                                         "editorProperties": {
                                             "escapeHTML": false
                                         }
                                     }
                                 ],
                                 "members":
                                 []
                             }
                             ),
                             isc.Canvas.create({ID: "canvas1"}),
                             isc.Canvas.create({ID: "canvas2"})]})
        Best regards

        Comment


          #5
          Hi there,
          For me the reproduction steps are very clear and in the gifs you can see that in the first case there are 3 widths attributes and in the second there is only one.
          Do you need any additional information for this issue?

          Best regards

          Comment


            #6
            We're looking this over, but a few things in your code:

            1) it's not valid to call Super() when you are not in the base method (as in other programming languages)

            2) viewState / fieldState is not a documented format (by design) so your code to manipulate it is outside of what's supported

            3) you're asserting that the width of all columns should be in the viewState, but this isn't the main way viewState is intended to be used. viewState is more intended as an overlay of the default grid settings, that is, we are trying to capture what the user explicitly changed. This allows things like: the user changed the width for one field, and the base grid changed to add an additional field, and the user's width is respected, but used alongside the new base grid settings.

            Comment


              #7
              Hi there,
              Thansk for the response.

              1) thanks for the clarification, as I stated the code is not pretty, but for the example it did the job

              2) Yes that I have thought of, that the viewstate itself is a propriety format. I can understand that it's neither documented nor supported by default.

              3) I understand the usage of the viewstate to overlay and manipulate the grid as the user has configured. That's what we have in our mind too. We are saving the viewstate (including the widths of the rows, the order of the rows, the sorting, etc). When entering the view again we are delivering the viewstate back to the user. So if the user has changed the widths and order of the fields this is the preference of the user which we would like to set again when the user opens the view. So I don't understand how after changing the sorting (with a call to sortchange) the widths of the rows are irrelevant and not represented in the viewstate?
              Thats the problem that we are focused on since the beginning.

              Best regards

              Comment


                #8
                Without getting too deep, right now when you drag-resize a field, internal code gives all fields temporarily fixed sizes, and that's why you see them all in that case. It isn't clear what you mean by "a call to sortchange", but when you click a header to sort it, the temporary fixed-sizes are not present, so the sizes for *unchanged* fields don't appear in state because, right now, viewState does not include percentage values.

                We're looking at the best way to proceed and will update here shortly.

                In the meantime, can you clarify what you're trying to achieve with this code? It seems like you have existing state which has percentage sizes, and you want to apply those widths to your grid - but it isn't clear why you're converting to and from percentages. Is it just because getViewState() does not include percentage sizes?

                thanks

                Isomorphic SUpport
                Last edited by Isomorphic; 14 Jun 2023, 03:56.

                Comment


                  #9
                  Hi there,

                  We do have multiple users, which do not always work in full-screen. So after a sinlge manipulation of the column all sizes of the columns are saved with the absolute pixel size.
                  When the user reopens the view with another computer or slightly different sized browser and we do apply the previous saved viewstate it does occur often that there is a horizontal scollbar on the bottom. In most cases the user area resizing the column to the fit for their current browser, without the need to scroll horizontally. So doing a conversion to percentage widhts of the colums fixes this to avoid the horizontal scrollbar when reopening the view.

                  The core of this request is that the viewstate behaves different after certain calls.
                  After sortChanged was called (when changing the sorting) the viewState does only has the width only in 1 column.
                  After fieldStateChanged was called (when resizing one column) the viewstate does have the width of all columns.

                  As you have already written, you will take care of it and check what there is a possibility.
                  No matter if a conversion would happen or the viewstate would be stored in localstorage (to be loaded when re-entering): It makes no sense that the resulting viewstate-string looks different (in terms of the column-widths)

                  Best regards

                  Comment


                    #10
                    We agree that it's a bug that after fieldStateChanged, all widths are reported. We'll be fixing that.

                    However, it terms of how fieldState works, to clarify:

                    1) fieldState is expected to include only sizes for fields that the user has manually resized. fieldState will never include percentage widths because users cannot set fields to percentage sizes

                    2) it's invalid to try to apply percentage sizes via fieldState / viewState

                    With this in mind, your sample code is doing multiple invalid things. However, as far as your goal, that's just what naturally happens if you store and re-apply fieldState, at least, it will be again once we've fixed the bug with reporting all widths.
                    Last edited by Isomorphic; 16 Jun 2023, 13:20.

                    Comment


                      #11
                      A quick follow-up - we've addressed the content of fieldState for today's builds, dated June 21 and later.

                      As of those builds, the result of calling getViewState(), generally or from one of the state-change events, will be the same, and will only include width or autoFitWidth settings for fields that have been modified by the user, or if the widths were applied by a previous call to setViewState().
                      Last edited by Isomorphic; 20 Jun 2023, 20:55.

                      Comment

                      Working...
                      X