Announcement

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

    List grid appears empty after underlying data update

    I'm using: SmartClient_v110p_2017-05-15_PowerEdition

    I have a 3 pane application with the typical tree in pane 1 and listgrid in pane 2. Selecting a record in the listgrid causes various details to become visible in the several detail tabs of pane 3. So far this works fairly well, however today I discovered a situation where saving a value in one of the detail panes to the table associated with the listgrid in pane 2 causes that grid to appear empty "No items to show" is displayed. To complicate matters the pane 2 listgrid datasource is bound to an SQL view that merges 6 tables. The detail pane form that makes the change uses another datasource bound to one of the undelying tables of the view.

    I tried adding code to refresh the grid and reselect the record after the save operation, but that fails because the reselect fires before the refresh completes and get's ignored by the grid.

    Am I missing some clean builtin functionality to refresh the listgrid and keep the selection after the save?

    Or

    Is there a way to get the selectSingleRecord call to wait until after the refresh has completed?

    The listGrid:

    isc.ListGrid.create({
    ID:"peopleListGrid",
    autoDraw:false,
    autoFetchData:true,
    dataSource:"peopleGrid", //This datasource is a view that connects the people table to 5 related tables to facilitate searching
    reselectOnUpdate:true,
    initialCriteria:{
    fieldName:"active",
    operator:"equals",
    value:1.0
    },
    fields:[

    ...Omitting lots of fields here..

    ],
    showFilterEditor:true,
    sortDirection:true,
    canGroupBy:true,

    recordClick: {
    target:"peopleDetailTabs",
    name:"updateDetails"
    },
    selectionUpdated: {
    target:"peopleDetailTabs",
    name:"updateDetails"
    },
    filterEditorSubmit: {
    target:"peopleDetailTabs",
    name:"clearDetails"
    }
    })


    The form:

    isc.DynamicForm.create({
    ID:"copierBaseCode",
    autoDraw:false,
    dataSource:"people", //This is a simple one table datasource
    fields:[
    {
    name:"personalCode",
    title:"Base Code",
    _constructor:"TextItem"
    }
    ],
    // This function is called by clicking a button.
    getCode: function () {
    // Retrieve the person's personalCode or generate a new, unique, random one if it doesn't exist
    var record = peopleListGrid.getSelectedRecord();
    if(record == null) return null;
    if(/[0-9]{4}/.test(record.personalCode)) {
    myCode = record.personalCode;
    } else {
    myCode = Math.floor(Math.random()*(9999-1000))+1000;
    while (peopleListGrid.fetchData({personalCode:myCode}) != null) {
    myCode = Math.floor(Math.random()*(9999-1000))+1000;
    }
    this.editRecord({id_People:record.id_People,personalCode:myCode});
    this.saveData();

    // I thought the following 2 function calls would redraw the grid and reselect the person, but the selectSingleRecord() call get's ignored by the grid during refresh.
    //topToolStripFilterForm.findPeople();
    //peopleListGrid.selectSingleRecord({id_People:record.id_People});
    }
    return myCode;
    }
    })

    #2
    Solved.

    I'm a little bummed that I haven't (yet) found some more clever solution, but I do have code that works to re-draw the grid and re-select the person being worked on.



    isc.DynamicForm.create({
    ID:"copierBaseCode",
    autoDraw:false,
    dataSource:"people",
    fields:[
    {
    name:"personalCode",
    title:"Base Code",
    _constructor:"TextItem"
    }
    ],
    //This function is called by clicking a button to begin editing a new code entry
    getCode: function () {
    // Retrieve the person's personalCode or generate a new, unique, random one if it doesn't exist
    var record = peopleListGrid.getSelectedRecord();
    if(record == null) return null;
    if(/[0-9]{4}/.test(record.personalCode)) {
    myCode = record.personalCode;
    } else {
    myCode = Math.floor(Math.random()*(9999-1000))+1000;

    var startingCriteria = peopleListGrid.getCriteria(); //Save the criteria to generate the current view of the grid

    while (peopleListGrid.fetchData({personalCode:myCode}) != null) {
    myCode = Math.floor(Math.random()*(9999-1000))+1000;
    }
    this.editRecord({id_People:record.id_People,personalCode:myCode});
    this.saveData();

    // Call filterData with the saved criteria and a callback to select the correct person
    // has the effect of re-drawing the grid the way it was before the save.
    peopleListGrid.filterData(
    startingCriteria,
    function() {peopleListGrid.selectSingleRecord({id_People:record.id_People})});
    }
    return myCode;
    }
    })

    Comment


      #3
      See getSelectedState()/setSelectedState().

      We're not sure how you are ending up clearing out all the data in your grid, however, as that's not necessary or normal. See the ResultSet docs for a discussion of automatic cache sync.

      Comment


        #4
        So the function I posted earlier was a really bad effort at checking if a randomly generated number is already present in the datasource (isUnique). The much better solution is to use validation. Validiation eliminates the need for the

        peopleListGrid.fetchData({personalCode:myCode}) != null

        condition which was the line that was clearing the grid.

        This function randomly generates a number, takes advantage of an isUnique validator on the datasource to avoid collisions and calls itself recursively in the rare case where the randomly generated value already exists in the database. Thus the problem of the vanishing grid contents is avoided by not doing things that are dumb and don't work as expected anyway.


        getCode: function (recursionDepth) {
        // Retrieve the person's personalCode or generate a new, unique, random one if it doesn't exist
        if(typeof recursionDepth != 'number') recursionDepth = 0;
        var record = peopleListGrid.getSelectedRecord();
        if(record == null) return null;
        var myCode;
        if(/[0-9]{4}/.test(record.personalCode)) {
        myCode = record.personalCode;
        } else {
        myCode = Math.floor(Math.random()*(9999-1000))+1000;
        this.editRecord({id_People:record.id_People,personalCode:myCode});
        this.checkForValidationErrors(function (errorMap) {
        if(errorMap && recursionDepth < 5) {
        recursionDepth++;
        copierBaseCode.getCode(recursionDepth);
        } else {
        copierBaseCode.saveData();
        }
        });
        }
        return myCode;
        }

        Comment

        Working...
        X