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

    Dynamically adding DataSourceField and ListGridField

    I am using SmartClient_v121p_2020-04-14_PowerEdition.

    Is it possible to add a column (field) to a DataSource and ListGrid after the initial DS and grid definitions were declared? I have a grid backed by a client only datasource. The grid displays a list of tests. When a test is run, I will receive a result that I want to display. When the test result comes in, I have tried adding a new field to both the DataSource and the ListGrid and then updating the row in the DataSource with the test response. I've tried several variations of invalidating the caches on both the DataSource and ListGrid, but nothing seems to be working. In the code snippet below, what happens is that when the first result comes in, the last column is updated with the data (but not the column header until I hover over it, and then the header title updates), essentially erasing whatever was in that column. Subsequent data is not displayed, although in the debugger, when I look at the values of "fields" for both, the new columns appear to exist. So, the underlying data is there. Am I missing something simple here?

    function addTestResult(result) {

    const testType = result.testType;

    // Build the data source and the grid IDs and check if they exist
    const dsID = testType + "_DS";
    const gridID = testType + "_grid";
    let testDS = window[dsID];
    let testGrid = window[gridID];

    // If these exist, add the result
    if( testDS && testGrid ) {

    // The column name should be the time that the result came in.
    const time = result.time;

    // Check to see if the data source contains the column
    let dsField = testDS.getField(time);
    if( dsField === undefined ) {
    // Build the field definition
    let field = {name: time, title: time, width: 80, canSort: false, align: "center"};

    // Add this field to the data source and the grid.
    // Add the field at the second to last column.
    // Per the documentation, addAt puts the item at the specified position and moves everything else over, so
    // make the position the last one so that it'll insert it there and then move the last column over.
    const numCols = testGrid.fields.length;
    let position = 0;
    if( numCols > 0 ) {
    position = numCols - 1;
    // NOTE: For some reason, the DS fields don't show up as an array, but a JSON object,
    // even though the documentation says fields is an Array.
    testDS.fields[time] = field;
    testGrid.fields.addAt(field, position);

    // Now that the time column exists, we can add the data
    // Get the row that the result belongs on
    // See if the row exists (it should because we create all rows at initialization)
    let testData = testDS.getCacheData();
    if( testData !== undefined ) {
    let row = testData.find({testName: result.testName});
    if( row !== null ) {
    row[time] = result.testResponse;


    testGrid.scrollToColumn(testGrid.fields.length - 1);

    There is no need to dynamically add a field here. Define the test result column ahead of time in the DataSource, and if you don't want it shown initially, just hide it (listGridField.hidden, or showIf, or hideField() / showField()).


      I apologize if I wasn't clear in my explanation. I will have multiple test result columns, but there is no way to know how many I will have on initialization. Each time a result comes in, I have to display the results in its own column based on the time I received the result.

      For instance, my fields will initially look like this (simply showing the column headers to make it easy):
      testName, run

      The user will run the test and when the result comes in, it would look like this:
      testName, 10:45, run

      The next result that comes in:
      testName, 10:45, 11:15, run

      And so on.....a new time column will be added for each result. Hope this makes better sense!


        You cannot add new columns to a DataSource after creation (if you think it through, this has a ridiculous amount of ambiguities). You can however, have non-DS columns in your ListGrid. Just create the new set of fields and call setFields(). Trying to directly modify the fields array is never allowed.