dojodgrid

dgrid (onDemandGrid) loads on first time button click, but error on second time button is clicked


Thanks to some previous help here, I got the Dojo dgrid to work; and even figured out how to tie it to data from my rest service.

Now I added an input box, a button, and all the logic happens on the button-click. But the second time I click the button, even with the same input value in the input field, I get an error.

ERROR:

TypeError: Cannot read property 'element' of undefined in StoreMixin.js:33

Including the picture so you can see my console.logs enter image description here

I read this How To reset the OnDemandGrid, but is it necessary to check to see if grid exists and do different logic? Can't I just "new up" a new one each time?

CODE:

<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"CustomersGrid"'>
    <label for="lastnameStartsWith">Lastname Starts With:</label>
    <input id="lastnameStartsWith" type="text" name="lastnameStartsWith" value="Wag" 
           data-dojo-type="dijit/form/TextBox"
           data-dojo-props="trim:true, propercase:true" />
    <br />
    <br />  
        <button id="queryStudentsButton" data-dojo-type="dijit/form/Button"
        data-dojo-type="dijit/form/Button" 
        data-dojo-props="iconClass:'dijitIconTask'">
            <span>Query</span>
            <script type='dojo/on' data-dojo-event='click'>
    require([
        'dstore/RequestMemory',
        'dstore/Memory',
        'dgrid/OnDemandGrid'
    ], function (RequestMemory, Memory, OnDemandGrid) {
                    var url = '../students/' + dojo.byId('lastnameStartsWith').value; 
                    console.log("query students for dataGrid latsnameStartsWith:" + dojo.byId('lastnameStartsWith').value);             

                    require(['dojo/request'], function(request){
                        request.get(url,
                             {headers: {"Content-Type": 'application/json',
                                        "username": securityConfig.username,
                                        "password": securityConfig.password}}
                               )
                            .then(function(response){
                                //console.log("string response=" + response); 
                                var respJSON = JSON.parse(response);
                                var respDataForDGrid = respJSON.recordset;
                                console.log("got respJSON back, num rows= " + respDataForDGrid.length);     


                                //================================================          
                                // Create an instance of OnDemandGrid referencing the store
                                console.log("Debug1");             

                                var grid2 = new OnDemandGrid({
                                    collection: new Memory({ data: respDataForDGrid }),
                                    columns: {
                                        student_id: 'ID',
                                        student_firstname: 'First Name',
                                        student_lastname: 'Last Name',
                                        student_city: 'City',
                                        student_state: 'State',
                                        student_zip: 'Zip'
                                    }
                                }, 'grid2');                                    

                                console.log("Debug2");             

                                grid2.startup();
                                console.log("Debug3");             

                             },
                             function(error){
                                console.log("Error=" + error); 
                                //dom.byId('studentFeedback').value += response;
                             }); 
                    });
    });
            </script> 
        </button>
<h2>My demoGrid - From JSON RestService (Database)</h2>
<div id='grid2'></div>

</div>  

Part 2 -

enter image description here

