Why won't my dojo grid display in my bootstrap dialog box?

8630
19
Jump to solution
07-31-2015 11:57 AM
ChrisSergent
Regular Contributor III

I am using this sample here: http://www.w3schools.com/bootstrap/bootstrap_modal.asp  to attempt to create a bootstrap dialog box. The only problem is I can't get the dojo grid to display inside of my modal dialog box. What am I doing wrong?

Here is my code with references as to where I am trying to display the modal and the grid.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="http://js.arcgis.com/3.14/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.14/dojox/grid/resources/Grid.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.14/dojox/grid/resources/claroGrid.css">
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>


    <title></title>


    <style>
        #myModal {
            height:80%;
        }
    </style>
    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
       <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.min.js"></script>
       <script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
    <script type="text/javascript">
    var dojoConfig = {
        parseOnLoad: true,
        isDebug: true,
        locale: 'en-us',
        extraLocale: ['ja-jp']
    };
    </script>


    <!-- This will not work if you set the html lang https://community.esri.com/thread/81475 -->
  <script src="http://js.arcgis.com/3.14/"></script>
   <style>
       .modal-body, #grid
       {
           height:500px;
       }
      
   </style>


</head>
<body class="claro">
    <label id="lblOwnerAddress" for="ownerAddress">Owner's Address</label>
    <input type="text" id="ownerAddress" name="ownerAddress" value="111 S Main" />
    <div class="container">
       


        <!-- Modal -->
        <div class="modal fade" id="myModal" role="dialog">
            <div class="modal-dialog">


                <!-- Modal content-->
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal">&times;</button>
                        <h4 class="modal-title">Modal Header</h4>
                    </div>
                    <div class="modal-body">
                        <table data-dojo-type="dojox/grid/DataGrid" data-dojo-id="grid" id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px'">
                            <thead>
                                <tr>
                                    <th field="address" width="200px">Address</th>
                                    <!--<th field="score">Scrore</th>-->


                                </tr>
                            </thead>
                        </table>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                    </div>
                </div>


            </div>
        </div>


    </div>


    <script>
        var items;


       


    require([
            "dojo/on",
            "dojo/_base/array",
            "esri/tasks/locator",
            "dojox/grid/DataGrid",
            "dojo/data/ItemFileReadStore",
            "dijit/registry", "dojo/parser",
            "dijit/layout/ContentPane",
            "dojo/domReady!"
    ],
     function (on, arrayUtils, Locator, DataGrid, ItemFileReadStore, registry, parser) {
         parser.parse();


         document.getElementById("grid").style.display = "none";


         on(document.getElementById('ownerAddress'), 'focusout', checkAddress);


         function checkAddress() {
             var locator = new Locator("http://maps.decaturil.gov/arcgis/rest/services/Public/WebAddressLocator/GeocodeServer");
             //console.log(document.getElementById('ownerAddress').value);
             var node = document.getElementById('ownerAddress');
             // according to your service it takes Single Line
             var params = {
                 "Single Line Input": node.value
             };
             locator.addressToLocations(params).then(function (addressCandidates) {
                 //console.log('success', addressCandidates);
                 //console.log(addressCandidates.length);
                 if (addressCandidates.length > 1) {
                     for (a = 0; a < addressCandidates.length; a++) {
                         // This is the address that should go into a grid cell
                         console.log(addressCandidates.address);


                     }
                     console.log(addressCandidates);
                     items = arrayUtils.map(addressCandidates, function (result) {
                         console.log(result);
                         return result;
                     });
                     console.log(items);
                 }
                 var data = {


                     items: items
                 };
                 console.log("Log" + data);
                 store = new ItemFileReadStore({
                     data: data
                 });
                 
                 // display grid
                 document.getElementById("grid").style.display = "block";
                 // Show modal
                 $("#myModal").modal("show");
                 var grid = registry.byId("grid");
                 grid.setStore(store);
                 //registry.byId("grid").display=block;
                 grid.on("rowclick", onRowClickHandler);
                 //console.log(addressCandidates.length);


                 


                 var adresses = addressCandidates.map(function  {
                     return x.address;


                 });
                 //console.log(adresses);


             }).otherwise(function (err) {
                 console.log('somethings wrong', err);
             });




         }




         function onRowClickHandler(evt) {
             console.log(evt);
             var clickedAddress = evt.grid.getItem(evt.rowIndex).address;
             console.log(clickedAddress);
             alert(clickedAddress);
             //  console.log(evt.explicitOriginalTarget.data);
         }
     });
    </script>
