PDA

View Full Version : 4.0.7 Asking how to recalculate the size of a menu after hiding and showing items



townsenda
28 Mar 2012, 6:32 AM
I'm asking
1) how I can inform Ext that I need the menu canvas size recalculated (and applied) during the beforeshow (or show) event
2) what the event for 'headerchange' changed to in ExtJS4.

Note this post was related to http://www.sencha.com/forum/showthread.php?190976-4.0.7-Dynamically-Hide-Show-MenuItems-in-beforeshow-event-menu-won-t-resize-Menu but I while I thought I had the answer I totally did not.

I'm attaching the example so that anyone may see the behavior.

The issue I have is that after hiding or showing menu items the menu does not re-calculate it's size.
The scenario is that I've added 2 "features" to a grid's menu beforeShow. 1) If the column is not sortable I need to hide the asc/desc menu items and their seperator. 2) Allow renaming of the column header.

The code looks like




<html>
<head>
<link rel="stylesheet" type="text/css" href="/DevTestApp/scripts/extjs4/resources/css/ext-all.css" />
<script type="text/javascript" src="/DevTestApp/scripts/extjs4/ext-all-debug-w-comments.js"></script>
<title>Grid Panel - Hide/Show Resizing Issue</title>
<script type="text/javascript">
Ext.require([
'Ext.grid.View',
'Ext.data.ArrayStore',
'Ext.grid.Panel'
]);


// Here's a cut down example of my custom view to illustrate the issue.

Ext.define('testView', {
extend : 'Ext.grid.View',
requires: ['Ext.grid.View'],
alias: 'widget.testView',


renameHeaderText: 'Rename header',
renamePromptTitleText: 'Rename column header',
renamePromptMsgText: 'Enter new column name',
renameFailedText: 'Rename failed: a column with header "{0}" already exists!',
hideIfNotSortable: true,

constructor: function(config){
Ext.apply(this, config);


testView.superclass.constructor.apply(this, arguments);

// Allow us to add the rename menu and hide/show when the column is not sortable
this.headerCt.on('menucreate', this.onMenuCreate, this);
},
onMenuCreate: function(headerCt, menu) {
menu.on('beforeshow', this.onBeforeShow, this);
},
onBeforeShow: function(menu) {
// menu.superclass.onBeforeShow.apply(this, arguments);

var me = this,
menuItems = menu.items,
renameMenuItem;


// Hide ascending / descending and the following seperator if
// the column isn't even sortable.
if (this.hideIfNotSortable) {
// Hide the asc/desc if this is not sortable
if (!menu.activeHeader.sortable) {
menuItems.get('ascItem').hide();
menuItems.get('descItem').hide();
} else {
menuItems.get('ascItem').show();
menuItems.get('descItem').show();
if (menu.apsFirstSeparatorAfterHidden != null) {
menu.apsFirstSeparatorAfterHidden.show();
}
}
var hiddenCount = 0;
var firstSeparator = null;
Ext.each(menuItems.items, function(item){
if (item.hidden) {
hiddenCount++;
}
if (hiddenCount > 0 && item.separatorCls == 'x-menu-item-separator') {
firstSeparator = item;
return false; // break the loop
}
});
if (firstSeparator != null) {
firstSeparator.hide();
// Put a marker in the menu for this
menu.apsFirstSeparatorAfterHidden = firstSeparator;
}
}

// Now create the rename header item
if (!me.restrictRename) {
renameMenuItem = me.renameMenuItem;
if (!renameMenuItem || renameMenuItem.isDestroyed) {
me.createMenuItem(menu);
renameMenuItem = me.renameMenuItem;
}
}

menu.doLayout();

},
createMenuItem: function(menu) {
this.renameMenuItem = menu.add('-', {
iconCls: 'column-header-rename-icon',
itemId: 'renameColumnHeader',
text: this.renameHeaderText,
scope: this,
handler: function(menu) {
var activeHeader = menu.ownerCt.activeHeader;
Ext.Msg.prompt(this.renamePromptTitleText, this.renamePromptMsgText,
function(btn, text) {

if (Ext.isEmpty(text)) {
return;
}
if (btn == 'ok') {
this.setText(text);
}
}, activeHeader, false, activeHeader.text);
}
});
}


});

var empData = [
["Nancy", "Davolio", 55000],
["Andrew", "Fuller", 108000]
];


var myStore = Ext.create('Ext.data.ArrayStore', {
fields : [
{name:'firstName'},
{name:'lastName'},
{name:'salary'}
],
data: empData
});




Ext.onReady(function() {
Ext.Loader.setConfig({enabled:true});


var myGrid = Ext.create('Ext.grid.Panel', {
id: 'myPaymentGridID',
width: 1000,
restrictRename: true,
store : myStore,
renderTo : 'content',
viewType:'testView',
columns:[
{
dataIndex:'firstName',
header:'First',
sortable:true,
width:100
},{
dataIndex:'lastName',
header:'Last',
sortable:true,
width:150
},{
dataIndex:'salary',
header:'Salary',
sortable:false,
width:175
}
]
});
myGrid.show();


});
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>




So in this simple grid of 3 columns all but the last item is marked as sortable.

You can see the behavior I'm seeing by clicking on the last columns header menu... afterward click on the first or seconds's header and you will see the size is constrained to that of the first header activated (refresh and now do this in the opposite order.. see how the last menu is large and does not get recalculated even though menu items are being hidden.

Now because we tie this grid view to a standard grid I'd also like to know what event (if any) replaced 'hiddenchange' from extJS3 (but this is the lesser my questions).

Thanks for considering these questions.

mitchellsimoens
28 Mar 2012, 8:45 AM
4.1.0-RC1 resizes the height of the menu.