views:

134

answers:

1

I have a grid that will edit small chunks of data based on a larger tree structure. In order to make it easier to know what's being saved by the user, I want to have the grid be in a non-editable state when the user first sees the grid. When the user is ready, they can click the edit button, which will make portions of the grid editable. Then, there is a save or a cancel button to either save the changes or revert back.

For the most part it works. However, if you click edit, don't change anything, click save, and then click edit again, you cannot edit the data in the grid, and on some occasions you receive an "assertion failed in ItemFileWriteStore" message. This also happens if you click on the cancel button. Occasionally, all the data in the grid will disappear after clicking the cancel button as well.

Below, I've included the smallest chunk of code that reproduces the problem I'm seeing. Has anyone outer there seen this issue and been able to fix it, or am I doing something wrong in my code that is causing this particular problem?

Thanks.

<html>
  <head>
    <title>Dojo Grid Test</title>
    <script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js" type="text/javascript"></script>

    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dijit/themes/tundra/tundra.css" />
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojox/grid/resources/Grid.css"&gt;
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojox/grid/resources/tundraGrid.css"&gt;

    <script>

      dojo.require("dojo.data.ItemFileWriteStore")
      dojo.require("dojox.grid.cells.dijit");
      dojo.require("dojox.grid.DataGrid");
      dojo.require("dojox.grid.cells");

      var attCodeStore = null;
      var containerGrid = null;

      function editTable() {
          var theStructure = containerGrid.structure;
          theStructure[1].editable = true;
          theStructure[2].editable = true;
          containerGrid.setStructure(theStructure);
          toggleButtons();
      }

      function saveTable() {
          var theStructure = containerGrid.structure;
          theStructure[1].editable = false;
          theStructure[2].editable = false;
          containerGrid.setStructure(theStructure);
          attCodeStore.save();
          toggleButtons();
      }

      function cancelTable() {
          var theStructure = containerGrid.structure;
          theStructure[1].editable = false;
          theStructure[2].editable = false;
          containerGrid.setStructure(theStructure);
          attCodeStore.revert();
          toggleButtons();
      }

      function toggleButtons() {
          if (dojo.hasClass("editButton", "dijitHidden")) {
              dojo.removeClass("editButton", "dijitHidden");
              dojo.addClass("saveButton", "dijitHidden");
              dojo.addClass("cancelEditButton", "dijitHidden");
          } else {
              dojo.addClass("editButton", "dijitHidden");
              dojo.removeClass("saveButton", "dijitHidden");
              dojo.removeClass("cancelEditButton", "dijitHidden");
          }
      }

      function setupTable() {

        var attCodeData = {label:'attribute',
                           identifier: 'id',
                            items: [
                                { id:'itemOneId',
                                  alias:'itemOneAlias',
                                  description:'itemOneDescription',
                                  attribute:'itemOneAttribute'
                                },
                                { id:'itemTwoId',
                                  alias:'itemTwoAlias',
                                  description:'itemTwoDescription',
                                  attribute:'itemTwoAttribute'
                                },
                                { id:'itemThreeId',
                                  alias:'itemThreeAlias',
                                  description:'itemThreeDescription',
                                  attribute:'itemThreeAttribute'
                                },
                                { id:'itemFourId',
                                  alias:'itemFourAlias',
                                  description:'itemFourDescription',
                                  attribute:'itemFourAttribute'
                                },
                              ]
                            };

        attCodeStore = new dojo.data.ItemFileWriteStore({data:attCodeData})

        console.log(attCodeStore);
        console.log(attCodeData);

        containerGrid = new dojox.grid.DataGrid({
                      store: attCodeStore,
                      clientSort: true,
                      autoHeight: true,
                      structure: [
                          {field: 'attribute', width: '100px', name: 'Attribute'},
                          {field: 'alias', width: '100px', name: 'Alias'},
                          {field: 'description', width: 'auto', name: 'Description'}
                      ]
                  });

        dojo.byId("gridDiv").appendChild(containerGrid.domNode);
        containerGrid.startup();
      }

      dojo.addOnLoad(function(){
         setupTable();  
      })
    </script>
  </head>
  <body>
     <div id="gridArea">
          <div>
              <input type="button" value="Edit" id="editButton" onclick="editTable()"/>
              <input type="button" value="Save" id="saveButton" onclick="saveTable()" class="dijitHidden"/>
              <input type="button" value="Cancel" id="cancelEditButton" onclick="cancelTable()" class="dijitHidden" />
          </div>
      </div>
      <div id="gridDiv"></div>
  </body>
</html>
A: 

Figured this one out (though it took a bit). Turns out, that when you click on an entry in an editable grid, the grid goes into an editing state. (Makes sense.) However, when I saved the data store while the grid was in an editing state, it didn't change the state of the grid. The next time I clicked on edit and brought the grid back to where I thought I could start editing, the grid thought it was still editing the previously selected cell, and would only send that cells information.

When I put the following code at the beginning of my saveTable and cancelTable methods, all worked as expected:

if (containerGrid.edit.isEditing()) {
     containerGrid.edit.apply();
}

Hopefully, this answer can save someone else some time later.

Thanks.

Dante617