</body>


</html>
Tags (3)
0 Kudos
19 Replies
TracySchloss
Frequent Contributor

I had several sets, but it seems like you can replicate.  I set one for items, store and for the line grid.setStore(store).  Doing that the modal is populating.

ChrisSergent
Regular Contributor III

I was able to see the datagrid through debugging too.

I tried to pause before and after the grid.setStore like so:
// Show modal
                    $("#myModal").modal("show");
                    var grid = registry.byId("grid");
                    window.setTimeout(function () { }, 5000);
                    grid.setStore(store);
                    window.setTimeout(function () { }, 5000);

but that didn't do anything.

0 Kudos
TracySchloss
Frequent Contributor

I tried changing it around to have a listener as 

on (locator, 'address-to-locations-complete', populateModal);

thinking that it wasn't having enough time to get all the candidates before it tried to populate the store, but that didn't help.

Is there a reason you aren't using the Search widget and just defining your own locator as the source?  It should handle the list of candidates for you.

0 Kudos
ChrisSergent
Regular Contributor III

I was asked to validate text boxes after users entered in addresses, otherwise this would be a lot simpler.

0 Kudos
TracySchloss
Frequent Contributor

Since I'm used to dGrid and Memory for my store, I changed this up. It works for me now with no breakpoints.

<!DOCTYPE html>
<html>
<head>
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content=
"width=device-width, initial-scale=1.0">
<link type="text/css" rel="stylesheet" href=
"http://js.arcgis.com/3.14/dijit/themes/claro/claro.css">
<link type="text/css" rel="stylesheet" href=
"http://js.arcgis.com/3.14/esri/css/esri.css">
<link type="text/css" rel="stylesheet" href=
"http://js.arcgis.com/3.14/dojox/grid/resources/Grid.css">
<link type="text/css" rel="stylesheet" href=
"http://js.arcgis.com/3.14/dojox/grid/resources/claroGrid.css">
<link type="text/css" rel="stylesheet" href=
"http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script type="text/javascript" src=
"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">




</script>
<script type="text/javascript" src=
"http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">




</script>


<title></title>
<style type="text/css">
    #myModal {
        height: 80%;
    }


</style>
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
            <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.min.js"></script>
            <script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->
<script type="text/javascript">
    var dojoConfig = {
        parseOnLoad: true,
        isDebug: true,
        locale: 'en-us',
        extraLocale: ['ja-jp']
    };


</script>
<!-- This will not work if you set the html lang https://community.esri.com/thread/81475 -->
<script type="text/javascript" src="http://js.arcgis.com/3.14/">


</script>
<style type="text/css">
    .modal-body, #grid {
        height: 500px;
    }


</style>
</head>


<body class="claro">
<label id="lblOwnerAddress" for="ownerAddress">Owner's
Address</label> <input type="text" id="ownerAddress" name=
"ownerAddress" value="111 S Main">


<div class="container">
    <!-- Modal -->


    <div class="modal fade" id="myModal" role="dialog">
        <div class="modal-dialog">
            <!-- Modal content-->


            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close"
                    data-dismiss="modal">&times;</button>


                    <h4 class="modal-title">Modal
                    Header</h4>
                </div>


                <div class="modal-body">
                  <div id="gridDiv"></div>
                </div>


                <div class="modal-footer">
                    <button type="button" class=
                    "btn btn-default" data-dismiss=
                    "modal">Close</button>
                </div>
            </div>
        </div>
    </div>