I tried mix of your code and code on this page: How To reset the OnDemandGrid

  if (grid2Registered){
    console.log("reuse existing grid"); 
    grid2Registered.set('collection', memStore);
    // refresh: clear the grid and re-queries the store for data. 
    grid2Registered.refresh();  
    }
    else{...    

Doc here (https://github.com/SitePen/dgrid/blob/v0.4.3/doc/components/core-components/OnDemandList-and-OnDemandGrid.md) says:

Clears the grid and re-queries the store for data. If keepScrollPosition is true on either the instance or the options passed to refresh, an attempt will be made to preserve the current scroll position. OnDemandList returns a promise from refresh, which resolves when items in view finish rendering. The promise resolves with the QueryResults that were rendered.


Solution

  • This one has been tough! Below a working example.

    First I switched from declarative to programmatic for the onClick function: declarative scripts are parsed by dojo, and as a consequence you cannot examine them (set break points, etc.) under the debugger (at least I don't know how to do that). So it seems to me good practice to avoid them.

    Then, indeed the bug is due to re-instantiating the dgrid with the same id, so that you do need a way to detect that the dgrid already exists. But there is a trick: for dgrids to be properly handled by the dijit system, they need to be mixed in with the dijitRegistry extension. See here for details.

    Then you can use registry.byId('grid2') to detect that the dgrid already exists.

    Also I had to skip the respDataForDgrid part and used directly respJSON instead (may be due to a difference with your server side(?) - I used a simple text file with a json array on the server side).

        <!DOCTYPE HTML><html lang="en">
    <head>
    <meta charset="utf-8">
    <title>Neal Walters stask overflow test</title>
    <link rel="stylesheet"
        href="dojo-release-1.12.2-src/dijit/themes/claro/claro.css"
        media="screen">
    <link rel="stylesheet"
        href="dojo-release-1.12.2-src/dgrid/css/dgrid.css" media="screen">
    
    </head>
    <body class="claro">
        <div data-dojo-type="dijit/layout/ContentPane"
            data-dojo-props='title:"CustomersGrid"'>
            <label for="lastnameStartsWith">Lastname Starts With:</label> <input
                id="lastnameStartsWith" type="text" name="lastnameStartsWith"
                value="Wag" data-dojo-type="dijit/form/TextBox"
                data-dojo-props="trim:true, propercase:true" /> <br /> <br />
            <button id="queryStudentsButton" data-dojo-type="dijit/form/Button"
                data-dojo-props="iconClass:'dijitIconTask', onClick: myClick">Query</button>
            <h2>My demoGrid - From JSON RestService (Database)</h2>
            <div id='grid2'></div>
    
        </div>
        <script src="dojo-release-1.12.2-src/dojo/dojo.js"
            data-dojo-config="async:true"></script>
        <script type="text/javascript">
                require(["dojo", "dojo/parser", "dojo/domReady!"],
                function(dojo, parser){
                    parser.parse();
                });
            function myClick(){
            var url = 'students/' + dojo.byId('lastnameStartsWith').value, securityConfig = {username: 'john', password: 'Doe'}; 
                        console.log("query students for dataGrid latsnameStartsWith:" + dojo.byId('lastnameStartsWith').value);             
    
                        require(['dojo/_base/declare', 'dojo/request', "dijit/registry", "dstore/RequestMemory", "dstore/Memory", "dgrid/OnDemandGrid", "dgrid/extensions/DijitRegistry"], function(declare, request, registry, RequestMemory, Memory, OnDemandGrid, DijitRegistry){
                            request.get(url,{})
                                .then(function(response){
                                    console.log("string response=" + response); 
                                    var respJSON = JSON.parse(response);
                                    //var respDataForDGrid = respJSON.recordset;
                                    //console.log("got respJSON back, num rows= " + respDataForDGrid.length);     
    
    
                                    //================================================          
                                    // Create an instance of OnDemandGrid referencing the store
                                    console.log("Debug1");             
                                    var theGrid = registry.byId('grid2');
                                    if (theGrid){
                                        theGrid.set('collection', new Memory({data: respJSON}));
                                    }else{
                                        var grid2 = new (declare([OnDemandGrid, DijitRegistry]))({
                                            collection: new Memory({ data: respJSON }),
                                            columns: {
                                                student_id: 'ID',
                                                student_firstname: 'First Name',
                                                student_lastname: 'Last Name',
                                                student_city: 'City',
                                                student_state: 'State',
                                                student_zip: 'Zip'
                                            }
                                        }, 'grid2');                                    
    
                                        console.log("Debug2");             
    
                                        grid2.startup();
                                        console.log("Debug3"); 
                                    }            
    
                                 },
                                 function(error){
                                    console.log("Error=" + error); 
                                    //dom.byId('studentFeedback').value += response;
                                 }); 
                        });
            };
                </script>
    </body>
    </html>