Login Register

Events

As we alluded to in the last few pages, selection and cell editing is pointless without some kind of background processing. So how do you hook code into these places? Through Dojo's event model, of course!

Editing Changes

If you're using a writable dojo.data datastore, you simply hook your procedures into the dojo.data Notification API. Suppose in our running example, we make the Description field editable:

cells: [[
    {name: 'Namespace', field:0, width:"30em"}, 
    {name: 'Description', field:3, width:"30em",
        editor: dojox.grid.editors.Dijit }
  ]
],

Then, we place the hook into dojo.data.Notification's onSet extension point:

<div dojoType="dojo.data.ItemFileWriteStore"
        jsId="jsonStore" url="dijits.txt">

    <script type="dojo/connect" event="onSet" args="item,attr,oldVal,newVal">
       console.debug("About to change "+attr+" from "+oldVal+" to "+newVal);
       // Save the record with dojo.xhrPost or your favorite remote method
    </script>
</div>

Here is the entire source code. Note how we place the layout initialization code in a dojo/method block inside the Grid tag. That's due to the editor class dojox.grid.editors.Dijit in the view definition. When you're using CDN, the dojox.grid.editors package is not available directly after the dojo.require., so we can't place the initialization code after it (as we did in our previous examples). By using a dojo/method, we can place this code close to its use (the Grid tag) and it's guaranteed to run after all dojo.require'd modules have loaded. You can also use dojo.addOnLoad to accomplish this.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Test dojox.Grid Editing</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
    <style type="text/css">
        @import "http://o.aolcdn.com/dojo/1.0.0/dojox/grid/_grid/tundraGrid.css";
        @import "http://o.aolcdn.com/dojo/1.0.0/dijit/themes/tundra/tundra.css";
        @import "http://o.aolcdn.com/dojo/1.0.0/dojo/resources/dojo.css"
        body {
            font-size: 0.9em;
            font-family: Geneva, Arial, Helvetica, sans-serif;
        }
        .heading {
            font-weight: bold;
            padding-bottom: 0.25em;
        }
               
        #grid {
            border: 1px solid #333;
            width: 40em;
            height: 30em;
        }
    </style>
    <script type="text/javascript" src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
            djConfig="isDebug:false, parseOnLoad: true">
</script>
    <script type="text/javascript">
        dojo.require("dojo.data.ItemFileWriteStore");
        dojo.require("dojox.grid.Grid");
        dojo.require("dojox.grid._data.model");
        dojo.require("dojox.grid.editors");
        dojo.require("dojo.parser");
   
</script>
</head>
<body class="tundra">
<div class="heading">Grid Events</div>
    <div dojoType="dojo.data.ItemFileWriteStore"
        jsId="jsonStore" url="dijits.txt">

        <script type="dojo/connect" event="onSet" args="item,attr,oldVal,newVal">
            console.debug("About to change "+attr+" from "+oldVal+" to "+newVal);
        </script>
    </div>
    <div dojoType="dojox.grid.data.DojoData" jsId="model"
        rowsPerPage="20" store="jsonStore" query="{ namespace: '*' }"
        clientSort="true">

    </div>
    <div id="grid" elasticView="2" dojoType="dojox.Grid" model="model"
        jsId="thisGrid">

        <script type="dojo/method">
            var view1 = {
                cells: [[
                    {name: 'Namespace', field:0, width:"30em"},
                    {name: 'Description', field:3, width:"30em"}
                  ],
                  [
                    {name: 'Summary', field:2, colspan:2,
                     editor: dojox.grid.editors.Dijit }
                  ]
                ]
            };
            var rowbar = {
               type: 'dojox.GridRowView', width: '20px'
            };
            var fixedColumn = {
                 noscroll: true,
                 cells: [[ {name: 'Class', field:1} ]]
            };
           
            // When you initialize inside the dojo/method script, you must set the
            // structure manually.
            var layout = [ rowbar, fixedColumn, view1 ];
            thisGrid.setStructure(layout);
        </script>
       </div>
</body>
</html>

You can read more on the dojo.data Notification API in Part 3 of the book, but here are the basics for your Grid needs:

  • onSet: function(/* item */ item, /* attribute-name-string */ attribute, /* object | array */ oldValue, /* object | array */ newValue ) - called after any cell is edited and saved.
  • onNew: function(/* item */ newItem,) - called after a row is added to the grid.
  • onDelete: function(/* item */ deletedItem) - called after a row is deleted

