Question

I have this code that loads a data store for all stories that contain each of the names from an array.

var prefix_set = [list of names]
for(var i=0;i<prefix_set.length;i++)
   _get_stories_of_feature(prefix_set[i]) //this function creates a data store

I am storing all the data into a global array and creating a data store which is passed to a grid in the end. The problem is that my grid loads up with incomplete data (the grid loads up even before all the data has been loaded into the global array).

Here's my code:

Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
items:[{ xtype: 'container', itemId: 'print_button_box', padding: 5},{xtype: 'container', itemId: 'grid_box'}],
count: 0,
globalStore: null,
totalDataLength: 0,
gridCounter: 0,
launch: function() {
    var me = this;
    this.globalStore = null;
    this.gridCounter = 0;
    this.totalDataLength=0;
    this.count = 0;
    this._addPrintButton();
     list = [];
    //Write app code here
    var prefix_set = ["Epic:","Arch:","Refa:","Innov:","Spike:","Producer:","Dependency:","Consumer:"];
    var i;
    for(i=0;i<prefix_set.length;i++){

        this._get_stories_of_feature(prefix_set[i],prefix_set.length,i);

    }

},
_addPrintButton: function() {
    var me = this;
    this.down('#print_button_box').add( { 
        xtype: 'rallybutton', 
        itemId: 'print_button',
        text: 'CSV',
        disabled: false,
        handler: function() {
           console.log('globalStore ',me.globalStore);

            me.exportGrid(me.globalStore);

        }
    });
},
_onClickExport: function () {

     if (document.getElementById('grid_box')) {

        //Ext.getBody().mask('Exporting Tasks...');
        console.log('inside export');
        setTimeout(function () {
            var template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-' +
                'microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head>' +
                '<!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>' +
                '{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>' +
                '</x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}' +
                '</table></body></html>';

            var base64 = function (s) {
                return window.btoa(unescape(encodeURIComponent(s)));
            };
            var format = function (s, c) {
                return s.replace(/{(\w+)}/g, function (m, p) {
                    return c[p];
                });
            };
            var table = document.getElementById('grid_box');
            console.log("Exporting table ",table);
            var excel_data = '<tr>';
            Ext.Array.each(table.innerHTML.match(/<span .*?x-column-header-text.*?>.*?<\/span>/gm), function (column_header_span) {
                excel_data += (column_header_span.replace(/span/g, 'td'));
            });
            excel_data += '</tr>';
            Ext.Array.each(table.innerHTML.match(/<tr class="x-grid-row.*?<\/tr>/gm), function (line) {
                excel_data += line.replace(/[^\011\012\015\040-\177]/g, '>>');
            });
            console.log("Excel data ",excel_data);
            var ctx = {worksheet: name || 'Worksheet', table: excel_data};
            window.location.href = 'data:application/vnd.ms-excel;base64,' + base64(format(template, ctx));
            Ext.getBody().unmask();
        }, 500);
    }else{
        console.log("grid_box does not exist");
    }
},
tableToExcel: function(){
    var me = this;
    console.log("Global store ",me.globalStore);
     var uri = 'data:application/vnd.ms-excel;base64,'
    , template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>'
    , base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))); }
    , format = function(s, c) { return s.replace(/{(\w+)}/g, function(m, p) { return c[p]; }); };

     return function(table, name) {
    if (!table.nodeType) table = document.getElementById(table);
    var ctx = {worksheet: name || 'Worksheet', table: table.innerHTML};
    window.location.href = uri + base64(format(template, ctx));
  };
},
_createStore: function(){
    var me = this;
    //var f = [{property: 'UserStories', operator: '!=', value: null}];
    Ext.create('Rally.data.WsapiDataStore',{
        autoLoad: true,
        model: "PortfolioItem/Feature",
        limit: 10000,
        fetch: ['FormattedID','Name','UserStories','c_DIteration','c_DPSI'],


        listeners:{
            load: function(store,data,success){

                console.log("Store ",store);
                var data_length = data.length;
                console.log('Data length is '+data.length);
                Ext.Array.each(data,function(item){
                    if(item.get('UserStories')==null){
                        store.remove(item);
                    }else{
                        var data = {
                            id: item.get("FormattedID"),
                            name: item.get("Name"),
                            UserStories: item.get("UserStories")._type,
                            DIteration: item.get("c_DIteration"),
                            DPSI: item.get("c_DPSI")
                        };
                        //list.push(data);
                    }


                    me._get_stories_of_feature(item.get("ObjectID"),item.get("Name"),data_length);
                });

            },
            scope: this
        }
    });
},
_showGrid: function(store){
    var me = this;
    if(!this.grid){
        this.grid = Ext.create('Rally.ui.grid.Grid',{
            store: store,
            columnCfgs:[
                {text: 'Feature', dataIndex: 'name'},
                {text: 'FormattedID', dataIndex: 'FormattedID'},
                {text: 'Name', dataIndex: 'UserStories'},
                {text: 'Release', dataIndex: 'Release'},
                {text: 'Iteration', dataIndex: 'Iteration'},
                {text: 'DIteration', dataIndex: 'DIteration'},
                {text: 'DPSI', dataIndex: 'DPSI'},
                {text: 'Schedule State', dataIndex: 'ScheduleState'},
                {text: 'Task Remaining Total', dataIndex: 'TaskRemainingTotal'},
                {text: 'Owner', dataIndex: 'Owner'},,
                {text: 'Project', dataIndex: 'Project'},
                {text: 'Unscheduled', dataIndex: 'Unscheduled'}
            ]
        });
        me.globalStore = this.grid;
        this.down('#grid_box').add(this.grid);
    }
},
_get_stories_of_feature: function(name,length,k){
    var me = this;
    Ext.create('Rally.data.WsapiDataStore',{
        autoLoad: true,
        model: "HierarchicalRequirement",
        limit: 10000,
        fetch: ['Name','ObjectID','FormattedID','Parent','Feature','TaskRemainingTotal','c_DIteration','c_DPSI','DragAndDropRank','Release','Iteration','Project','Owner','ScheduleState'],
        sorters:[{
            property: 'DragAndDropRank', direction: 'ASC'
        ,},{property: 'Project', direction: 'ASC'}],
        filters:[{
            property: 'Name', operator: 'contains', value: name
        },{
            property: 'ScheduleState', operator: '!=', value: 'Accepted'
        }],
        pageSize: 5000,
        listeners:{
            load: function(store,data,success){

                var data_length = data.length;

                if(data_length>0){
                    console.log("Total stories ",data_length);
                    for(var i=0;i<data_length;i++){
                        console.log("Data length for ",k," is ",data_length);

                        console.log("Data i ",data[i]);
                            me.totalDataLength++;
                            var flag;
                            var iteration=""; var release="";
                            var fid = "",fname="";
                            var owner="";
                            if(data[i].data.Feature!=null && (data[i].data.Feature.c_DIteration==null || data[i].data.Feature.c_DIteration.toString().indexOf("*")!=-1))
                                 flag = "YES";
                            else flag = "NO";

                            if(data[i].data.Iteration!=null){
                                iteration = data[i].data.Iteration._refObjectName;
                            }
                            if(data[i].data.Release!=null){
                                release = data[i].data.Release._refObjectName;
                            }
                            if(data[i].data.Owner!=null){
                                owner = data[i].data.Owner._refObjectName;
                            }
                            if(data[i].data.Feature!=null){
                                fid = data[i].data.Feature.FormattedID;
                                fname = data[i].data.Feature.Name; 
                            }
                            var element = {
                                name: fid+":"+fname,
                                UserStories: data[i].data.Name,
                                Project: data[i].data.Project._refObjectName,
                                Owner: owner,
                                FormattedID: data[i].data.FormattedID,
                                Iteration: iteration,
                                TaskRemainingTotal: parseInt(data[i].data.TaskRemainingTotal),
                                Release: release,
                                ScheduleState: data[i].data.ScheduleState,
                                DIteration: data[i].data.c_DIteration,
                                DPSI: data[i].data.c_DPSI,
                                Unscheduled: flag                                   
                            };
                            list.push(element);

                            console.log("me count is ",me.count);
                            console.log("Found ",data[i].data);

                            me.count++;
                    }
                }
                console.log("Total Data Length is ",me.totalDataLength);
                console.log("k is ",k," and length is ",length);
                if(k==length-1){
                    console.log("Building store");
                    //once all the stories and feature data is computed
                    var myStore = Ext.create("Rally.data.custom.Store",{
                    data: list,
                    sortable: true,
                    pageSize: me.totalDataLength,

                });
                me._showGrid(myStore);  
                }


            }

        }
    });
    me.gridCounter++;

},
 exportGrid: function(grid) {
    if (Ext.isIE) {
        this._ieToExcel(grid);

    } else {
        var data = this._getCSV(grid);

        window.location = 'data:text/csv;charset=utf8,' + encodeURIComponent(data);
    }
},

