PDA

View Full Version : Grid inside jtab not rendering



Aaryn015
19 Sep 2007, 9:50 PM
Hi all,

I've got dynamic tab set in my center panel that changes depending on the node that is selected in a tree in the west panel. All working well.

I am creating these tabs using the jtab method, and using setDefaultUrl to get the tab content.

However, my method of doing this must be incorrect, because if I view the setDefaultUrl value in a browser, the grid renders fine. However if I view using the tab in the application, the grid is missing. (Other html is rendered). It seems that the document load event isn't firing because the tabs have already loaded the document.

Like so:

Javascript for rendering the tabs (works fine)


var TabsCompany = {
init : function(){

// Second tabs built from JS
var jtabs = new Ext.TabPanel('jtabs');

var tab1 = jtabs.addTab('jtabs-1', "Site Info");
var updater = tab1.getUpdateManager();
updater.setDefaultUrl('/tab_pages/site/site-info.php?site_array=' + parent.globalSelectedTreeNode.id);
tab1.on('activate', updater.refresh, updater, true);

var tab2 = jtabs.addTab('jtabs-2', "Data Servers");
var updater = tab2.getUpdateManager();
updater.setDefaultUrl('/tab_pages/site/site-data-servers.php?site_array=' + parent.globalSelectedTreeNode.id);
tab2.on('activate', updater.refresh, updater, true);

jtabs.activate('jtabs-1');
}
}

Ext.EventManager.onDocumentReady(TabsCompany.init, TabsCompany, true);
Ext.util.CSS.swapStyleSheet('theme', "extjs/resources/css/xtheme-gray.css");


The PHP pages have their own js file for setup of the grid (and anything else I want)

site-data-servers.php for getting the tab content


<?php

/**
* @desc Display the Dataservers for the selected Site
*/

// Id sent in URL
$site_array = explode(',', $_REQUEST['site_array']);
$site_id = $site_array[1];

require_once($_SERVER['DOCUMENT_ROOT'] . '/classes/Config.php');
require_once(CLASS_PATH . 'Dataserver.class.php');

$coreDataServer = new Dataserver();
$data_server_ids = $coreDataServer->GetAllIDs('site_id=' . $site_id);

foreach($data_server_ids as $ds_id) {
$currentDataServer = new Dataserver($ds_id);
$data_server_array[] = $currentDataServer;
}

?>
<!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">

<!-- Core Scripts and Styles -->
<link rel="stylesheet" type="text/css" href="../../extjs/resources/css/ext-all.css">
<script type="text/javascript" src="../../extjs/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../../extjs/ext-all-debug.js"></script>
<!-- Core Scripts and Styles -->

<!-- Application Centric Scripts and Styles -->
<script type="text/javascript" src="site-data-servers.js"></script>
<!-- Application Centric Scripts and Styles -->

</head>

<body>
<!-- you must define the select box here, as the custom editor for the 'Light' column will require it -->

<select name="light" id="light" style="display: none;">
<option value="Shade">Shade</option>
<option value="Mostly Shady">Mostly Shady</option>
<option value="Sun or Shade">Sun or Shade</option>
<option value="Mostly Sunny">Mostly Sunny</option>
<option value="Sunny">Sunny</option>
</select>

<div id="grid-panel" style="width:600px;height:300px;">
<div id="editor-grid"></div>
</div>

<pre>
<?php print_r($data_server_array) ?>
</pre>
</body>

</html>


site-data-servers.js for putting the grid on the site-data-servers.php


Ext.onReady(function(){
Ext.QuickTips.init();
function formatBoolean(value){
return value ? 'Yes' : 'No';
};

function formatDate(value){
return value ? value.dateFormat('M d, Y') : '';
};
// shorthand alias
var fm = Ext.form, Ed = Ext.grid.GridEditor;

// the column model has information about grid columns
// dataIndex maps the column to the specific data field in
// the data store (created below)
var cm = new Ext.grid.ColumnModel([{
header: "Common Name",
dataIndex: 'common',
width: 220,
editor: new Ed(new fm.TextField({
allowBlank: false
}))
},{
header: "Light",
dataIndex: 'light',
width: 130,
editor: new Ed(new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',
transform:'light',
lazyRender:true
}))
},{
header: "Price",
dataIndex: 'price',
width: 70,
align: 'right',
renderer: 'usMoney',
editor: new Ed(new fm.NumberField({
allowBlank: false,
allowNegative: false,
maxValue: 10
}))
},{
header: "Available",
dataIndex: 'availDate',
width: 95,
renderer: formatDate,
editor: new Ed(new fm.DateField({
format: 'm/d/y',
minValue: '01/01/06',
disabledDays: [0, 6],
disabledDaysText: 'Plants are not available on the weekends'
}))
},{
header: "Indoor?",
dataIndex: 'indoor',
width: 55,
renderer: formatBoolean,
editor: new Ed(new fm.Checkbox())
}]);

