PDA

View Full Version : Multi-Column Menus



walkins5
5 May 2009, 7:22 AM
I am currently preparing for a new project and have convinced the company to invest in ExtJs, but I have to develop a proof of concept. One of the requirements is to create a multi-column menu which is something like mcDropdown jQuery Plug-in v1.2.07. The functionality is almost what I need except for the lack of ability to specify my own columns. I basically need to specify a column header of Products with a list below and another column with a header of Sales with a list below it. I wanted to use the ExtJs menu, but it only offers 1 column. Is there something that I may be missing that allows me to create 2 columns in a menu? Thanks in advance for the help. Take Care and Have a Great Day.

walkins5

jay@moduscreate.com
5 May 2009, 7:29 AM
Ext JS follows most, if not, all OS UI design patterns.

Multiple column context menus go beyond the typical context menu design pattern.

That said, there is no reason why you can't do it if you extend the menu layout,etc.

Animal
5 May 2009, 7:34 AM
Menu Items are Components. You could place them in a 2 column layout.

jay@moduscreate.com
5 May 2009, 7:36 AM
I remember hitting walls trying to do custom layouts. I need to work on this further to enumerate what doesn't work.

Animal
5 May 2009, 7:53 AM
Drop the following into examples/menu as menus.js then run the menus example.



Ext.onReady(function(){
Ext.QuickTips.init();

// Menus can be prebuilt and passed by reference
var dateMenu = new Ext.menu.DateMenu({
handler: function(dp, date){
Ext.example.msg('Date Selected', 'You chose {0}.', date.format('M j, Y'));
}
});

var colorMenu = new Ext.menu.ColorMenu({
handler: function(cm, color){
Ext.example.msg('Color Selected', 'You chose {0}.', color);
}
});

var store = new Ext.data.ArrayStore({
fields: ['abbr', 'state'],
data : Ext.exampledata.states // from states.js
});

var combo = new Ext.form.ComboBox({
store: store,
displayField: 'state',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText: 'Select a state...',
selectOnFocus: true,
width: 135,
getListParent: function() {
return this.el.up('.x-menu');
},
iconCls: 'no-icon'
});

var menu = new Ext.menu.Menu({
id: 'mainMenu',
style: {
overflow: 'visible' // For the Combo popup
},
items: [
combo, // A Field in a Menu
{
text: 'I like Ext',
checked: true, // when checked has a boolean value, it is assumed to be a CheckItem
checkHandler: onItemCheck
}, '-', {
text: 'Radio Options',
menu: { // <-- submenu by nested config object
layout: 'column', // <-- change its layout to accomodate two Menus.
width: 400,
autoHeight: true,
style: {
'background-image': 'none'
},
defaults: {
xtype: 'menu',
floating: false,
columnWidth: 0.5,
hidden: false,
style: {
'border-color': 'transparent'
}
},
items: [{
items: [
// stick any markup in a menu
'<b class="menu-title">Choose a Theme</b>',
{
text: 'Aero Glass',
checked: true,
group: 'theme',
checkHandler: onItemCheck
}]
}, {
items: [{
text: 'Vista Black',
checked: false,
group: 'theme',
checkHandler: onItemCheck
}, {
text: 'Gray Theme',
checked: false,
group: 'theme',
checkHandler: onItemCheck
}, {
text: 'Default Theme',
checked: false,
group: 'theme',
checkHandler: onItemCheck
}]
}]
}
},{
text: 'Choose a Date',
iconCls: 'calendar',
menu: dateMenu // <-- submenu by reference
},{
text: 'Choose a Color',
menu: colorMenu // <-- submenu by reference
}
]
});

var tb = new Ext.Toolbar();
tb.render('toolbar');

tb.add({
text:'Button w/ Menu',
iconCls: 'bmenu', // <-- icon
menu: menu // assign menu by instance
},
new Ext.Toolbar.SplitButton({
text: 'Split Button',
handler: onButtonClick,
tooltip: {text:'This is a an example QuickTip for a toolbar item', title:'Tip Title'},
iconCls: 'blist',
// Menus can be built/referenced by using nested menu config objects
menu : {
items: [{
text: '<b>Bold</b>', handler: onItemClick
}, {
text: '<i>Italic</i>', handler: onItemClick
}, {
text: '<u>Underline</u>', handler: onItemClick
}, '-', {
text: 'Pick a Color',
handler: onItemClick,
menu: {
items: [
new Ext.ColorPalette({
listeners: {
select: function(cp, color){
Ext.example.msg('Color Selected', 'You chose {0}.', color);
}
}
}), '-',
{
text: 'More Colors...',
handler: onItemClick
}
]
}
}, {
text: 'Extellent!',
handler: onItemClick
}]
}
}), '-', {
text: 'Toggle Me',
enableToggle: true,
toggleHandler: onItemToggle,
pressed: true
});

menu.addSeparator();
// Menus have a rich api for
// adding and removing elements dynamically
var item = menu.add({
text: 'Dynamically added Item'
});
// items support full Observable API
item.on('click', onItemClick);

// items can easily be looked up
menu.add({
text: 'Disabled Item',
id: 'disableMe' // <-- Items can also have an id for easy lookup
// disabled: true <-- allowed but for sake of example we use long way below
});
// access items by id or index
menu.items.get('disableMe').disable();

// They can also be referenced by id in or components
tb.add('-', {
icon: 'list-items.gif', // icons can also be specified inline
cls: 'x-btn-icon',
tooltip: '<b>Quick Tips</b><br/>Icon only button with tooltip'
}, '-');

var scrollMenu = new Ext.menu.Menu();
for (var i = 0; i < 50; ++i){
scrollMenu.add({
text: 'Item ' + (i + 1)
});
}
// scrollable menu
tb.add({
icon: 'preview.png',
cls: 'x-btn-text-icon',
text: 'Scrolling Menu',
menu: scrollMenu
});

// add a combobox to the toolbar
var combo = new Ext.form.ComboBox({
store: store,
displayField: 'state',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Select a state...',
selectOnFocus:true,
width:135
});
tb.addField(combo);

tb.doLayout();

// functions to display feedback
function onButtonClick(btn){
Ext.example.msg('Button Click','You clicked the "{0}" button.', btn.text);
}

function onItemClick(item){
Ext.example.msg('Menu Click', 'You clicked the "{0}" menu item.', item.text);
}

function onItemCheck(item, checked){
Ext.example.msg('Item Check', 'You {1} the "{0}" menu item.', item.text, checked ? 'checked' : 'unchecked');
}

function onItemToggle(item, pressed){
Ext.example.msg('Button Toggled', 'Button "{0}" was toggled to {1}.', item.text, pressed);
}

});