</div>
<script type="text/javascript">
var items; 
require([ 
                "dojo/on", 
                "dojo/_base/array", 
                "esri/tasks/locator", 
                "dojox/grid/DataGrid", 
                "dgrid/OnDemandGrid",
                'dojo/store/Memory',
                "dojo/data/ItemFileReadStore", 
                "dijit/registry", "dojo/parser", 
                "dijit/layout/ContentPane", 
                "dojo/domReady!" 
        ], 
        function (on, arrayUtils, Locator, DataGrid, dGrid, Memory, ItemFileReadStore, registry, parser) { 
            parser.parse();       
            on(document.getElementById('ownerAddress'), 'focusout', checkAddress); 
                var locator = new Locator("http://maps.decaturil.gov/arcgis/rest/services/Public/WebAddressLocator/GeocodeServer"); 


          var grid = new dGrid({
        id: 'addrGrid',
        selectionMode: 'single', 
        columns: { addess:'Candidate'},
        loadingMessage: 'Loading data...'
    }, "gridDiv");
    grid.startup();
     
            function checkAddress() { 
                var node = document.getElementById('ownerAddress'); 
                // according to your service it takes Single Line 
                var params = { 
                    "Single Line Input": node.value 
                }; 
            on (locator, 'address-to-locations-complete', populateModal);
                locator.addressToLocations(params);
            } 
           
          function populateModal(addressCandidates){
            if (grid) {
                grid.refresh();
            }
            if (addressCandidates.addresses.length > 1) {                     
                  items = arrayUtils.map(addressCandidates.addresses, function (result,idx) { 
                            return {
                              'id':idx,
                              'address':result.address
                              } ;
                        }); 
                    } 

                  var currentMemory = new Memory({
                        data: items,
                        idProperty: 'id'
                    });
                  grid.set('store', currentMemory);
                 
                    $("#myModal").modal("show"); 
                    grid.on("rowclick", onRowClickHandler); 
          }
          function onRowClickHandler(evt) { 
                console.log(evt); 
                var clickedAddress = evt.grid.getItem(evt.rowIndex).address; 
                console.log(clickedAddress); 
                alert(clickedAddress); 
            } 
        }); 
       


</script>
</body>
</html>
ChrisSergent
Regular Contributor III

Did it display addresses for you? There should be two addresses when you tab out of the textbox.

0 Kudos
ChrisSmith7
Frequent Contributor

Chris,

in follow-up to our discussion in How do I write address candidates to a grid?, I think you have the right idea trying to construct this declaratively. I have had problems in the past when trying to render stuff in the modal dialog programmatically. I hacked something together, though, that accomplishes this:

GRID modal test - JSFiddle

Sorry, it's messy... I haven't had a chance to clean it up. Essentially, I had to trigger an event to render the grid after the modal dialog was visible, otherwise, it didn't know how to render completely on startup. While the modal dialog appears responsive, the grid does not... but it should get you in the right direction.

ChrisSergent
Regular Contributor III

Chris,

Awesome! There was some duplication in the code, but it worked out great!

Had no idea why it would show up. Thanks for adding the documentation as well.

Here is my complete code for anyone that needs it:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="http://js.arcgis.com/3.14/dijit/themes/claro/claro.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css">
    <script src="http://js.arcgis.com/3.14/"></script>
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <style>
        #gridDiv {
            height: 100%;
            width: 100%;
        }


        #myModal {
            height: 100%;
            width: 100%;
        }


        .modal-body {
            height: 300px;
        } 
    </style>
    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.min.js"></script>
      <script src="//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->


