View Full Version : Creating a menu from source
frando
15 Mar 2007, 8:24 AM
Hey guys,
first of I'm *really* impressed with Ext so far!
But I've one question:
Is there a helper function or something to create a menu from the page source?
So imagine I have an ul tree like this:
<ul id="menu-main">
<a>First Menu</a>
<ul class="menu">
item 1
item 2
item 3
item 4
[/list]
<a>Second Menu</a>
<ul class="menu">
item 1
item 2
item 3
item 4
[/list]
[/list]
Or anything similar, but you get the idea...
What's the best/easiest way to create a menu out of this?
If there is no helper function, I'd just parse the tree with jquery and somehow create a menu out of the parse data. But I just wanted to ask first if there's a simpler way ...
regards,
frando[/code]
Animal
15 Mar 2007, 8:48 AM
There isn't anything to do this. Should be easy to do with Ext.query
frando
15 Mar 2007, 12:36 PM
Yup,
got already something working with jQuery. It's not really ful-featured yet, but it works.
I'm posting the code here for those who're interested (needs jquery.js):
function constructMenu(e) {
var items = [ ];
$(e).children('li').each( function() {
// set current item properties
var link = $(this).children('a:first');
var currentItem = {
text: $(link).html(),
cls: $(link).attr('class'),
id: $(link).attr('id'),
handler: menuClick
};
// check wether we have sub menus
if ($(this).children('ul').size()) {
var subitems = constructMenu($(this).children('ul:first'));
currentItem.menu = { items: subitems };
}
items.push( currentItem );
});
return items;
}
So that's the main function. It converts ul trees to a menu object (recursively, there's no depth limit).
The ul tree should look like this:
<ul id="menu-main">
<a class="menu-top">Simple Menu</a>
<ul>
<a>item 1b</a>
<a>item 2b</a>
<a>item 3b</a>
<a>item 4b</a>
[/list]
<a class="menu-top">Nested menu</a>
<ul>
<a id="item1">item 1</a>
<a id="item2">item 2</a>
<a id="item3">item 3</a>
<ul>
<a>subitem a</a>
<a>even another level</a>
<ul>
<a>foo</a>
<a>bar</a>
<a>lorem</a>
<a>ipsum</a>
[/list]
[/list]
<a id="item4">item 4</a>
[/list]
[/list]
And you use the function like this:
$(document).ready( function() {
var tb = new Ext.Toolbar('toolbar');
var menu = constructMenu('#menu-main');
tb.add(menu);
}
It doesn't allow for any fancy stuff like checkObjects yet, but it's working great for basic menus. Clicks can be caught in a function menuClick(e), and the clicked menu item either via e.text or e.id.
--frando
Animal
15 Mar 2007, 10:21 PM
Errr "$"???
Why not code it so that it can be read and followed? How much time do you save over typing Ext.get or whatever? Typing time is about .000001% of software development time. It's irritating and utterly, utterly, incomprehensibly, irresponsibly, unthinkingly, unjustifiably POINTLESS.
JeffHowden
15 Mar 2007, 11:24 PM
I think what Animal is trying to say is, why not leverage aspects of Ext that are not only easier to read, but also better performing while keeping every bit of the functionality you've implemented using the non-descriptive $() function that's native to jQuery.
Animal
16 Mar 2007, 1:20 AM
I hadn't had my morning coffee or oatmeal or exercise :roll:
Anyway, here's an Ext example which should drop into examples/menu
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Menu from markup</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<script type="text/javascript" src="../../yui-utilities.js"></script>
<script type="text/javascript" src="../../ext-yui-adapter.js"></script>
<script type="text/javascript" src="../../ext-all-debug.js"></script>
<script type="text/javascript">
function constructMenu(e, clickHandler) {
var items = [ ];
Ext.get(e).select('>li').each( function() {
// set current item properties
var link = this.child('a:first', true);
var currentItem = {
text: link.innerHTML,
cls: link.className,
id: link.id,
handler: clickHandler,
};
// Check for sub menu.
var s = this.select('>ul');
if (s.elements.length) {
currentItem.menu = {items: constructMenu(s.item(0), clickHandler)};
}
items.push(currentItem);
});
return items;
}
Ext.onReady(function() {
var m = new Ext.menu.Menu({id: "the-menu", items: constructMenu("menu-main", function(){alert("clicked")})});
Ext.get("menu-main").remove();
m.render();
m.show(Ext.get("container"));
});
</script>
</head>
<body>
<h1>Menu from markup</h1>
The js is not minified so it is readable. See menus.js.</p>
<div id="container">
</div>
<ul id="menu-main">
<a class="menu-top">Simple Menu</a>
<ul>
<a>item 1b</a>
<a>item 2b</a>
<a>item 3b</a>
<a>item 4b</a>
[/list]
<a class="menu-top">Nested menu</a>
<ul>
<a id="item1">item 1</a>
<a id="item2">item 2</a>
<a id="item3">item 3</a>
<ul>
<a>subitem a</a>
<a>even another level</a>
<ul>
<a>foo</a>
<a>bar</a>
<a>lorem</a>
<a>ipsum</a>
[/list]
[/list]
<a id="item4">item 4</a>
[/list]
[/list]
</body>
</html>
mikegiddens
16 Mar 2007, 6:58 AM
I have made my mind up that when I find a useful code I will post it on my website so others can see it in action. If you object animal or know of others that you would like to post just let me know. In the meantime I will be digging through the forum as I am searching for information and post others that I find to help the community.
http://www.greekhappy.com/ext/
Powered by vBulletin® Version 4.1.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.