mcouillard
21 Jul 2011, 5:19 AM
Thanks Animal. Your example worked; here's the code that relates to this thread:



var menu = new Ext.menu.Menu({
id: 'mainMenu',
layout: 'column', // <-- change its layout to accomodate two Menus.
width: 400, //required
autoHeight: true,
style: {
'background-image': 'none'
},
defaults: {
xtype: 'menu',
floating: false,
columnWidth: 0.33,
hidden: false,
style: {
'border-color': 'transparent'
}
},
items: [
{
items: [
'<b class="menu-title">Col1</b>',
{
text: 'Aero Glass'
},{
text: 'Aero Glass2'
}
]
}, {
items: [
'<b class="menu-title">Col2</b>',
{
text: 'Vista Black'
}, {
text: 'Gray Theme'
}, {
text: 'Default Theme'
}
]
}, {
items: [
'<b class="menu-title">Col3</b>',
{
text: 'Vista Black'
}, {
text: 'Gray Theme'
}, {
text: 'Default Theme'
}
]
}
]
});


This effectively makes ExtJS able to create a "mega menu", as they're called these days.

misterblinky
15 Nov 2011, 3:34 AM
The 'column' layout for menus is gone in Ext 4. I tried implementing it as an 'hbox' layout, with no luck. Here's my code if anyone is willing to take a look. This code results in two stacked menus -- not side-by-side.

BTW I posted also this request on the Ext 4 forum here (http://www.sencha.com/forum/showthread.php?154614-Multi-column-Menus-in-Ext-JS-4&p=673165#post673165). But since this is the post that helped me get this working in Ext 3, I thought I'd raise it here too.



Ext.onReady(function(){ Ext.QuickTips.init(); var menu = Ext.create('Ext.menu.Menu', { layout: { type: 'hbox', align: 'stretch' }, autoWidth: true, autoHeight: true, defaults: { xtype: 'menu', floating: false }, items: [ { items: [ {text: 'aaa'}, {text: 'bbb'}, {text: 'ccc'} ] }, { items: [ {text: 'ddd'}, {text: 'eee'}, {text: 'fff'} ] } ] }); var mytoolbar = Ext.create('Ext.toolbar.Toolbar'); mytoolbar.add({ text:'MultiColMenu', menu: menu } ); mytoolbar.render('toolbar'); mytoolbar.doLayout(); });

thanks for any thoughts