Example application code:
    1 // vim: ts=2:sw=2:nu:fdc=4:nospell
    2 /**
    3   * Ext.ux.InfoPanel and Ext.ux.Accordion Example Application
    4   *
    5   * @author  Ing. Jozef Sakalos
    6   * @version $Id: accordion.js 61 2007-06-23 18:10:59Z jozo $
    7   *
    8   */
    9 
   10 // set blank image to local file
   11 Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
   12 
   13 // {{{
   14 /**
   15   * Ext.example class
   16   *
   17   * To display sliding popup. Borrowed from ExtJS examples.
   18   *
   19   * @class Ext.exammple
   20   * @singleton
   21   *
   22   */
   23 Ext.example = function() {
   24     var msgCt;
   25 
   26     function createBox(t, s){
   27         return ['<div class="msg">',
   28                 '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
   29                 '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc"><h3>', t,
   30                 '</h3>', s, '</div></div></div>',
   31                 '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
   32                 '</div>'].join('');
   33     }
   34     return {
   35         msg : function(title, format){
   36             if(!msgCt){
   37                 msgCt = Ext.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
   38             }
   39             msgCt.alignTo(document, 'bl-bl', [10, -90]);
   40             var s = String.format.apply(String, Array.prototype.slice.call(arguments, 1));
   41             var m = Ext.DomHelper.append(msgCt, {html:createBox(title, s)}, true);
   42             m.slideIn('b').pause(1).ghost("b", {remove:true});
   43         }
   44     };
   45 }();
   46 // }}}
   47 
   48 // run this function when document becomes ready
   49 Ext.onReady(function() {
   50 
   51   var iconPath = '../img/silk/icons/';
   52 
   53   // {{{
   54   // function to remove loading mask
   55   var unmask = function() {
   56     var mask = Ext.get('loading-mask');
   57     var msg = Ext.get('loading-msg');
   58     if(mask && msg) {
   59       mask.shift({
   60         xy:msg.getXY()
   61         , width:msg.getWidth()
   62         , height:msg.getHeight()
   63         , remove: true
   64         , duration: 1.6
   65         , opacity: 0.3
   66         , easing: 'bounceOut'
   67         , callback: function(){Ext.fly(msg).remove();}
   68       });
   69     }
   70   };
   71   // }}}
   72 
   73   // install onclick handler to unmask body (for debugging)
   74   Ext.fly('loading-mask').on('click', unmask);
   75 
   76   // initialize state manager, we will use cookies
   77   Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
   78 
   79   // initialize QuickTips
   80   Ext.QuickTips.init();
   81   Ext.apply(Ext.QuickTips, {interceptTitles: true});
   82 
   83   // {{{
   84   // create layout
   85   var layout = new Ext.BorderLayout(document.body, {
   86     hideOnLayout: true
   87     , north: { split: false, initialSize: 34, titlebar: false }
   88     , west: {
   89       split: true
   90       , initialSize: 220
   91       , minSize: 220
   92       , maxSize: 300
   93       , titlebar: false
   94       , collapsible: true
   95       , showPin: true
   96       , animate: true
   97     }
   98     , center: {
   99       titlebar: true
  100       , autoScroll: false
  101     }
  102     , south: {
  103       titlebar: true
  104       , split: true
  105       , initialSize: 56
  106       , collapsible: true
  107       , collapsed: true
  108       , hidden: false
  109       , collapsedTitle: 'South'
  110       , animate: true
  111       , showPin: true
  112     }
  113     , east: {
  114       titlebar: true
  115       , split: false
  116       , initialSize: 142
  117       , collapsible: false
  118       , autoScroll: true
  119     }
  120   });
  121   // }}}
  122   // {{{
  123   // create accordion in west region
  124   var acc = new Ext.ux.Accordion('west', {
  125     title: 'Accordion'
  126     , body: 'west-body'
  127     , fitContainer: true
  128     , fitToFrame: true
  129     , useShadow: true
  130     , adjustments: [ 0, -26 ]
  131   });
  132   // }}}
  133   // {{{
  134   // create global toolbar
  135   acc.toolbar = new Ext.Toolbar('acc-tb-global', [
  136 
  137     // reset order
  138     { tooltip: 'Reset order'
  139       , cls: 'x-btn-icon'
  140       , icon: iconPath + 'application_put.png'
  141       , scope: acc
  142       , handler: acc.resetOrder
  143     }
  144 
  145     // undockable mode
  146     , { tooltip: 'Undockable mode'
  147       , cls: 'x-btn-icon'
  148       , enableToggle: true
  149       , id: 'btn-undockable'
  150       , icon: iconPath + 'layout_content.png'
  151       , scope: acc
  152       , handler: function(btn, e) {
  153         this.setUndockable(btn.pressed);
  154       }
  155     }
  156 
  157     // independent mode
  158     , { tooltip: 'Independent mode'
  159       , cls: 'x-btn-icon'
  160       , enableToggle: true
  161       , id: 'btn-independent'
  162       , icon: iconPath + 'application_tile_vertical.png'
  163       , scope: acc
  164       , handler: function(btn, e) {
  165         if(!btn.pressed) {
  166           this.collapseAll(false);
  167         }
  168         this.setIndependent(btn.pressed);
  169       }
  170     }
  171 
  172     // collapse all
  173     , { tooltip: 'Collapse all (also pinned)'
  174       , cls: 'x-btn-icon'
  175       , icon: iconPath + 'application_view_list.png'
  176       , scope: acc
  177       , handler: function(btn, e) {
  178         this.collapseAll(true);
  179       }
  180     }
  181 
  182     // expand all
  183     , { tooltip: 'Expand all (in independent mode)'
  184       , cls: 'x-btn-icon'
  185       , icon: iconPath + 'application_view_tile.png'
  186       , scope: acc
  187       , handler: function(btn, e) {
  188         this.expandAll();
  189       }
  190     }
  191 
  192     // use shadows
  193     , { tooltip: 'Use shadows for undocked panels'
  194       , id: 'btn-shadow'
  195       , cls: 'x-btn-icon'
  196       , enableToggle: true
  197       , icon: iconPath + 'contrast_low.png'
  198       , scope: acc
  199       , handler: function(btn, e) {
  200         this.setShadow(btn.pressed);
  201       }
  202     }
  203 
  204     // separator
  205     , '-'
  206 
  207     // find text
  208     , 'Find:'
  209 
  210     // search text input field
  211     , new Ext.form.TextField({
  212         id: 'find-field'
  213       , msgTarget:'side'
  214       , autoCreate: {
  215           tag:'input'
  216         , type:'text'
  217         , qtip:'Try to type <b>&quot;acc&quot;</b> here.<br>'
  218             + 'Then switch to independent mode and type <b>&quot;note&quot;</b> here.<br>'
  219             + 'You can try also <b>&quot;dev&quot;</b> and <b>&quot;comp&quot;</b>'
  220         , size:3
  221       }
  222     })
  223   ]);
  224   // }}}
  225   // {{{
  226   // add panels to west accordion
  227 
  228   // Introduction
  229   var panel1 = new Ext.ux.InfoPanel('panel-1', {
  230     trigger:'title', collapsed:true
  231     , icon: iconPath + 'lightbulb_off.png'
  232     , showPin: true
  233     , collapseOnUnpin: false
  234   });
  235 
  236   // example of installing custom panel event handlers
  237   acc.add(panel1);
  238   panel1.on('expand', function(panel) {
  239     Ext.example.msg('expand event handler', 'Panel: ' + panel.getTitle());
  240 //    panel.setIcon(iconPath + 'lightbulb.png');
  241   });
  242 
  243   panel1.on('collapse', function(panel) {
  244     Ext.example.msg('collapse event handler', 'Panel: ' + panel.getTitle());
  245 //    panel.setIcon(iconPath + 'lightbulb_off.png');
  246   });
  247 
  248   // extjs
  249   acc.add(new Ext.ux.InfoPanel('panel-2', {
  250     trigger:'title', collapsed:true
  251     , icon: iconPath + 'brick.png'
  252     , showPin: true
  253     , collapseOnUnpin: false
  254   }));
  255 
  256   // usage
  257   var panel3 = acc.add(new Ext.ux.InfoPanel('panel-3', {
  258     trigger:'title', collapsed:true
  259     , icon: iconPath + 'layout.png'
  260   }));
  261 
  262   // create toolbar for panel 3
  263   var toolbar3 = panel3.createToolbar();
  264 
  265   // add greedy spacer to align button right
  266   Ext.fly(toolbar3.addSpacer().getEl().parentNode).setStyle('width', '100%');
  267   toolbar3.add([{
  268     icon: iconPath + 'application_put.png'
  269     , cls: 'x-btn-text-icon'
  270     , text: 'Reset order'
  271     , scope: acc
  272     , handler: acc.resetOrder
  273   }]);
  274 
  275   // drag & drop
  276   var panel4 = acc.add(new Ext.ux.InfoPanel('panel-4', {
  277     trigger:'title', collapsed:true
  278     , icon: iconPath + 'mouse.png'
  279   }));
  280 
  281   // create bottom toolbar for panel 4
  282   var toolbar4 = panel4.createToolbar([], true);
  283 
  284   // add greedy spacer to align button right
  285   Ext.fly(toolbar4.addSpacer().getEl().parentNode).setStyle('width', '100%');
  286   toolbar4.add([{
  287     icon: iconPath + 'mouse.png'
  288     , cls: 'x-btn-text-icon'
  289     , text: 'Button'
  290     , scope: this
  291     , handler: function() {
  292       alert('You clicked me');
  293     }
  294   }]);
  295 
  296   // configuration options
  297   acc.add(new Ext.ux.InfoPanel('panel-5', {
  298     trigger:'title'
  299     , collapsed:true
  300     , icon: iconPath + 'wrench.png'
  301 //    , autoScroll: true
  302   }));
  303 
  304   // custom functions
  305   var panel6 = acc.add(new Ext.ux.InfoPanel({
  306     title:'6. Custom functions'
  307     , icon: iconPath + 'script.png'
  308     , id:'panel-6'
  309     , autoCreate: {
  310       tag:'div'
  311     }
  312   }));
  313 
  314   // set content for panel 6
  315   panel6.update(
  316     '<div class="text-content">'
  317     + '<p>Both Accordion and InfoPanel expose an Application Programming Interface (API) that makes'
  318     + ' implementation of custom functions easy.</p>'
  319     + '<p>The above Search function is one example of that. Try to'
  320     + ' type three or more characters in the Find input.</p>'
  321     + '</div>'
  322   );
  323 
  324   // theme selector
  325   var panel7 = acc.add(new Ext.ux.InfoPanel('panel-7', {
  326     icon: iconPath + 'palette.png'
  327     , showPin: true
  328     , minWidth: 200
  329     , minHeight: 100
  330   }));
  331   var ctheme = new Ext.form.ComboBox({
  332     typeAhead: true
  333     , triggerAction: 'all'
  334     , transform: 'theme-combo'
  335     , forceSelection: true
  336     , width: 140
  337     , listWidth: 158
  338   });
  339 
  340   // change theme on combo select
  341   ctheme.on('select', function() {
  342     Ext.util.CSS.swapStyleSheet('theme', '../extjs/resources/css/' + this.getValue());
  343   }, ctheme);
  344 
  345   // donate
  346   var panel8 = acc.add(new Ext.ux.InfoPanel('panel-8', {
  347     icon: iconPath + 'money.png'
  348   }));
  349   // {{{
  350   // add google search panel
  351   var pnGoogle = acc.add(new Ext.ux.InfoPanel.GoogleSearch('google-search', {
  352     icon: iconPath + 'magnifier.png'
  353     , searchBtnIcon: iconPath + 'magnifier.png'
  354     , searchTextSize: 25
  355     , searchResultIframe: 'center-result'
  356   }));
  357   pnGoogle.searchButton.on({
  358     click: {
  359       fn: function() {
  360       layout.getRegion('center').getTabs().getTab('center-result').activate();
  361     }}
  362   });
  363 
  364 //  // create nicer Ext form
  365 //  var gsForm = new Ext.BasicForm(pnGoogle.body.select('form').item(0), {});
  366 //
  367 //  // disable submit
  368 //  gsForm.el.dom.onsubmit = function() { return false };
  369 //
  370 //  // beautify search text input
  371 //  var gsText = new Ext.form.TextField({});
  372 //  gsText.applyTo(gsForm.el.select('input[type=text]').item(0));
  373 //  gsText.el.dom.size = 25;
  374 //
  375 //  // remove original google button
  376 //  Ext.fly('sbb').remove();
  377 //
  378 //  // create new nicer button
  379 //  var gsBtn = new Ext.Button(gsForm.el, {
  380 //    text: "Search"
  381 //    , icon: iconPath + 'magnifier.png'
  382 //    , cls: 'x-btn-text-icon'
  383 ////    , name: 'sa'
  384 //    , type: 'submit'
  385 ////    , id: 'sbb'
  386 ////    , value: 'Search'
  387 //    , handler: function() {
  388 //      // activate search results tab
  389 //      layout.getRegion('center').getTabs().getTab('center-result').activate();
  390 //
  391 //      // create google search URL
  392 //      var inputs = gsForm.el.select('input');
  393 //      var getPars = [];
  394 //      inputs.each(function(el) {
  395 //        if('radio' === el.dom.type && !el.dom.checked) {
  396 //          return;
  397 //        }
  398 //        getPars.push(el.dom.name + '=' + encodeURIComponent(el.dom.value));
  399 //      });
  400 //      var gsURL = 'http://www.google.com/custom?' + getPars.join('&');
  401 //
  402 //      // set iframe src attribute
  403 //      Ext.get('center-result').dom.src = gsURL;
  404 //
  405 //    }
  406 //  });
  407   // }}}
  408 
  409   // useful links
  410   var panel10 = acc.add(new Ext.ux.InfoPanel('panel-10', {
  411     icon: iconPath + 'world_link.png'
  412   }));
  413   panel10.body.on({
  414     click: {
  415       stopEvent: true
  416       , delegate: 'a'
  417       , scope: null
  418       , fn: function(e, target) {
  419         layout.getRegion('center').getTabs().getTab('center-result').activate();
  420         Ext.get('center-result').dom.src = target.href;
  421       }
  422     }
  423   });
  424   // }}}
  425   // {{{
  426   // create fitHeight accordion
  427   var acc2 = new Ext.ux.Accordion('acc2-body', {
  428     body: 'acc2-body'
  429     , boxWrap: true
  430     , wrapEl: 'acc2-wrap'
  431     , fitContainer: true
  432     , fitToFrame: true
  433     , fitHeight: true
  434     , initialHeight: 240
  435     , desktop: 'center-accordions'
  436 //    , animate: false
  437   });
  438   // }}}
  439   // {{{
  440   // add panels to fitHeight accordion
  441   acc2.add(new Ext.ux.InfoPanel('panel2-1', {
  442     icon: iconPath + 'calendar_view_month.png'
  443 //    , autoScroll: true
  444   }));
  445 
  446   acc2.add(new Ext.ux.InfoPanel('panel2-2', {
  447     icon: iconPath + 'database_table.png'
  448   }));
  449 
  450   acc2.add(new Ext.ux.InfoPanel('panel2-3', {
  451     icon: iconPath + 'cart.png'
  452   }));
  453 
  454   acc2.add(new Ext.ux.InfoPanel('panel2-4', {
  455     icon: iconPath + 'email.png'
  456   }));
  457 
  458   acc2.add(new Ext.ux.InfoPanel('panel2-5', {
  459     icon: iconPath + 'feed.png'
  460   }));
  461   // }}}
  462   // {{{
  463   // resizing of fitHeight accordion
  464   var acc2Ct = Ext.get('acc2-ct');
  465   var resizer = new Ext.Resizable(acc2Ct, {
  466     handles:'s e se'
  467     , transparent: true
  468     , minHeight: 180 //244
  469     , minWidth: 150 // 224
  470     , pinned: true
  471   });
  472   resizer.on({
  473     beforeresize: {
  474       scope:acc2
  475       , fn: function(r, e) {
  476 
  477         // save old sizes
  478         r.oldSize = acc2Ct.getSize();
  479         r.oldAccSize = this.body.getSize();
  480     }}
  481     , resize: {
  482       scope:acc2
  483       , fn: function(r, w, h, e) {
  484 
  485         // calculate deltas
  486         var dw, dh;
  487         dw = w - r.oldSize.width;
  488         dh = h - r.oldSize.height;
  489 
  490         // resize Accordion
  491         this.setSize(r.oldAccSize.width + dw, r.oldAccSize.height + dh);
  492 
  493     }}
  494   });
  495   // }}}
  496   // {{{
  497   // Accordion in dialog
  498   var accDlgShow = function(btn, e) {
  499 
  500     var dpanel4, stickyNote;
  501 
  502     // {{{
  503     // lazy create the dialog
  504     if(!this.dlg) {
  505 
  506       // create the BasicDialog
  507       this.dlg = new Ext.BasicDialog('acc-dialog', {
  508         width: 220
  509         , height: 220
  510         , x: 560
  511         , y: 144
  512         , modal: false
  513         , shadow: true
  514         , proxyDrag: true
  515       });
  516 
  517       // add hide on escape pressed handler
  518       this.dlg.addKeyListener(27, this.dlg.hide, this.dlg);
  519 
  520       // create the Accordion
  521       this.acc = new Ext.ux.Accordion(this.dlg.body, {
  522         fitHeight: true
  523         , fitToFrame: true
  524         , fitContainer: true
  525         , desktop: 'center-accordions'
  526         , autoScroll: false
  527       });
  528 
  529       // add panels
  530       this.acc.add(new Ext.ux.InfoPanel('dpanel-1', {
  531         icon: iconPath + 'application_home.png'
  532       }));
  533 
  534       this.acc.add(new Ext.ux.InfoPanel('dpanel-2', {
  535         icon: iconPath + 'emoticon_happy.png'
  536       }));
  537 
  538       this.acc.add(new Ext.ux.InfoPanel('dpanel-3', {
  539         icon: iconPath + 'mouse.png'
  540       }));
  541 
  542       // inform accordion of dialog resize
  543       this.dlg.on('resize', function(dlg, w, h) {
  544         this.setSize(dlg.body.getWidth(), dlg.body.getHeight());
  545       }, this.acc);
  546 
  547       // update text of show/hide button
  548       this.dlg.on('show', function() {
  549         btn.setText('Hide Accordion Dialog');
  550         this.setPanelHeight();
  551 
  552         // fix the firefox cursor bug
  553 //        var dlgCt;
  554 //        if(Ext.isGecko) {
  555 //          dlgCt = Ext.get('acc-dialog');
  556 //          dlgCt.setStyle('overflow','');
  557 //          dlgCt.setStyle.defer(10, dlgCt, ['overflow','auto']);
  558 //        }
  559 
  560       }, this.acc);
  561       this.dlg.on('hide', function() {btn.setText('Show Accordion Dialog');});
  562 
  563 //      this.acc.restoreState();
  564 //      if(!dpanel4.collapsed) {
  565 //        stickyNote.fitToParent();
  566 //      }
  567 
  568     } // end of dlg lazy creation
  569     // }}}
  570 
  571     // show/hide dialog on button click
  572     if(this.dlg.isVisible()) {
  573       this.dlg.hide(btn.el);
  574     }
  575     else {
  576       this.dlg.show(btn.el);
  577     }
  578   }; // end of function accDlgShow
  579   // }}}
  580   // {{{
  581   // create show/hide dialog button
  582   var btnDlg = new Ext.Button('btn-show-dlg', {
  583     icon: iconPath + 'application.png'
  584     , cls: 'x-btn-text-icon'
  585     , text: 'Show Accordion Dialog'
  586     , scope: accDlgShow
  587     , handler: accDlgShow
  588   });
  589   // }}}
  590 // {{{
  591   // independent panels example
  592   var ipanel1 = new Ext.ux.InfoPanel('ipanel-1', {
  593     collapsed: false
  594   });
  595   var ipanel2 = new Ext.ux.InfoPanel('ipanel-2', {
  596     animate: false
  597   });
  598   var ipanel3 = new Ext.ux.InfoPanel('ipanel-3', {
  599     trigger: 'button'
  600   });
  601   var ipanel4 = new Ext.ux.InfoPanel('ipanel-4', {
  602     title:'4. Container from markup'
  603     , content:
  604       '<div class="text-content">'
  605       + '<h3>Container from markup, body from code</h3>'
  606 //      + '<p>&nbsp;</p>'
  607       + '<p>Markup:<p>'
  608       + '<pre class="code">'
  609       + '&lt;div id="ipanel-4"&gt;&lt/div&gt;'
  610       + '</pre>'
  611       + '<p>Code:<p>'
  612       + '<pre class="code">'
  613       + 'new Ext.ux.InfoPanel(\'ipanel-4\', {\n'
  614       + '  title:\'4. Container from...\'\n'
  615       + '  , content:\'This text.\'\n'
  616       + '  , useShadow:true\n'
  617       + '  , easingCollapse: \'backIn\'\n'
  618       + '  , easingExpand: \'backOut\'\n'
  619       + '});'
  620       + '</pre>'
  621       + '</div>'
  622     , useShadow: true
  623     , easingCollapse: 'backIn'
  624     , easingExpand: 'backOut'
  625   });
  626 
  627   var ipanel5 = new Ext.ux.InfoPanel('ipanel-5', {
  628     useShadow: true
  629     , draggable: true
  630     , desktop:'panels-tab'
  631     , duration: 1.0
  632   });
  633 
  634   var ipanel6 = new Ext.ux.InfoPanel({
  635     title: '6. Auto-created panel, no markup'
  636     , id:'ipanel-6'
  637     , desktop: 'panels-tab'
  638     , draggable: true
  639     , useShadow: true
  640     , autoCreate: {
  641       tag:'div'
  642       , children:[{
  643         tag:'div'
  644         , cls:'text-content'
  645         , html: '<h3>No html markup, autoCreate object.</h3>'
  646         + '<p>&nbsp;</p>'
  647         + '<p>Code:</p>'
  648         + '<pre class="code">'
  649         + 'new Ext.ux.InfoPanel({\n'
  650         + '    title: \'6. Auto-created...\'\n'
  651         + '  , id: \'ipanel-6\'\n'
  652         + '  , desktop: \'panels-tab\'\n'
  653         + '  , draggable: true\n'
  654         + '  , useShadow: true\n'
  655         + '  , autoCreate: {\n'
  656         + '      tag: \'div\'\n'
  657         + '    , children:[{\n'
  658         + '        tag: \'div\'\n'
  659         + '      , cls: \'text-content\'\n'
  660         + '      , html: \'This text.\'\n'
  661         + '    }]\n'
  662         + '  }\n'
  663         + '});'
  664         + '</pre>'
  665       }]
  666     }
  667   });
  668 
  669   var ipanel7 = new Ext.ux.InfoPanel({
  670     title: '7. Auto-created, body from markup'
  671     , id: 'ipanel-7'
  672     , desktop: 'panels-tab'
  673     , bodyEl: 'ipanel-7-body'
  674     , autoCreate: true
  675     , draggable: true
  676     , useShadow: true
  677     , resizable: true
  678   });
  679 
  680   if(showGrid) {
  681     var ipanel8 = new Ext.ux.InfoPanel({
  682       id: 'ipanel-8'
  683       , title: '8. Grid in the panel'
  684       , reiszable: true
  685       , collapsed: true
  686       , draggable: true
  687       , resizable: true
  688       , animate: false
  689       , useShadow: true
  690     //  , autoScroll: true
  691       , desktop: 'panels-tab'
  692       , autoCreate: {
  693         tag:'div'
  694         , style: 'position:absolute;width:600px;left:244px;top:130px'
  695         , children: [{
  696           tag: 'div'
  697           , style: 'height:300px;overflow:auto'
  698           , id: 'grid-ct'
  699         }]
  700       }
  701     });
  702 
  703         // some data yanked off the web
  704         var myData = [
  705       ['3m Co',71.72,0.02,0.03,'9/1 12:00am'],
  706             ['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am'],
  707             ['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am'],
  708             ['American Express Company',52.55,0.01,0.02,'9/1 12:00am'],
  709             ['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am'],
  710             ['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am'],
  711             ['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am'],
  712             ['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am'],
  713             ['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am'],
  714             ['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am'],
  715             ['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am'],
  716             ['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am'],
  717             ['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am'],
  718             ['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am'],
  719             ['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am'],
  720             ['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am'],
  721             ['International Business Machines',81.41,0.44,0.54,'9/1 12:00am'],
  722             ['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am'],
  723             ['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am'],
  724             ['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am'],
  725             ['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am'],
  726             ['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am'],
  727             ['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am'],
  728             ['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am'],
  729             ['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am'],
  730             ['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am'],
  731             ['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am'],
  732             ['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am'],
  733             ['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am'],
  734             ['Walt Disney Company (The) (Holding Company)',29.89,0.24,0.81,'9/1 12:00am']
  735     ];
  736 
  737         var ds = new Ext.data.Store({
  738             proxy: new Ext.data.MemoryProxy(myData),
  739             reader: new Ext.data.ArrayReader({}, [
  740                        {name: 'company'},
  741                        {name: 'price', type: 'float'},
  742                        {name: 'change', type: 'float'},
  743                        {name: 'pctChange', type: 'float'},
  744                        {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
  745                   ])
  746         });
  747         ds.load();
  748 
  749     // example of custom renderer function
  750         function italic(value){
  751             return '<i>' + value + '</i>';
  752         }
  753 
  754     // example of custom renderer function
  755         function change(val){
  756             if(val > 0){
  757                 return '<span style="color:green;">' + val + '</span>';
  758             }else if(val < 0){
  759                 return '<span style="color:red;">' + val + '</span>';
  760             }
  761             return val;
  762         }
  763     // example of custom renderer function
  764         function pctChange(val){
  765         if(val > 0){
  766             return '<span style="color:green;">' + val + '%</span>';
  767         }else if(val < 0){
  768             return '<span style="color:red;">' + val + '%</span>';
  769         }
  770         return val;
  771     }
  772 
  773     // the DefaultColumnModel expects this blob to define columns. It can be extended to provide
  774         // custom or reusable ColumnModels
  775         var colModel = new Ext.grid.ColumnModel([
  776       {id:'company',header: "Company", width: 160, sortable: true, locked:false, dataIndex: 'company'},
  777       {header: "Price", width: 75, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'},
  778       {header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change'},
  779       {header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
  780       {header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
  781     ]);
  782 
  783 
  784     // create the Grid
  785     var grid = new Ext.grid.Grid('grid-ct', {
  786       ds: ds
  787       , cm: colModel
  788       , autoExpandColumn: 'company'
  789 //      , enableColumnMove: false
  790     });
  791 
  792 //        var gridLayout = Ext.BorderLayout.create({
  793 //            center: {
  794 //                margins:{left:3,top:3,right:3,bottom:3},
  795 //                panels: [new Ext.GridPanel(grid)]
  796 //            }
  797 //        }, 'grid-panel-ct');
  798 
  799 //    grid.render();
  800 //    grid.getSelectionModel().selectFirstRow();
  801 
  802     ipanel8.on({
  803       expand: {
  804         scope: grid
  805         , single: true
  806         , fn: function(panel) {
  807           this.render();
  808           this.getSelectionModel().selectFirstRow();
  809       }}
  810       , resize: {
  811         scope: grid
  812         , fn: function() {
  813           Ext.get('grid-ct').fitToParent();
  814           grid.autoSize();
  815       }}
  816     });
  817 } // if(showGrid) end
  818 
  819 //  var ipanel9 = new Ext.ux.InfoPanel({
  820 //    title: '9. Loaded by Ajax on expand'
  821 //    , id:'ipanel-9'
  822 //    , url: 'panel-content.php'
  823 //    , desktop: 'panels-tab'
  824 //    , draggable: true
  825 //    , resizable: true
  826 //    , useShadow: true
  827 ////    , loadOnce: true
  828 //    , autoCreate: {
  829 //      tag: 'div'
  830 //      , style: 'position:absolute;width:200px;top:350px;left:20px'
  831 //    }
  832 //  });
  833 // }}}
  834   // {{{
  835   // add panels to layout
  836   layout.beginUpdate();