// by default columns are sortable
cm.defaultSortable = true;

// this could be inline, but we want to define the Plant record
// type so we can add records dynamically
var Plant = Ext.data.Record.create([
// the "name" below matches the tag name to read, except "availDate"
// which is mapped to the tag "availability"
{name: 'common', type: 'string'},
{name: 'botanical', type: 'string'},
{name: 'light'},
{name: 'price', type: 'float'}, // automatic date conversions
{name: 'availDate', mapping: 'availability', type: 'date', dateFormat: 'm/d/Y'},
{name: 'indoor', type: 'bool'}
]);

// create the Data Store
var ds = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({url: 'plants.xml'}),

// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have a "plant" tag
record: 'plant'
}, Plant)
});

// create the editor grid
var grid = new Ext.grid.EditorGrid('editor-grid', {
ds: ds,
cm: cm,
enableColLock:false
});

var layout = Ext.BorderLayout.create({
center: {
margins:{left:3,top:3,right:3,bottom:3},
panels: [new Ext.GridPanel(grid)]
}
}, 'grid-panel');


// render it
grid.render();


var gridHead = grid.getView().getHeaderPanel(true);
var tb = new Ext.Toolbar(gridHead, [{
text: 'Add Plant',
handler : function(){
var p = new Plant({
common: 'New Plant 1',
light: 'Mostly Shade',
price: 0,
availDate: new Date(),
indoor: false
});
grid.stopEditing();
ds.insert(0, p);
grid.startEditing(0, 0);
}
}]);

// trigger the data store load
ds.load();
});


Have I gone about this wrong? I'm sure I'm close to the reason in that the page has already been rendered by the tabs, so the on document ready event for the grid is never run. But I can't work out how to fire the grid setup when that particular page loads inside the tab.

Any ideas?

Aaryn015
20 Sep 2007, 6:58 PM
Another day gone and still can't find a solution to this one. Does anyone see what I'm doing wrong?

Aaryn015
23 Sep 2007, 6:05 PM
4 days and this can't work no matter what I do. And it seems noone knows how to reference a function kept on a tab default url to get a grid rendered? So the entire model of what I am trying to do mustn't be yet possible in Ext.

HTML it is. Grid would have been nice - but hardly worth the time.

evant
23 Sep 2007, 6:13 PM
When you load the DOM fragment into the tab, you don't use onReady, the document has already been loaded for a long time.

Aaryn015
23 Sep 2007, 7:09 PM
I understand that. But it doesn't seem possible to call any function (or even if I just write it procedual that runs when the page I am using for content loads.

The closest I have got is getting it to run the function, but getting an "e has no properties" error somewhere where the column model is setup.

evant
23 Sep 2007, 8:03 PM
I do pretty much the same thing in an application I'm building, the only difference being I include my js inline, not through a script include. See if that makes any difference.

devnull
24 Sep 2007, 9:04 AM
too many people try to treat ajax applications the same as real desktop apps; you simply cannot do that. underneath all this fancy user interface fluff is still a webpage and it must be treated as such.
dont blame the framework just because you dont have a complete understanding of how html works.
I created a simple framework for my tabbed interface app that loads all the javascript needed; one file per tab (the php backend decides which "modules" wil be available based on user permissions), which are objects and register themselves with the main app, including a callback reference for when the tab is ready. Its a roundabout way to do it, but thats how this stuff has to work.
Javascript was never meant to be able to dynamically load scripts inline, and as such it doesnt always work right. Your app will work alot better if you figure out a way to avoid doing that (as i have).

ebarchiesi
26 Mar 2008, 9:12 PM
WEll iam starting with extjs, i can