Rich
Rich

Reputation: 65

How do I get dgrid ondemandgrid to show inside dijit/dialog?

I am using dgrid OnDemandGrid in a digit/dialog. I post the dialog, but the grid doesn't show. I can see the where the grid should occur, but the grid itself doesn't post with grid.startup(). I think this is because I don't understand when the events are happening, and therefore don't startup the grid at the right time.

I am setting up a page for a user to define goals. I'd like to have them link one goal to another.

To do that, I want to post a dialog box with a grid of the existing goals and let them pick one to link. Even though I get a grid of goals on the page, when I try to do the same thing for a grid within a dialog, it fails to show the grid.

I have used dgrid to form a grid on the main page, and that code works to show the list of existing goals, like this...

HTML

<div>
  <h4>Goals</h4> 
  <div id="goalgrid" class="grid"></div>
</div>

Script

require(["dojo/_base/declare", "dgrid/OnDemandGrid", "dgrid/Selection", "dstore/Memory", "dijit/Dialog", "dijit/form/TextBox", "dijit/form/CheckBox", "dijit/form/Button", "dojo/dom", "dojo/on"],
  function (declare, OnDemandGrid, Selection, Memory, Dialog, TextBox, CheckBox, Button, dom, on) {
    var gridData = [
        { id: 1, goalName: "Top Goal", parentId: 0 },
        { id: 2, goalName: "Objective 1", parentId: 1 },
        { id: 3, goalName: "Objective 2", parentId: 1 }
    ];
    gridStore = new Memory({data: gridData});
    var grid = new (declare([ OnDemandGrid, Selection ]))({
        collection: gridStore,
        columns: {
          id: "ID",
          goalName: "Name",
          parentId: "Parent"
        }
    }, "goalgrid");
    grid.renderArray(gridData);
...

This page displays the Goals title and a grid with the three goals in gridData.

I tried adding code for a dialog box like this:

echo '<div class="content">';
echo '<p>This page allows you to describe your goals.</p>
       <div data-dojo-type="dijit/form/Form" id="connect-form" widgetid="form" lang="en" action="" method="">
          <fieldset data-dojo-attach-point="part1">
            <div class="event-input-text">
              <h4>Goals</h4> 
              <div id="maingrid">Main grid for page, which shows data when dgrid is invoked on maingrid.</div>
            </div>
            <div id="buttonArea" style="padding:5em 0 0 15px;">
            <input id="goa-link-button" name="submit" value="Link" type="button">
            </div>
            </fieldset>
       </div>';
echo '</div>'; // end of content
echo '<script>
require(["dojo/_base/declare", "dgrid/OnDemandGrid", "dgrid/Selection", "dstore/Memory", "dijit/Dialog", "dijit/form/TextBox", "dijit/form/Button", "dojo/dom", "dojo/on"],
  function (declare, OnDemandGrid, Selection, Memory, Dialog, TextBox, Button, dom, on) {

    var linkGoalDialogContent = `
      <div id="gldiv">
        <ul>
          <li>Sub-Goal ID: ID</li>
          <li>Sub-Goal Name: Goal</li>
        </ul>
        <div id="goallist" class="listgrid">gridspace</div>
        <div class=\"dijitDialogPaneActionBar\">
            <input id="goa-link-goal-cancel-button" name="submit" value="Cancel" type="button">
            <input id="goa-goal-link-button" name="submit" value="Link" type="button">
        </div>
      </div>`;
    var goalGridData = [
        { id: 1, goalName: "Top Goal" },
        { id: 2, goalName: "Objective 1" },
        { id: 3, goalName: "Objective 2" }
    ];
    var goalGridStore = new Memory({data: goalGridData});
    var ggrid = new (declare([ OnDemandGrid, Selection ]))({
        collection: goalGridStore,
        columns: {
          id: "ID",
          goalName: "Name"
        }
    }, "linkGoalDialog.gldiv.goallist");
    var linkGoalDialog = new Dialog({
      id: "linkGoalDialog",
      title: "Link Goal to New Parent Goal",
      content: linkGoalDialogContent,
      style: "width: 400px",
      onShow: function() {
           console.log("Show called on linkGoalDialog\n");
           console.log("The goallist node has contents: "+dom.byId("goallist").innerHTML+"\n");
           ggrid.startup();
           console.log("The goallist node has contents: "+dom.byId("goallist").innerHTML+"\n");
      },
      onHide: function () {
           console.log("Hide called on linkGoalDialog\n");
      }
    });
    ggrid.startup();
    on(dom.byId("goa-link-button"), "click", function(){
        linkGoalDialog.show();
    });
    on(dom.byId("goa-link-goal-cancel-button"), "click", function(){
        linkGoalDialog.hide();
    });
    on(dom.byId("goa-goal-link-button"), "click", function(){
        linkGoalDialog.hide();
    });
});
</script>';

I also tried ggrid.renderArray(goalGridData) in place of ggrid.startup(), but neither of these give me the grid. The output in the console for this when you click the Link button is that the goallist node has the contents "gridspace", both before and after startup().

And, in fact, the dialog shows on the page with "gridspace" where the grid is supposed to be.

Because the original grid (code not shown here) loads and displays properly, I suspect I have a timing issue or some kind of problem with scope.

Here is the custom CSS I'm using for this:

.grid {
    width: 700px;
    height: 25em;
    margin: 10px;
}

.listgrid {
    width: 300px;
    height: 5em;
    margin: 10px;
}

.grid .dgrid-cell {
    width: 80px;
}

.grid .field-id {
    width: 10px;
}

.grid .field-goalName {
    width: 100px;
}

.grid .field-parentId {
    width: 15px;
}

Does anyone have any ideas why the grid within the dialog is not showing? Thanks for help!

Update 3 May 2020

Here are the versions I'm using:

For what it's worth, I installed the dgrid and dojo files by uploading the .tar.gz to the web server and unpacking them there, but I installed the dstore files by downloading the .zip file to my Windows machine, unpacking them there, and copying to the web server with FTP.

I'm using these in the context of the WebsiteBaker framework, from WebsiteBaker-2_12_2.tar.gz.

After more research, I tried putting up the grid when after the dialog.show() call, as with:

    on(dom.byId("goa-link-button"), "click", function(){
        linkGoalDialog.show();
        ggrid.renderArray(goalGridData);
    });

This doesn't work. I tried ggrid.startup() there, as well, but it doesn't work, either.

Update 26 May 2020

After more research, I tried changing:

    var linkGoalDialog = new Dialog({

to

    window.linkGoalDialog = new Dialog({

on the theory that the dialog should go on the window object, so that it would be rendered before the cal to set up the grid. But this didn't work, either.

Upvotes: 0

Views: 173

Answers (1)

dgrid performs DOM dimension calculations that fail if the dgrid DOM is not visible. It sounds like this is the case for your dialog. The solution is to call startup/renderArray when the dgrid DOM is visible. Try calling grid.renderArray(gridData) after the dialog has been opened and is visible.

Upvotes: 0

Related Questions