Bottom of Two dijit.InlineEditBox with dijit.form.Textarea Editor Does Not Open on Single Click

dijit.InlineEditBox is great, but if you have two stacked on each other in containers with undefined heights, things can get a little buggy for a user. Example:

The problem is that if you open up id=”one” first, the page height expands two rows to make a textarea, so when you click on id=”two”, the page re renders and doesn’t open “two”! (This will work going from “two” to “one” since the top part of the page won’t change.)

If you watch the focus and blur events you’d see the following from “two” to “one”:

Focus: two
Blur: two
… click one
… two closes
Focus: one
… one opens
Blur: one

If you watch the focus and blur events you’d see the following from “one” to “two”:

Focus: one
Blur: one
… click two
… one closes
Focus: two
…. NOTHING …..

Basically for some reason it doesn’t open. So to fix this, just implicitly call edit() during onFocus.


...
onFocus: function()
{
this.inherited(arguments);
this.edit(); // Force (technically it may get called twice now, oh well.)
},
....

Unregistering Child Widgets from Custom Widget Template

I’ve been having this problem of child widgets hanging around after I destroy a custom widget. For some reason I just can’t get them to destroy when I call destroy / destroyRescursive on my custom widget. This is a problem because every time I try to replace the current instance of my widget with a new one I’ll get the “already registered” error.


var my_tabs = new my.dijit.layout.TabContainer.MyTabs(); // Errors 🙁

To combat this I’ve come up with a little technique to remove them during my custom widget creation life cycle. Just hook into the postMixInProperties function and remove the child widgets if they exists:


postMixInProperties: function()
{
// Destroy the child tabs if they exists. This is just a checker
// incase they don't get destroyed somehow.
this._destroyChildTab('search_form_pane');
this._destroyChildTab('a_tab');
this._destroyChildTab('another_tab');
this.inherited(arguments);
},

/**
* Destroy the tab if it exists.
*/
_destroyChildTab: function(tab)
{
try { dijit.byId(tab).destroy(true); } catch(e){}
}

Since my custom widgets use templates, I know the ID of any of its child widgets, so I’m able to do this. Below is an example of one of my TabContainer templates:

TabContainer / BorderContainer Not Resizing with Custom Widget

I have the following custom widget that defines a tab container in it’s template:


dojo.require("dijit.layout.TabContainer");
dojo.provide('custom.dijit.layout.TabContainer.Courses');

dojo.declare('custom.dijit.layout.TabContainer.Courses', [dijit._Widget, dijit._Templated],
{
widgetsInTemplate:true,
templateString: dojo.cache('custom.dijit.layout.TabContainer', 'Courses.html'),

...
}

The template looks like:

When the widget loads, the template doesn’t render correctly until after the browser is resized. Apparently if you create widgets that contain dijit.layout widgets you have to tell them to resize after they render. All you have to do is add a resize function, that will call all of the ContentPane’s resize functions, to your widget and everything will look great again 🙂


resize: function()
{
// Tell the content panes to resize.
dojo.forEach(this.getChildren(), function (child) { child.resize(); });
}

A Dojo Enhanced Grid Example with Context Menu

For some reason dojox.grid.EnhancedGrid doesn’t have an out of the box way to access the selected rows data and send it to the context menu. Google doesn’t help either so hope this helps someone. Here is how to access the selected row from the context menu:

Ugly Demo


// First create a menu object to hold the various menus
var menusObject = {
// headerMenu: new dijit.Menu(),
rowMenu: new dijit.Menu()//,
// cellMenu: new dijit.Menu(),
// selectedRegionMenu: new dijit.Menu()
};

//Add a menu item

menusObject.rowMenu.addChild(new dijit.MenuItem({
label: "Show me data",
onClick: function(e){
console.log(this.selectedRow)
}
}));

menusObject.rowMenu.startup();

//Create the grid

var grid = new dojox.grid.EnhancedGrid({
store : store,
structure : layout,
rowsPerPage: 10,
escapeHTMLInData: false,
plugins: {
menus: menusObject
}
}, 'some are to place');

// Activate message sending from data grid row to menu items

dojo.connect(grid, 'onRowContextMenu', function(e)
{
// Set the "selectedItem" property of all of the menu items of a menu. This lets you reference the row data!!

var menuChildren = menusObject.rowMenu.getChildren();
for(var i = 0; i

Ugly Demo