APEX & ExtJS Integration – Report column links that open in an Ext window APEX & ExtJS Integration – Ext Grid Grouping Revisited
Jul 14
Today’s post focuses on reusing our tab panel functionality for cross site searching, i.e. from one search box and a single mouse click we can fire off a search against multiple websites and display the sites results in their own tab within our page center tab panel. It’s a simple technique to show you how to use iframes to your advantage which also make use of the browser multi threading as each tab opens simultaneously.
How its done:
- We save our search links to a backend table (minus the search string)
- We create our toolbar javascript source which creates a text field in the toolbar, along with a split button for running the search and a menu for configuring which sites we are to search against and which one to put in focus. (It also contains an options menu for theme switching)
/* * Ext JS Library 2.2.1 * Copyright(c) 2006-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license * * APEX &amp;amp;amp; Ext JS Integration Kit - 2.2.1 * Copyright(c) 2009-2010, e-DBA Ltd * apex-sig@e-dba.com * * http://www.e-dba.com/uk/f?p=WEBSITE:APEXTJS_LICENSE */ Ext.app.appToolbar = function (pMetaObj, pRenderTo) { Ext.QuickTips.init(); var multisiteSearchMenu = new Ext.menu.Menu({ id: 'multisite-search-menu', items: pMetaObj.menuMssItems }); var optionsMenu = new Ext.menu.Menu({ id: 'options-menu', items: pMetaObj.menuOptionsItems }); var tb = new Ext.Toolbar(); tb.render(pRenderTo); var searchfield = new Ext.form.TextField({ "id": 'multisite-search-field', "allowBlank": true, "width": 200 }); tb.add(searchfield); var splitbutton = new Ext.Toolbar.SplitButton({ id: 'multisite-search-button', text: 'Search Sites', iconCls: 'icon-searchsites', handler: onSearchSiteClick, menu: multisiteSearchMenu }); tb.add(splitbutton, { text: 'Options', iconCls: 'icon-options', menu: { items: [{ text: 'Select a Theme', iconCls: 'icon-theme', menu: optionsMenu }] } }); // Were going to look for any class based items which belong in the toolbar Ext.select('a[class*=ext-' + pRenderTo + ']', true).each(function (el) { tb.add({ text: el.dom.firstChild.data, iconCls: 'icon-button', handler: function (btn) { window.location = el.dom.href; } }); Ext.destroy(el); }); // functions to display feedback function onSearchSiteClick(btn) { var searchText = Ext.get('multisite-search-field').getValue(); var activeTab, activeTabText = ""; if (searchText) { menu = Ext.getCmp('multisite-search-button').menu; for (var i = 0; i < menu.items.length; i++) { if ((menu.items.get(i).checked) && (menu.items.get(i).getId().indexOf('mssTabFocus') !== -1)) { activeTabText = menu.items.get(i).text; } } for (var i = 0; i < menu.items.length; i++) { if ((menu.items.get(i).checked) && (menu.items.get(i).getId().indexOf('mssSite') !== -1) && (menu.items.get(i).text !== activeTabText)) { var href = eval("pMetaObj." + menu.items.get(i).getId()) + searchText; centerPanel.loadTab(href, menu.items.get(i).getId(), menu.items.get(i).text, 'Info here soon', true); } else if (menu.items.get(i).text == activeTabText) { activeTab = menu.items.get(i); } } if (activeTab) { var href = eval("pMetaObj." + activeTab.getId()) + searchText; centerPanel.loadTab(href, activeTab.getId(), activeTab.text, 'Info here soon', true); } } } function onItemCheck(item, checked) { alert('Item Check'); } function onItemToggle(item, pressed) { alert('Button Toggled'); } } - We update our navigation bar entries to convert them into toolbar buttons by performing a javascript transform on the anchor links. We set a class attribute of “ext-”+pRenderTo which is the id of our toolbar div container, in order to define which toolbar they belong to. Note: the following source was in the above JS..
// Were going to look for any class based items which belong in the toolbar Ext.select('a[class*=ext-' + pRenderTo + ']', true).each(function (el) { tb.add({ text: el.dom.firstChild.data, iconCls: 'icon-button', handler: function (btn) { window.location = el.dom.href; } }); Ext.destroy(el); }); - We create our JSON meta data object in the page header which contains our searching reference, saves us firing a page post each time we search, alternatively we can grab the JSON object via an AJAX call if we’re going to allow the addition of extra sites at run time.
var extMultisiteSearchJSONObject = { "mssSite2": "http:\/\/www.google.com\/search?q=", "mssTabFocus2": "http:\/\/www.google.com\/search?q=", "mssSite1": "http:\/\/search.oracle.com\/search\/search?start=1&amp;amp;amp;nodeid=&amp;amp;amp;fid=&amp;amp;amp;group=Oracle.com&amp;amp;amp;keyword=", "mssTabFocus1": "http:\/\/search.oracle.com\/search\/search?start=1&amp;amp;amp;nodeid=&amp;amp;amp;fid=&amp;amp;amp;group=Oracle.com&amp;amp;amp;keyword=", "mssSite13": "http:\/\/en.wikipedia.org\/wiki\/", "mssTabFocus13": "http:\/\/en.wikipedia.org\/wiki\/", "menuMssItems": ['<b class="menu-title">Search Sites</b>', { "id": "mssSite2", "text": "Google", "checked": true }, { "id": "mssSite1", "text": "Oracle", "checked": true }, { "id": "mssSite13", "text": "Wikipedia", "checked": true }, '-', '<b class="menu-title">Tab Focus</b>', { "id": "mssTabFocus2", "text": "Google", "group": "active-tab", "checked": false }, { "id": "mssTabFocus1", "text": "Oracle", "group": "active-tab", "checked": false }, { "id": "mssTabFocus13", "text": "Wikipedia", "group": "active-tab", "checked": false }], "themeMenuItem13": "\/resources\/css\/xtheme-aero.css", "themeMenuItem4": "\/resources\/css\/xtheme-darkgray.css", "themeMenuItem3": "\/resources\/css\/xtheme-gray-extend.css", "themeMenuItem7": "\/resources\/css\/xtheme-midnight.css", "themeMenuItem9": "\/resources\/css\/xtheme-olive.css", "themeMenuItem12": "\/resources\/css\/xtheme-slickness.css", "themeMenuItem8": "\/resources\/css\/xtheme-black.css", "menuOptionsItems": [{ "id": "themeMenuItem13", "text": "Aero Glass", "group": "theme", "checked": false, "handler": Ext.app.onThemeSwitch }, { "id": "themeMenuItem4", "text": "Dark Grey Theme", "group": "theme", "checked": false, "handler": Ext.app.onThemeSwitch }, { "id": "themeMenuItem3", "text": "Grey Theme", "group": "theme", "checked": false, "handler": Ext.app.onThemeSwitch }, { "id": "themeMenuItem7", "text": "Midnight", "group": "theme", "checked": false, "handler": Ext.app.onThemeSwitch }, { "id": "themeMenuItem9", "text": "Olive Theme", "group": "theme", "checked": false, "handler": Ext.app.onThemeSwitch }, { "id": "themeMenuItem12", "text": "Slickness", "group": "theme", "checked": false, "handler": Ext.app.onThemeSwitch }, { "id": "themeMenuItem8", "text": "Vista Black", "group": "theme", "checked": false, "handler": Ext.app.onThemeSwitch }] } - We update our page template to define the HTML where we will render the toolbar to (it has the id “north-toolbar”)
<div id="north-pane"> <table cellpadding="0" cellspacing="0" summary=""><tr><td width="100%"> <div style="margin:5px;display:inline;float:left;">#LOGO#</div></td><td valign="top"> <div align="right" style="display:inline;float:right;">#REGION_POSITION_03#<div id="north-toolbar"></div><div valign="bottom" align="right" style="padding:3px;">#NAVIGATION_BAR#</div></div></td></tr></table> </div> - Finally we add the onload event to render the toolbar…
Ext.onReady(function() { Ext.app.appToolbar(extMultisiteSearchJSONObject,"north-toolbar"); });
The end result looks like this….