_escapeForCSV: function(string) {
    if (string.match(/,/)) {
        if (!string.match(/"/)) {
            string = '"' + string + '"';
        } else {
            string = string.replace(/,/g, ''); // comma's and quotes-- sorry, just loose the commas
        }
    }
    return string;
},

_getFieldText: function(fieldData) {
    var text;

    if (fieldData == null || fieldData == undefined) {
        text = '';

    } else if (fieldData._refObjectName && !fieldData.getMonth) {
        text = fieldData._refObjectName;

    } else if (fieldData instanceof Date) {
        text = Ext.Date.format(fieldData, this.dateFormat);

    } else if (!fieldData.match) { // not a string or object we recognize...bank it out
        text = '';

    } else {
        text = fieldData;
    }

    return text;
},

_getFieldTextAndEscape: function(fieldData) {
    var string  = this._getFieldText(fieldData);

    return this._escapeForCSV(string);
},

_getCSV: function (grid) {
    var cols    = grid.columns;
    var store   = grid.store;
    var data    = '';
console.log("Grid.Store is ",grid.store);
    var that = this;
    Ext.Array.each(cols, function(col, index) {
        if (col.hidden != true) {
            data += that._getFieldTextAndEscape(col.text) + ',';
        }
    });
    data += "\n";

    store.each(function(record) {
        var entry       = record.getData();
        Ext.Array.each(cols, function(col, index) {
            if (col.hidden != true) {
                var fieldName   = col.dataIndex;
                var text        = entry[fieldName];

                data += that._getFieldTextAndEscape(text) + ',';
            }
        });
        data += "\n";
    });

    return data;
},

_ieGetGridData : function(grid, sheet) {
    var that            = this;
    var resourceItems   = grid.store.data.items;
    var cols            = grid.columns;

    Ext.Array.each(cols, function(col, colIndex) {
        if (col.hidden != true) {
            console.log('header: ', col.text);
            sheet.cells(1,colIndex + 1).value = col.text;
        }
    });

    var rowIndex = 2;
    grid.store.each(function(record) {
        var entry   = record.getData();

        Ext.Array.each(cols, function(col, colIndex) {
            if (col.hidden != true) {
                var fieldName   = col.dataIndex;
                var text        = entry[fieldName];
                var value       = that._getFieldText(text);

                sheet.cells(rowIndex, colIndex+1).value = value;
            }
        });
        rowIndex++;
    });
},

_ieToExcel: function (grid) {
    if (window.ActiveXObject){
        var  xlApp, xlBook;
        try {
            xlApp = new ActiveXObject("Excel.Application"); 
            xlBook = xlApp.Workbooks.Add();
        } catch (e) {
            Ext.Msg.alert('Error', 'For the export to work in IE, you have to enable a security setting called "Initialize and script ActiveX control not marked as safe" from Internet Options -> Security -> Custom level..."');
            return;
        }

        xlBook.worksheets("Sheet1").activate;
        var XlSheet = xlBook.activeSheet;
        xlApp.visible = true; 

       this._ieGetGridData(grid, XlSheet);
       XlSheet.columns.autofit; 
    }
}



});
Was it helpful?

Solution

Please take a look at the code in this post, where Mark uses promises, and builds three separate Rally.data.wsapi.Stores and only after all the data is there _makeGrid(resultArray) is called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top