Low-Level Events

For more granular event processing, you can hook into Grid events. Each event calls the function you provide, passing back the event object. If e is the event, the interesting stuff is in:

  • e.rowIndex: the row number
  • e.cell.index: the column (cell) number. Taken with e.rowIndex, effectively gives you coordinates of a cell event.
  • e.keyCode: keystroke value, only applicable to keydown event.
Entity click/double click mouse over/out right click
Data Cell onCellClick
onCellDblClick
onCellMouseOver
onCellMouseOut
onCellContextMenu
Hdr Cell onHeaderCellClick
onHeaderCellDblClick
onHeaderCellMouseOver
onHeaderCellMouseOut
onHeaderCellContextMenu
Data Row onRowClick
onRowDblClick
onRowMouseOver
onRowMouseOut
onRowContextMenu
Hdr Row onHeaderClick
onHeaderDblClick
onHeaderMouseOver
onHeaderMouseOut
onHeaderContextMenu

onRowDblClick in IE6 with window.open misbehavior

Setting an onRowDblClick handler with a window.open command works fine in FF/Ubuntu.

But in IE6 the new window fails to get focus (sometimes blinks into focus momentarily) and will not retain focus when alt-tabbed to from the parent window.

Invoking the same handler from a button works fine.

grid = new dojox.Grid({
        "id": "grid",
        "model": model,
        "structure": layout,
        "autoWidth" : true,
        "onRowDblClick" : editCheck,
        "defaultHeight": 8
        },dojo.byId("list"));

...

function editCheck(evt) {

    var row=evt.rowIndex;
    
    var rowID=grid.model.getDatum(row,IDfieldNum);
    editwin=window.open('retCheckEdit.pl?id='+ rowID,'_blank','width=800,height=394,resizable=no,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no,left=30,top=128,screenX=30,screenY=128');

    return true;
}

* code edited to be more clear -1st version was for button or event

How can the new window get focus in IE6?

Thanks In Advance,

George

IE6 and clicks

IE frequently has trouble doing stuff at click-time. My usual solution is to set an idle-time timeout like so:

function editCheck(evt) {
  var row = evt.rowIndex;
  var rowID = grid.model.getDatum(row,IDfieldNum);
  setTimeout(function(){ window.open(...); }, 1);
  return true;
}

Cheers,
Scott

About corresponding syntaxe with dojo.connect ?

Dear all,

I want to add a simple event when the user edit a cell of my grid.
What I don't understand is that works (like the example above):

<div class="partsContainer">
<div class="gridContainer">
<div id="grid" dojoType="dojox.Grid" model="model" structure="structure" autoWidth="true">
<script type="dojo/connect" event="onApplyCellEdit" args="a,b,c">
console.debug("new value"+a);
</script>

But the following code doesn't work (nothing append when I edit a cell):

<div class="partsContainer">
<div class="gridContainer">
<div id="grid" dojoType="dojox.Grid" model="model" structure="structure" autoWidth="true">
<script type="text/javascript">
id= dojo.byId("grid");
dojo.connect (id, "onApplyCellEdit", function (a,b,c) {
console.debug ("new value" + a); } ;
</script>

I prefer the 2nd syntaxe which is more readable, but it doesn't work, I also try to create a specific function declared before the

and try to include the connect in an dojo.addOnLoad function without success.

Can you try to explain me the difference between the 2 syntaxes and where is my mistake ... I'm a javascript beginner ...

Note that the 2nd syntaxe works with a standard event such as "onclick"

Thanks
Mat

It's almost correct

Your syntax and code is correct, your only mistake is where it's placed. When you do a dojo.connect, it must execute after the element (or the window) is loaded. So, it should be:

dojo.addOnLoad (function(){
id= dojo.byId("grid");
dojo.connect (id, "onApplyCellEdit", function (a,b,c) {
console.debug ("new value" + a); } ;
});

...

...

Thats all.
Greetings
Edgarin

explicit save button for dojox.grid.editors?

Hi there,

I'm using dojox.grid.editors.Input to update each row's comment field in my grid. Currently, i need to click away from the edited field, and it need to be on the grid elsewhere, otherwise, onApplyCellEdit is not fired off. Is there an option like InlineEdit Box's autoSave, which I can turn off so I need to click a button to save when I'm done editing?
Thanks,

david