</head>


   
    <body class="claro">
        <label id="lblOwnerAddress" for="ownerAddress">Owner's Address</label>
        <input type="text" id="ownerAddress" name="ownerAddress" value="111 S Main" />
        <div id="mainDiv" class="container">




            <!-- Modal -->
            <div class="modal fade" id="myModal" role="dialog">
                <div class="modal-dialog">




                    <!-- Modal content-->
                    <div class="modal-content">


                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal">&times;</button>
                            <h4 class="modal-title">Modal Header</h4>


                        </div>


                        <div class="modal-body">
                            <div id="gridDiv"></div>
                        </div>
                        <div class="modal-footer">


                            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <script>
            var items;










            require([
                    "dojo/on",
                    "dojo/_base/array",
                    "esri/tasks/locator",
                    "dojox/grid/DataGrid",
                    "dojo/data/ItemFileWriteStore",
                    "dijit/registry", "dojo/parser",
                    "dijit/registry",
                    "dojo/dom",
                    "dojo/_base/lang",
                    "dijit/layout/ContentPane",
                    "dojo/domReady!"
            ],
            function (on, arrayUtils, Locator, DataGrid, ItemFileWriteStore, registry, parser, registry, dom, lang) {
                parser.parse();
                var store, grid, data, layout;


                //document.getElementById("grid").style.display = "none";




                on(document.getElementById('ownerAddress'), 'focusout', checkAddress);




                function checkAddress() {
                    var locator = new Locator("http://maps.decaturil.gov/arcgis/rest/services/Public/WebAddressLocator/GeocodeServer");
                    //console.log(document.getElementById('ownerAddress').value);
                    var node = document.getElementById('ownerAddress');
                    // according to your service it takes Single Line
                    var params = {
                        "Single Line Input": node.value
                    };
                    locator.addressToLocations(params).then(function (addressCandidates) {
                        //console.log('success', addressCandidates);
                        //console.log(addressCandidates.length);


                        data = {
                            identifier: "id",
                            items: []
                        };


                        layout = [[
                        //  {'name': 'FID', 'field': 'id', 'width': '50px'},//
                          { 'name': 'Address', 'field': 'address', 'width': '200px' }
                        ]];
                        if (addressCandidates.length > 1) {
                            for (a = 0; a < addressCandidates.length; a++) {
                                // This is the address that should go into a grid cell
                                data.items.push(lang.mixin({ id: a + 1 }, { address: addressCandidates.address }));
                                console.log(addressCandidates.address);




                            }
                            console.log(addressCandidates);
                            items = arrayUtils.map(addressCandidates, function (result) {
                                console.log(result);
                                return result;
                            });
                            console.log(items);
                        }




                        console.log("Log" + data);
                        if (window.grid) {
                            dojo.destroy('grid');
                            dijit.byId('grid').destroy(true);
                            registry.remove(dom.byId('gridDiv'));
                        }
                        store = new ItemFileWriteStore({ data: data });
                        grid = new DataGrid({
                            id: 'grid',
                            store: store,
                            structure: layout,
                            autoWidth: true,
                            autoHeight: false,
                            rowSelector: '20px'
                        });






                        // display grid
                        //document.getElementById("grid").style.display = "block";
                        // Show modal
                        $("#myModal").modal("show");
                        $('#myModal').show(function () {
                            $(this).trigger('isVisible');
                        });
                        //registry.byId("grid").display=block;
                        grid.on("rowclick", onRowClickHandler);
                        //console.log(addressCandidates.length);




                        //hookup the event
                        $('#myModal').bind('isVisible', isVisible);




                        var adresses = addressCandidates.map(function () {
                            return x.address;




                        });
                        //console.log(adresses);




                    }).otherwise(function (err) {
                        console.log('somethings wrong', err);
                    });








                }




                //declare event to run when div is visible
                function isVisible() {
                    /*append the new grid to the div*/
                    grid.placeAt("gridDiv");
                    /*Call startup() to render the grid*/
                    grid.startup();


                }


                function onRowClickHandler(evt) {
                    console.log(evt);
                    var clickedAddress = evt.grid.getItem(evt.rowIndex).address;
                    console.log(clickedAddress);
                    alert(clickedAddress);
                    //  console.log(evt.explicitOriginalTarget.data);
                }
            });
        </script>
</body>
</html>
0 Kudos
ChrisSmith7
Frequent Contributor

Cool - glad to help! We have a big initiative to retrofit our app to make it responsive using Bootstrap... it's a pretty slick framework. One thing I may need to revisit is how the dialog is created/destroyed... I'm probably being a little heavy-handed in this approach, but I didn't have luck trying to update the control if it already existed in the DOM.

ChrisSergent
Regular Contributor III

I have seen the issue of needing to destroy items before due to conflicts. If you are interested I would be willing to help learn/create a Bootstrap template on Github to make a responsive app. Still learning responsive, but I am very much into learning new things and very active into helping out when I can and would welcome the challenge.

0 Kudos