PDA

View Full Version : Grid Editor



abnfire
21 Feb 2008, 4:25 PM
Hi

i been searching on how to add grid editor on web desktop. dose anyone know how to do it? im little clueless :">


Best Regards
Basit

catacaustic
21 Feb 2008, 4:55 PM
On the desktop example there's a window that holds a grid. All you need to do is change 'new Ext.grid.GridPanel' to 'new Ext.grid.EditorGridPanel' on the grid there, and it will be an editor grid. From there you just need to define the properties the same way that you would with any other editor grid.

abnfire
21 Feb 2008, 5:01 PM
thanks for the quick reply, but there is editor with php..
http://extjs.com/forum/showthread.php?t=18435

and i asked the person who made it, he said to post here.. but then i start to search and do it my own, but still no idea what to do :">

catacaustic
21 Feb 2008, 6:44 PM
What is it that you actually want here? How to add an editable grid to a window, or how to handle the grid in the backend?

abnfire
21 Feb 2008, 8:11 PM
yes the first one.

how to add grid to window for web desktop.. :) i can take care of backend and other changes.. :) really appreciate your help. thanks

catacaustic
21 Feb 2008, 8:20 PM
If that's all it is, my first response is still all that you need. It's just an EditorGridPanel object added to the layout of the Window. Nothing more. :)

abnfire
21 Feb 2008, 8:59 PM
grid = new Ext.grid.EditorGridPanel({ //to instantiate editor grid


editor is already being called up.. i got the above code from it. but how can i make the editor to be window and not embeded to the page itself.


where to use or put this ? i try replacing ext.grid.EditorGridPanel to Ext.Window.. gave me error lol

win = new Ext.Window({

catacaustic
21 Feb 2008, 9:49 PM
this.grid = new Ext.grid.EditorGrid ({
... // Add in the grid config
});

var win = new Ext.Window ({
height: 400,
width: 500,
title: "Editor grid",
layout: "fit",
items: this.grid
});OR
var win = new Ext.Window ({
height: 400,
width: 500,
title: "Editor grid",
layout: "fit",
items: [
{
xtype: "editorgrid",
store: ...
... // Add in the rest of the grid config
}
]
});


The grid itself is NOT a replacement for the window. Instead, it is an inner component of the window. This would have been set out in exactly the same way in the desktop example

This is the basis of all of the panel layouts in Ext. You do really need to get a grip on these before you try to go into anything to much more heavy or you'll keep on getting more and more lost. :)

abnfire
22 Feb 2008, 7:50 AM
i been trying what you said, nothing works.. he has another function and it builds, stores, render and show in the end, which is following
getMyGrid: function() {


Ext.QuickTips.init();//Enable Quicktips

setupDataSource(); //Setup the Data Source
//getColumnModel();//Create the Column Model
//this is invoked when the grid object is created
buildGrid(); //Build the Grid
renderGrid(); //Render the Grid
loadStore(); //Load the Store

},

//Method to check what is in our Data Store
//You might call this method fromt he firebug console for example
getDataSource: function() {
return ds;
}


i just need to know one time and rest i will create and expand it.. jst help me out on this please..

following is all of his js grid editor code




Ext.BLANK_IMAGE_URL = './../../images/s.gif';


Ext.namespace('myNameSpace'); //define namespace with some 'name'

myNameSpace.myModule = function(){

// Private variables specific to this module
var colModel; //definition of the columns
var ds; //primary data store
var dsIndustry; //secondary data store (dropdowns)
var filters; //definition of filter plugin
var grid; //the grid component (object)
var myReader; //reader
var myRecordObj; //data record object
var pagingPlugin;//definition of paging plugin
var primaryKey='companyID'; //primary key is used several times throughout
var renderPctChange;
var win; //pop up window


var setupDataSource = function(){

myRecordObj = Ext.data.Record.create([

{name: primaryKey},//this corresponds to 'companyID', I assigned a
{name: 'company', mapping: 'company', sortDir: 'ASC', sortType: 'asUCString'},
{name: 'price', type: 'float'},
{name: 'tax', type: 'float'},
{name: 'change', type: 'float'}, //will use mapping='change'
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'Y-m-d H:i:s'},
{name: 'industryID'},
{name: 'risk'},
{name: 'stars'},
{name: 'check'} //again, the order shown here does NOT matter
]);



myReader = new Ext.data.JsonReader( //creates array from JSON response
{

root: 'results', //delimiter tag for each record (row of data)
totalProperty: 'total',//element containing total dataset size (opt
id: primaryKey //used several times so a Private Variable is used
},
myRecordObj//pass a reference to the object
);


// Data Store #1
ds = new Ext.data.GroupingStore({ //if grouping
//ds = new Ext.data.Store({ //if not grouping
proxy: new Ext.data.HttpProxy({
url: 'grid-editor.php', //url to data object (server side script)
method: 'POST'
}),
baseParams:{task: "readStock"},//This parameter is passed for any
reader: myReader,
//groupField:'industry', //added for GroupingStore, specifies initial group sort
sortInfo:{field: 'company', direction: "ASC"}
//remoteSort: true,//true if sort from server (false = sort from cache only)
});//end ds

dsIndustry = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
//where to retrieve data
url: 'grid-editor.php', //url to data object (server side script)
method: 'POST'
}),
baseParams:{task: "readIndustry"},//this parameter is passed for any HTTP request
/*2. specify the reader*/
reader: new Ext.data.JsonReader(
{
root: 'results',//name of the property that is container for an Array of row objects
id: 'industryID'//the property within each row object that provides an ID for the record (optional)
},
[
{name: 'industryID'},//name of the field in the stock table (not the industry table)
{name: 'industryName'}
]
),
sortInfo:{field: 'industryName', direction: "ASC"}
}
);//end dsIndustry

};//end setupDataSource

var getColumnModel = function(){
if(!colModel) { //only need to create columnModel if it doesn't already exist

/**
* Date renderer function
* Renders a date
* @param {Object} val
*/
function renderDate(value){
//Ext.util.Format.dateRenderer('m/d/Y')
return value ? value.dateFormat('M d, Y') : '';
};

/**
* Italic Custom renderer function
* takes val and renders it in italics
* @param {Object} val
*/
function italic(val){
return '<i>' + val + '</i>';
};

/**
* Percent Custom renderer function
* takes val and renders it red or green with %
* @param {Object} val
*/
// function renderPctChange(val){
this.renderPctChange = function(val){
if(val >= 0){
//-> this = obj (row from grid, properties of id, name='pctChange', style)
return '<span style="color:green;">' + val + '%</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '%</span>';
}
return val;
};

/**
* Red/Green Custom renderer function
* takes val and renders it red if <0 otherwise renders it green
* @param {Object} val
*/
function renderPosNeg(val){
if(val >= 0){
//-> this = obj (row from grid, properties of id, name='change', style)
return '<span style="color:green;">' + val + '</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '</span>';
}
return val;
};


/**
* Risk Custom renderer function
* Renders according to risk level
* @param {Object} val
*/
function renderRisk(data, cell, record, rowIndex, columnIndex, store){
switch(data) {
case "high":
cell.css = "redcell";
return "high";//display 'high' in the cell (could be
//we could display anything here
//"High","Hi","yup"...anything
case "medium":
return "medium";
case "low":
return "low";
}
};

/**
* Star Custom renderer function
* Renders a picture according to value
* @param {Object} val
*/
function renderStars(data, cell, record, rowIndex, columnIndex, store){
switch(data) {
case "1": cell.css = "stars1"; return 1;//returns text over the background image
case "2": cell.css = "stars2"; return;//just shows the background image
case "3": cell.css = "stars3"; return;
case "4": cell.css = "stars4"; return;
case "5": cell.css = "stars5"; return;
}
};


this.checkColumn = new Ext.grid.CheckColumn({
header: "Check",
dataIndex: 'check',
width: 9,
sortable: true
});

dsIndustry.load(); //industry column dropdown options

colModel = new Ext.grid.ColumnModel([ //instantiate ColumnModel
{
/*optionally specify the aligment (default = left)*/
align: 'right',

/*[Required] Specify the dataIndex which is the DataStore
* field "name" this column draws its data from */
dataIndex: 'companyID',

header:'ID',//header = text that appears at top of column
//hidden: true, //true to initially hide the column

id: 'classCompanyID',
//locked: false,//no longer supported, see user extensions
sortable: true,//false (default) disables sorting by this column
width: 9 //column width
},{
dataIndex: 'company',
header:"Company",
id: 'classCompany',
locked: false,
sortable: true,
//resizable: false,//disable column resizing (can also use fixed = true)
width: 40,

//TextField editor - for an editable field add an editor
editor: new Ext.form.TextField({
//specify options
allowBlank: false //default is true (nothing entered)
})
},{
align: 'right',//default is to align to the left
dataIndex: 'price',
header: "Price",
sortable: true,
width: 12,

/* optional rendering function to provide customized data
* formatting */
renderer: Ext.util.Format.usMoney,
editor: new Ext.form.NumberField({
//specify options
allowBlank: false, //default is true (nothing entered)
allowNegative: false, //could also use minValue
maxValue: 100
})
},{
align: 'right',
dataIndex: 'tax',
header: "Tax",
renderer: Ext.util.Format.usMoney,
sortable: true,
width: 12
},{
align: 'center',
dataIndex: 'change',
header: "Change",
//custom renderer specified by reference:
renderer: renderPosNeg,
sortable: true,
width: 12
},{
dataIndex: 'pctChange',
header: "% Change",
renderer: this.renderPctChange,
sortable: true,
width: 15
},{
dataIndex: 'lastChange',
header: "Last Updated",
renderer: renderDate,
sortable: true,
width: 20,
editor: new Ext.form.DateField({ //DateField editor
//specify options

//allow to leave blank? default is true (allow blanks)
allowBlank: false,

//prevents typing a new date violating criteria
minValue: '10/15/07',
disabledDays: [0, 3, 6],
disabledDaysText: 'Closed on this day'
})
},{
dataIndex: 'industryID',
header: "Industry",
sortable: true,
width: 23,

//create a dropdown based on server side data (from db)
editor: new Ext.form.ComboBox({
//if we enable typeAhead it will be querying database
//so we may not want typeahead consuming resources
typeAhead: false,
triggerAction: 'all',

//By enabling lazyRender this prevents the combo box
//from rendering until requested
lazyRender: true,//should always be true for editor

//where to get the data for our combobox
store: dsIndustry,

//the underlying data field name to bind to this
//ComboBox (defaults to undefined if mode = 'remote'
//or 'text' if transforming a select)
displayField: 'industryName',

//the underlying value field name to bind to this
//ComboBox
valueField: 'industryID'
}),
renderer: //custom rendering specified inline
function(data) {
record = dsIndustry.getById(data);
if(record) {
return record.data.industryName;
} else {
//return data;
return 'missing data';
}
}
},{
dataIndex: 'risk',
header: "Risk",
renderer: renderRisk,
sortable: true,
width: 11,

//dropdown based on client side data (from html)
editor: new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',

//look for this id to transform the html option values
//to a dropdown
transform:'riskID',
lazyRender:true,

//css class to apply to the dropdown list element
listClass: 'x-combo-list-small'
})
},{
align: 'center',
dataIndex: 'stars',
header: "Stars",
renderer: renderStars,
sortable: true,
width: 8
},

//this column is passed in by reference (see above)
checkColumn

]);//end colModel

this.filters = new Ext.ux.grid.GridFilters({
//need to specify if want local filtering (filter the store),
//otherwise defaults to server side filtering
local:true,//specify true if you want to filter client side

filters:[
{dataIndex: primaryKey, type: 'numeric'},
{dataIndex: 'company', type: 'string'},
{dataIndex: 'price', type: 'numeric'},
{dataIndex: 'tax', type: 'numeric'},
{dataIndex: 'change', type: 'numeric'},
{dataIndex: 'pctChange', type: 'numeric'},
{dataIndex: 'lastChange', type: 'date'},
{dataIndex: 'industryID', type: 'string'},
{dataIndex: 'risk', type: 'list',
active:false,//whether filter value is activated
value:'low',//default filter value
options: ['low','medium','high'],

//if local = false or unspecified, phpMode has an effect
phpMode: false},
{dataIndex: 'stars', type: 'numeric'},
{dataIndex: 'check', type: 'boolean'}
]
});//end filters setup


/**
* Paging Plugin
* Author = devnull / modified by Andrie
*/
this.pagingPlugin = new Ext.ux.Andrie.pPageSize({
afterText: 'records at a time'
});

}//end if colModel

return colModel;//if colModel already exists return it

}//end getColumnModel


var buildGrid = function(){

/**
* Handler for Adding a Record
*/
function addRecord() {
var r = new myRecordObj({
//specify default values

//will use this to trigger special handling when updating
companyID: 0,

//you can't comment out this line if you want the editor
//to start there, as it will show the html tags
company: '',
price: 0.00,
tax: 0.00,
change: 0.00,
pctChange: 0.00,
lastChange: (new Date()).clearTime(),
industry: '',
risk: '',
stars: '0'
});
grid.stopEditing();//stops any acitve editing

//very similar to ds.add, with ds.insert we can specify
//the insertion point
ds.insert(0, r); //1st arg is index,
//2nd arg is Ext.data.Record[] records

//start editing the specified rowIndex, colIndex
//make sure you pick an editable location
//otherwise it won't initiate the editor
grid.startEditing(0, 1);
}; // end addRecord


function callDelete(item) {
Ext.MessageBox.alert('Request','You selected '+this.text);
};


function callTrade(item) {
Ext.MessageBox.alert('Request','You selected '+this.text);
};


function callPrintPreview(item) {
Ext.MessageBox.alert('Request','You selected '+this.text);
};


/**
* Function for Deleting record(s)
* @param {Object} btn
*/
function deleteRecord(btn) {
if(btn=='yes')
{
/* block of code if we just want to remove 1 row
var selectedRow = grid.getSelectionModel().getSelected();//returns record object for the most recently selected
//row that is in data store for grid
if(selectedRow){
ds.remove(selectedRow);
} //end of block to remove 1 row
*/

//returns record objects for selected rows (all info for row)
var selectedRows = grid.selModel.selections.items;

//returns array of selected rows ids only
var selectedKeys = grid.selModel.selections.keys;

//note we already did an if(selectedKeys) to get here

//encode array into json
var encoded_keys = Ext.encode(selectedKeys);
//submit to server
Ext.Ajax.request( //alternative to Ext.form.FormPanel? or Ext.BasicForm.submit
{ //specify options (note success/failure below that receives these same options)
waitMsg: 'Saving changes...',
//url where to send request (url to server side script)
url: 'grid-editor.php',

//params will be available via $_POST or $_REQUEST:
params: {
task: "delete", //pass task to do to the server script
companyID: encoded_keys,//the unique id(s)
key: primaryKey//pass to server same 'id' that the reader used
},

callback: function (options, success, response) {
if (success) { //success will be true if the request succeeded
Ext.MessageBox.alert('OK',response.responseText);//you won't see this alert if the next one pops up fast
var json = Ext.util.JSON.decode(response.responseText);

Ext.MessageBox.alert('OK',json.del_count + ' record(s) deleted.');

//You could update an element on your page with
//the result from the server
//(e.g.<div id='total'></div>)
//var total = Ext.get('total');
//total.update(json.sum);

} else{
Ext.MessageBox.alert('Sorry, please try again. [Q304]',response.responseText);
}
},

//the function to be called upon failure of the request (server script, 404, or 403 errors)
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
//ds.rejectChanges();//undo any changes
},
success:function(response,options){
//Ext.MessageBox.alert('Success','Yeah...');
//commit changes and remove the red triangle which
//indicates a 'dirty' field
ds.reload();
}
} //end Ajax request config
);// end Ajax request initialization
};//end if click 'yes' on button
}; // end deleteRecord


/**
* Function for updating Tax shown in grid
* @param {Object} oGrid_Event
*/
function getTax(oGrid_Event) {

//submit to server
Ext.Ajax.request( //alternative to Ext.form.FormPanel? or Ext.BasicForm
{
//waitMsg: 'Saving changes...',
//url where to send request (url to server side script)
url: 'grid-editor.php',
//method: 'POST',

//params will be available via $_POST or $_REQUEST:
params: {
task: "calcTax", //pass task to do to the server script
price: oGrid_Event.value//the updated value
},//end params
//the function to be called upon failure of the request
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
//ds.rejectChanges();//undo any changes
},//end failure block
success:function(response,options){
//Ext.MessageBox.alert('Success','Yeah...');
var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server

//extract the value provided by the server
var myTax = responseData.tax;
//oGrid_Event.record.data.tax = myTax;//assign the tax to the record
//oGrid_Event.record.tax= myTax;//assign the id to the record
oGrid_Event.record.set('tax',myTax);

//commit changes (removes the red triangle which
//indicates a 'dirty' field)
ds.commitChanges();
}//end success block
}//end request config
); //end request
}; //end getTax


/**
* Handler for Deleting record(s)
*/
function handleDelete() {

//returns array of selected rows ids only
var selectedKeys = grid.selModel.selections.keys;
if(selectedKeys.length > 0)
{
Ext.MessageBox.confirm('Message','Do you really want to delete selection?', deleteRecord);
}
else
{
Ext.MessageBox.alert('Message','Please select at least one item to delete');
}//end if/else block
}; // end handleDelete


/**
* Handler to control grid editing
* @param {Object} oGrid_Event
*/
function handleEdit(editEvent) {
//determine what column is being edited
var gridField = editEvent.field;

//start the process to update the db with cell contents
updateDB(editEvent);

//I don't want to wait for server update to update the Total Column
if (gridField == 'price'){
getTax(editEvent);//start the process to update the Tax Field
}
}

/**
* onCheckColumn handler
* @param {Object} element
* @param {Object} e
* @param {Object} record
*/
function onCheckColumn(element, e, record) {
//remember 'on' is just a shortcut for 'addListener'
//maybe this should listen to 'dblclick' instead?

//alert(record.get('check'));
var myField = this.dataIndex;//the field name
var check = record.data[this.dataIndex];//same as record.data.check (but more abstract)
var checkStatus = check ? 'checked' : 'unchecked';
var checkItem = record.data.company;
var checkID = record.data.companyID;
Ext.example.msg('Item Check', 'You {0} the "{1}" check box, ID = {2}.', checkStatus, checkItem, checkID);
var myMsg = 'You <b>'+ checkStatus + '</b> the "<i>' + checkItem + '</i>" check box, ID = ' + '<span style="color:blue;">' + checkID + '</span>.';
Ext.MessageBox.alert('Item Check', myMsg);
var checkBoolean = check ? 1 : 0;

//update the database
Ext.Ajax.request(
{ //ajax request configuration
waitMsg: 'Saving changes...',
url: 'grid-editor.php', //url to server side script
params: { //these will be available via $_POST or $_REQUEST:
task: "update", //pass task to do to the server script
key: primaryKey,//pass to server same 'id' that the reader used
keyID: checkID,//for existing records this is the unique id (we need this one to relate to the db)
//newRecord: isNewRecord,//pass the new Record status indicator to server for special handling
field: myField,//the column name
value: checkBoolean,//the updated value
originalValue: !checkBoolean//the original value (oGrid_Event.orginalValue does not work for some reason)
},//end params
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
},//end failure block
success:function(response,options){
//Ext.MessageBox.alert('Success','Yeah...');
if(checkID == 0){
var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
var newID = responseData.newID;//extract the ID provided by the server
record.set('newRecord','no');//reset the indicator since update succeeded
record.set('companyID',newID);//assign the id to the record
ds.commitChanges();//commit changes (removes the red triangle which indicates a 'dirty' field)
} else {
ds.commitChanges();//commit changes (removes the red triangle which indicates a 'dirty' field)
}
}//end success block
}//end ajax request config
); //end ajax request
}; // end onCheckColumn handler


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




/* CHECK 1044 line to enable this
// var tpl = new Ext.XTemplate(
var tpl = new Ext.XTemplate(
'<div class="quote-item">' +
'<h2>{company}</h2>' +
'<img src="../images/user.png" alt="Logo" style="float:right;margin:4px;" />' +
'<label>Price:</label>${price}<br />' +
'<label>Change:</label>{change}<br />' +
'<label>% Change:</label>{pctChange}<br />' +
'<label>last updated:</label>{lastChange}<br />' +
'</div>'
);

var p = new Ext.Panel({
title: 'Basic Template',
width: 300,
html: '<p><i>Apply the template to see results here</i></p>',
tbar: [
{
text: 'Apply Data',
handler: function(){
tpl.overwrite(p.body, data);
p.body.highlight('#c3daf9', {block:true});
}
},
{
text: 'Do Something Else',
handler: function(){
// code here
}
}
],
renderTo: 'property-win'
});


/**
* properties
* Method to display record data in a popup tabbed window
* @param {Object} item
-/
function properties(item) {
var sel = grid.getSelectionModel().getSelected();
var selIndex = ds.indexOf(sel);
var seldata=sel.data;

seldata.lastChange=Ext.util.Format.date(seldata.lastChange,'m/d/Y');

/* //Scope problem trying to access the predefined custom renderer functions
seldata.pctChange = this.renderPctChange(seldata.pctChange);
seldata.change=renderPosNeg(seldata.change);
-/
tpl.overwrite(p.body, seldata);

// create the window on the first click and reuse on subsequent clicks
if(!win){
win = new Ext.Window({
el:'property-win',
layout:'fit',
width:500,
height:300,
closeAction:'hide',
plain: true,
items: p,
buttons: [{
text:'Submit',
disabled:true
},{
text: 'Close',
handler: function(){
win.hide();
}
}]
});
}
win.show(this);
p.body.highlight('#c3daf9', {block:true});

}; // end properties



//callback function for the right click event
function onMessageContextMenu(grid, rowIndex, e) {
e.stopEvent();
var coords = e.getXY();

//OK, we have our record, now how do we pass
//it to the referenced handler?
var record = grid.getStore().getAt(rowIndex);

var messageContextMenu = new Ext.menu.Menu({
id: 'messageContextMenu',
items: [
{
text: 'Properties',
handler: properties,
scope: this
},
{
text: 'I like Ext',
//when checked has a boolean value,
//it is assumed to be a CheckItem
checked: true,
checkHandler: onItemCheck
}
]
});

//predefine a menu item
var menuItem = new Ext.menu.Item({text: '<i>New Item</i>'});

//shows how to add items dynamically
var item = messageContextMenu.add(
'-',
menuItem, //add item by reference
{
//handler: onMessageContextItemClick(this,['open']),
//handler: function(){
// this.viewer.openTab(this.ctxRecord);
//},
iconCls: 'add',
text: '<u>Insert above</u>',
tooltip: 'Insert a row above this line'
},
{text: '<b>Print</b>', menu: new Ext.menu.Menu({// <-- submenu by nested config object
items: [
{text: 'PDF', handler:function(){callPrintPreview("PDF");} },
{text: 'EXCEL',handler:function(){callPrintPreview("EXCEL ");} },
{text: 'HTML', handler:function(){callPrintPreview("HTML") ;} },
{text: 'WORD', handler:function(){callPrintPreview("WORD") ;} }
]
})},
{text: '<b>Save Preferences</b>',handler: function(){saveUserPref(Ext.encode(colModel.config));}}
);

messageContextMenu.showAt([coords[0], coords[1]]);
e.preventDefault();//to disable the standard browser context menu
}

*/
/**
* Function for Refreshing Grid
*/
function refreshGrid() {
ds.reload();//
}; // end refresh


function SaveToExcel(item) {
Ext.MessageBox.alert('Request','You selected '+this.text);
};


/**
* toggleDetails
* @param {Object} btn
* @param {Object} pressed
*/
function toggleDetails(btn, pressed){
/*
var view = grid.getView();
view.showPreview = pressed;
view.refresh();
*/
}


/**
* Function for updating database
* @param {Object} oGrid_Event
*/
function updateDB(oGrid_Event) {

/**
* Do we need to disable a new record from further editing while
* the first request is being made since the record may not have
* the new companyID in time to use to properly handle other
* updates of the same record?
*
*
* Dates come through as an object instead of a string or
* numerical value, so do a check to prep the new value for
* transfer to the server side script
*/
if (oGrid_Event.value instanceof Date)
{ //format the value for easy insertion into MySQL
var fieldValue = oGrid_Event.value.format('Y-m-d H:i:s');
} else
{
var fieldValue = oGrid_Event.value;
}

//submit to server
Ext.Ajax.request( //alternative to Ext.form.FormPanel? or Ext.BasicForm
{ //Specify options (note success/failure below that
//receives these same options)
waitMsg: 'Saving changes...',
//url where to send request (url to server side script)
url: 'grid-editor.php',

//If specify params default is 'POST' instead of 'GET'
//method: 'POST',

//params will be available server side via $_POST or $_REQUEST:
params: {
task: "update", //pass task to do to the server script
key: primaryKey,//pass to server same 'id' that the reader used

//For existing records this is the unique id (we need
//this one to relate to the db). We'll check this
//server side to see if it is a new record
keyID: oGrid_Event.record.data.companyID,

//For new records Ext creates a number here unrelated
//to the database
//-bogusID: oGrid_Event.record.id,

field: oGrid_Event.field,//the column name
value: fieldValue,//the updated value

//The original value (oGrid_Event.orginalValue does
//not work for some reason) this might(?) be a way
//to 'undo' changes other than by cookie? When the
//response comes back from the server can we make an
//undo array?
originalValue: oGrid_Event.record.modified

},//end params

//the function to be called upon failure of the request
//(404 error etc, ***NOT*** success=false)
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
//ds.rejectChanges();//undo any changes
},//end failure block

//The function to be called upon success of the request
success:function(response,options){
//Ext.MessageBox.alert('Success','Yeah...');


//if this is a new record need special handling
if(oGrid_Event.record.data.companyID == 0){
var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server

//Extract the ID provided by the server
var newID = responseData.newID;
//oGrid_Event.record.id = newID;

//Reset the indicator since update succeeded
oGrid_Event.record.set('newRecord','no');

//Assign the id to the record
oGrid_Event.record.set('companyID',newID);
//Note the set() calls do not trigger everything
//since you may need to update multiple fields for
//example. So you still need to call commitChanges()
//to start the event flow to fire things like
//refreshRow()

//commit changes (removes the red triangle which
//indicates a 'dirty' field)
ds.commitChanges();

//var whatIsTheID = oGrid_Event.record.modified;

//not a new record so just commit changes
} else {
//commit changes (removes the red triangle
//which indicates a 'dirty' field)
ds.commitChanges();
}
}//end success block
}//end request config
); //end request
}; //end updateDB


///////////////////////////////////////////////////////////////////////////


/**
* 3.2. Create (instantiate) the Grid
* This creates the actual GUI for the Grid.
* We specify here where, how, and when to render the Grid.
*/

//grid = new Ext.grid.GridPanel({ //to instantiate normal grid
grid = new Ext.grid.EditorGridPanel({ //to instantiate editor grid
autoExpandColumn: 'company', //which column to stretch in width to fill up the grid width and not leave blank space
//autoSizeColumns: true,//deprecated as of Ext2.0
clicksToEdit:2,//number of clicks to activate cell editor, default = 2
colModel: getColumnModel(), //gets the ColumnModel object to use (cm: is shorthand)
//footer: true,
//frame:true,//add a frame around the grid; defaults to no frame
//autoHeight:true,//autoHeight resizes the height to show all records
height:350,//you must specify height or autoHeight
iconCls: 'icon-grid',//we create our own css with a class called 'icon-grid'
id: 'myGridID',//unique id of this component (defaults to an auto-assigned id).
//el:'grid-company', //html element (id of the div) where the grid will be rendered
//'renderTo' does the same as 'el', except eliminated the need to explicitly call render()
//renderTo: 'grid-company',//could also render it directly to document.body
loadMask: true,//use true to mask the grid while loading (default = false)
plugins:[this.checkColumn, this.filters],//object or array of objects (filters = enable filtering of records)
//plugins: filters,//example with just one plugin
//Enable a Selection Model. The Selection Model defines the selection behavior,
//(single vs. multiple select, row or cell selection, etc.)
selModel: new Ext.grid.RowSelectionModel({singleSelect:false}),//true to limit row selection to 1 row})
store: ds, //the DataStore object to use (ds: is shorthand)
stripeRows: true,//applies css classname to alternate rows, defaults to false
title:'Products',

//trackMouseOver: true,//highligts rows on mousever (default = false for editor grid)
width:740,
/**
* The config options above create the following html
*
* <div id="grid-company">
* <div id="myGridID" class="x-panel x-grid-panel"
* style="width: 740px;">
* </div>
* </div>
*/
//Add a bottom bar
bbar: new Ext.PagingToolbar({
plugins: [this.pagingPlugin, this.filters],
pageSize: myNameSpace.myModule.perPage,//default is 20
store: ds,
displayInfo: true,//default is false (to not show displayMsg)
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No data to display",//display message when no records found
items:[
'-', {
pressed: true,
enableToggle:true,
text: 'Show Preview',
cls: 'x-btn-text-icon details',
toggleHandler: toggleDetails
}]
}),
//Add a top bar
tbar: [
{
text: 'Add Record',
tooltip: 'Click to Add a row',

//We create our own css with a class called 'add'
//.add is a custom class not included in
// ext-all.css by default, so we need to define the
// attributes of this style ourselves
iconCls:'add',
handler: addRecord //what happens when user clicks on it
}, '-', //add a separator
{
text: 'Delete Selected',
tooltip: 'Click to Delete selected row(s)',

//function to call when user clicks on button
handler: handleDelete,
iconCls:'remove'
}, '->', // next fields will be aligned to the right
{
text: 'Refresh',
tooltip: 'Click to Refresh the table',
handler: refreshGrid,
iconCls:'refresh'
}
],

//this is the key to showing the GroupingStore
view: new Ext.grid.GroupingView({
forceFit:true,
//custom grouping text template to display the number of
//items per group
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
})
});//end grid


///////////////////////////////////////////////////////////////////////////


/**
* 3.3 Add listeners to the Grid
*/

/**
* Add right click event
* rowcontextmenu fires when a row is right clicked
*/
// grid.addListener('rowcontextmenu', onMessageContextMenu);


/**
* Add an event/listener to handle any updates to grid
*/
grid.addListener('afteredit', handleEdit);//give event name, handler (can use 'on' shorthand for addListener)


//instead of adding listeners individually could have also loaded together like so:
/*
grid.addListener({ //same as saying grid.on
'rowcontextmenu': onMessageContextMenu,
'afteredit': handleEdit
//note other listeners are same just without the 'on' (mousever, mouseout, click, etc.)
});
*/


/**
* Add an event/listener to column check boxes
*/
this.checkColumn.on('click', onCheckColumn);


}//end function buildGrid




///////////////////////////////////////////////////////////////////////////




/**
* 5.0 Render the Grid
* Explicitly rendering the grid is only required if "renderTo" is not
* specified in the configuration of the grid object above.
* In Ext2.0, every component automatically supports "lazy" (on demand)
* rendering. The rendering pipeline is managed automatically if you use
* "renderTo" in the grid constructor.
* Instead of using "renderTo" you can explicitly render the grid when you
* want using render(). This gives you the flexibility / power to control
* the rendering process (lazy render). In addition to render() you can
* also use the beforerender() event (see Ext.Component).
* Rendering the grid does not necessarily mean building rows. If there
* is no data, the rest of the grid layout gets built (e.g. headers,
* footers, etc.)
*/
var renderGrid = function() {
grid.render('grid-company');//1st argument is the container,
//2nd argument is the position within
//the div (end of the container is default)

/**
* Grid rendering effects
* if we want to render rows depending on values in row
*/
grid.getView().getRowClass = function(record, index) {
switch (record.data.stars) {
case '0': //this is the default when adding records
//Right now I shade the row yellow when stars = '0' to signify
//the row has not been saved yet. You might want to choose
//another option, like maybe when 'companyID' is no longer
//zero. For now I just decided to 'watch' the last column
//thinking that would be the last to get updated and I wanted
//the row to stay yellow until the row was completely updated.
return "yellowrow"
break
case '5':
return "greenrow"
break
case '4':
return "pinkrow"
break
default:
//something else?
}
};//end row rendering


};//end function renderGrid




///////////////////////////////////////////////////////////////////////////




/**
* 6.0 Load the Store (loadStore)
* Method created to enable loading the stores on demand
*
* "Store loading is the process of gettingthe data and building it's
* records, it has nothing to do with rendering. Store fires the load
* event when it's done building Records (not grid rows). The grid
* listens to events from the store (e.g. 'load') to know when the data is
* done loading - this drives the porcess of the grid building the HTML
* rows." - Tim Ryan
*/
var loadStore = function() {
/**
* Allegedly the proper order is to load the store after the grid is
* rendered. You'll see examples done both ways.
* I have noticed situations where it seemed to work better if the store
* returned before the execution gets to the grid render() line,
* otherwise it will still render the grid but the store will be
* empty and thus display an empty grid. If you use the paging
* toolbar refresh that will probably show all the data because it
* just refreshes the page from the cached data store*/
ds.load({
params: { //this is only parameters for the FIRST page load,
//use baseParams above for ALL pages.
start: 0, //pass start/limit parameters for paging
limit: myNameSpace.myModule.perPage//
}
});
/**Once this line executes the request gets sent to the server.
* Note that this is an asychronous request, this file keeps going
* independent of the server. If you're stepping through firebug,
* it's at this point you'll see the XHR get sent out.
*/

/**
* The following line is to highlight the first row of the grid once it
* is loaded. I've noticed this line is quite finicky though.
* There's probably a better way to do this that is more reliable.
* Allegedly you can't reliably select rows until the store is loaded,
* however I find the next line still doesn't work reliably, even
* when the store is already loaded. I think the next line should maybe
* be called after something else gets finished.
*/
grid.getSelectionModel().selectFirstRow();

};//end loadStore





///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------//
//------------------------------Public Area------------------------------//
//-----------------------------------------------------------------------//
///////////////////////////////////////////////////////////////////////////

return {//returns an object=myNameSpace.myModule with the following
//properties:

///////////////////////////////////////////////////////////////////////////
//---------------------------Public Properties---------------------------//
///////////////////////////////////////////////////////////////////////////
// It is considered good practice to put the following in the public area
// of the module:
// text used by module,
// default dimensions, styles,
// customizable options, etc.

// Example of Public Property (just an example; not needed for the grid
myPublicProperty: "I'm accessible as myNameSpace.myModule.myPublicProperty.",
//To reference this property use:
// this.myPublicProperty (while inside the Public Area)
// myNameSpace.myModule.myPublicProperty (when outside of the
// module)

// Public Properties specific to this module
perPage: 10, //page limit

///////////////////////////////////////////////////////////////////////////
//-----------------------------Public Methods----------------------------//
///////////////////////////////////////////////////////////////////////////
// Public methods can be called from outside the module using
// myNameSpace.myModule.method_name_here
// Public methods can access Private Area

// Example of Public Method (just an example; not needed for the grid

//The following method is accessible as myNameSpace.myModule.myPublicMethod
myPublicMethod: function(){

//note the use of 'this' to refer to Public Property
var myOtherProperty = this.myPublicProperty

//note reference to Private variable does NOT use 'this'
return myPrivateVar;
},

// Public Methods specific to this module

//Initialization Method
init : function(){
//This method is called by the last line below that looks like this:
//Ext.onReady(myNameSpace.myModule.init, myNameSpace.myModule, true);
//So, once the document is fully loaded, that line gets executed
//and we end up here. As a result, this is a good place to put
//DOM dependent tasks since we know the elements are now loaded.


/**
* Set up plugin for a check column
* @param {Object} config
*/
Ext.grid.CheckColumn = function(config){
this.addEvents({
click: true
});
Ext.grid.CheckColumn.superclass.constructor.call(this);

Ext.apply(this, config, {
init : function(grid){
this.grid = grid;
this.grid.on('render', function(){
var view = this.grid.getView();
view.mainBody.on('mousedown', this.onMouseDown, this);
}, this);
},

onMouseDown : function(e, t){
if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){
e.stopEvent();
var index = this.grid.getView().findRowIndex(t);
var record = this.grid.store.getAt(index);
record.set(this.dataIndex, !record.data[this.dataIndex]);
this.fireEvent('click', this, e, record);
}
},

renderer : function(v, p, record){
//the +v type converts to a number (json returns a string
//which always evaluates true)
var checkState = (+v) ? '-on' : '';

p.css += ' x-grid3-check-col-td';

//return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'"> </div>';
return '<div class="x-grid3-check-col'+ checkState +' x-grid3-cc-'+this.id+'"> </div>';
}
});

if(!this.id){
this.id = Ext.id();
}
this.renderer = this.renderer.createDelegate(this);
};

// extend Ext.util.Observable
Ext.extend(Ext.grid.CheckColumn, Ext.util.Observable);

//done with plugin setup
/////////////////////////////////////////////////////////////////

Ext.ux.menu.RangeMenu.prototype.icons = {
gt: 'images/greater_than.png',
lt: 'images/less_than.png',
eq: 'images/equals.png'
};
Ext.ux.grid.filter.StringFilter.prototype.icon = 'images/find.png';

// get our Grid (remember, 'this' refers to properties and methods
// inside the public area
this.getMyGrid();

//Works without this, used for state awareness...
//Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

},//end of init method

/**
* getMyGrid
* This method goes through the steps to create our grid
* 1.0 Initialization
* define icons
* 2.0 Setup the Data Source (setupDataSource)
* define store
* specify filters
* 3.0 Create the Column Model (getColumnModel)
* select rows or do anything else you want with rows
* 4.0 Build the Grid (buildGrid)
* 5.0 Render the Grid (renderGrid)
* 6.0 Load the Store (loadStore)
*/
getMyGrid: function() {


Ext.QuickTips.init();//Enable Quicktips

setupDataSource(); //Setup the Data Source
//getColumnModel();//Create the Column Model
//this is invoked when the grid object is created
buildGrid(); //Build the Grid
renderGrid(); //Render the Grid
loadStore(); //Load the Store

},

//Method to check what is in our Data Store
//You might call this method fromt he firebug console for example
getDataSource: function() {
return ds;
}

}//end of return

//------------------------------Public Area------------------------------//
//-----------------------------------------------------------------------//
///////////////////////////////////////////////////////////////////////////

}();


Ext.onReady(myNameSpace.myModule.init, myNameSpace.myModule, true);


please help me out on this..

brov0010
22 Feb 2008, 11:32 AM
Can you provide the Html you are trying to render it to?
My only assumption would be that you call grid.render('grid-company') and you do not have a target node in the DOM with an ID of 'grid-company'.

abnfire
22 Feb 2008, 5:36 PM
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Grid Example (MySQL/php)</title>

<link rel="stylesheet" type="text/css" href="./../javascript/extjs/resources/css/ext-all.css" />

<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="./../javascript/extjs/adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->

<script type="text/javascript" src="./../javascript/extjs/ext-all-debug.js"></script>




<script type="text/javascript" src="RowExpander.js"></script>

<!-- Extensions - Paging Toolbar -->
<script type="text/javascript" src="javascript/panel/ux/paging/pPageSize.js"></script>

<!-- Extensions - Filtering -->
<script type="text/javascript" src="javascript/panel/ux/menu/EditableItem.js"></script>
<script type="text/javascript" src="javascript/panel/ux/menu/RangeMenu.js"></script>

<script type="text/javascript" src="javascript/panel/ux/grid/GridFilters.js"></script>
<script type="text/javascript" src="javascript/panel/ux/grid/filter/Filter.js"></script>
<script type="text/javascript" src="javascript/panel/ux/grid/filter/StringFilter.js"></script>
<script type="text/javascript" src="javascript/panel/ux/grid/filter/DateFilter.js"></script>
<script type="text/javascript" src="javascript/panel/ux/grid/filter/ListFilter.js"></script>
<script type="text/javascript" src="javascript/panel/ux/grid/filter/NumericFilter.js"></script>
<script type="text/javascript" src="javascript/panel/ux/grid/filter/BooleanFilter.js"></script>

<!-- Page Specific -->
<script type="text/javascript" src="javascript/panel/grid-editor.js"></script>


<link rel="stylesheet" type="text/css" href="images/grid-editor.css" />

<!-- Common Styles for the examples -->

<link rel="stylesheet" type="text/css" href="examples.css" />

<style type="text/css">
body .x-panel {
margin-bottom:20px;
}
.icon-grid {
background-image:url(images/grid.png) !important;
}
#button-grid .x-panel-body {
border:1px solid #99bbe8;
border-top:0 none;
}
.add {
background-image:url(images/add.gif) !important;
}
.option {
background-image:url(images/plugin.gif) !important;
}
.remove {
background-image:url(images/delete.gif) !important;
}
.refresh {
background-image:url(images/table_refresh.png) !important;
}
.save {
background-image:url(images/save.gif) !important;
}

.red { color: red;}
.redcell { background-color:#FFE5E5 !important;}

.greenrow { background-color:#C3FF8F !important;}
.yellowrow { background-color:#FFFF66 !important;}
.pinkrow { background-color:#FFE6CC !important;}
.x-grid3-col-classCompanyID { background-color:#F2F2F2 !important;}
/* .x-grid3-col-classCompany { background-color:#FEFFE5 !important;} this shades the column but covers the red triangles*/

.stars1 {
background-image:url(images/user_suit.png) !important;
background-repeat: no-repeat;
background-position: center;
}
.stars2 {
background-image:url(images/user_red.png) !important;
background-repeat: no-repeat;
background-position: center;
}
.stars3 {
background-image:url(images/user_orange.png) !important;
background-repeat: no-repeat;
background-position: center;
}
.stars4 {
background-image:url(images/user_green.png) !important;
background-repeat: no-repeat;
background-position: center;
}
.stars5 {
background-image:url(images/user_gray.png) !important;
background-repeat: no-repeat;
background-position: center;
}

/*for filter extension*/
/*visual feedback of a filtered column, filtered columns will show bold/italic*/
.x-grid3-hd-row td.ux-filtered-column {
font-style: italic;
font-weight: bold;
}

</style>
</head>
<body>
<script type="text/javascript" src="examples.js"></script><!-- EXAMPLES -->


<select name="riskName" id="riskID" style="display: none;">
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
</select>
<div id="grid-company"></div>

<!---->
</body>
</html>

mjlecomte
22 Feb 2008, 5:44 PM
I think you are trying to build a skyscraper with your first project. Why don't you try a simpler grid first? Perhaps use one of the grids from the online demos? Like someone said earlier, you're trying to use some advanced features without understanding anything. I don't think you're going to get too far just hacking up other peoples codes until it miraculously works.
Have you even tried to make a popup message or something extremely simple with the desktop you're working with? You should at least learn to walk before running a marathon.

abnfire
22 Feb 2008, 10:21 PM
actually i need this, because it pulls and dose almost everything with backend database. i can play around and manage to get my project done from inside the frame, but the only place im getting stuck is the window and i would realy appreciate if someone can help me integrate this part..

i know i just started with ext, i would love to learn everything about ext, but i really need to give this project to customer quickly and only place im getting stuck is the window. you are expert in this, cant you just quickly help on this please... im already delay on the project.

abnfire
23 Feb 2008, 1:13 AM
also i was wondering.. is this something too hard to put in?

cause i saw where the tutorial was, loads of people were asking him, but he never posted to show them..


maybe it cant be implement it? im kind of lost now.. :-/ :(

mjlecomte
23 Feb 2008, 8:43 AM
The desktop already shows a grid in it, so that should tell you it can be done.

Customer? Typically to get help on the forums people will show some initiative in creating some code and then posting that code and indicating what their problems are and seek assistance.

The only thing I can tell you, is what I already did, start with a simple grid and build on that.

abnfire
23 Feb 2008, 11:37 AM
im not here to argue with you... i just need simple help and ya im soo good in ext, but im expert in php.. im jst getting late on a project, i would have did loads of research or learn on this, but i dont have soo much time.. whats better to ask a professional for some help.

simple grid dont have anyhting.. its like building static web site. seriously, please if you can help then do so.. you not really helping anything if you gonna say the same thing again and im not really looking for your leacture that i need to learn it like you did.

please dont post further, if you dont want to or cannot help on this and i really dont want to argue.. i just need help with this and thats why i posted this thread.. :(

i already spend almost 5 days trying to find a way to have this on the desktop, well i think i might jst put it in iframe thing, which is not professional way, but i guess thats all i can do for right now...

anyway, i will still wait one more day, before implementing the other way, if someone can help me..

Please Help!!!

abnfire
23 Feb 2008, 7:08 PM
Ext.BLANK_IMAGE_URL = './../../images/s.gif';


//MyDesktop.IMDBGridWindow = Ext.extend(Ext.app.Module, //define namespace with some 'name'

MyDesktop.IMDBGridWindow = Ext.extend(Ext.app.Module, {
appType : 'imdbgrid',
id : 'imdbgrid-win',

init : function(){
this.launcher = {
text: 'IMDB Grid Window',
iconCls:'icon-grid',
handler : this.createWindow,
scope: this
}
},

createWindow : function(){
var desktop = this.app.getDesktop();
var win = desktop.getWindow('imdbgrid-win');

if(!win){

Ext.namespace('myNameSpace');
myNameSpace.myModule = function(){

// Private variables specific to this module
var colModel; //definition of the columns
var ds; //primary data store
var dsIndustry; //secondary data store (dropdowns)
var filters; //definition of filter plugin
var grid; //the grid component (object)
var myReader; //reader
var myRecordObj; //data record object
var pagingPlugin;//definition of paging plugin
var primaryKey='companyID'; //primary key is used several times throughout
var renderPctChange;
var win; //pop up window


var setupDataSource = function(){

myRecordObj = Ext.data.Record.create([

{name: primaryKey},//this corresponds to 'companyID', I assigned a
{name: 'company', mapping: 'company', sortDir: 'ASC', sortType: 'asUCString'},
{name: 'price', type: 'float'},
{name: 'tax', type: 'float'},
{name: 'change', type: 'float'}, //will use mapping='change'
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'Y-m-d H:i:s'},
{name: 'industryID'},
{name: 'risk'},
{name: 'stars'},
{name: 'check'} //again, the order shown here does NOT matter
]);



myReader = new Ext.data.JsonReader( //creates array from JSON response
{

root: 'results', //delimiter tag for each record (row of data)
totalProperty: 'total',//element containing total dataset size (opt
id: primaryKey //used several times so a Private Variable is used
},
myRecordObj//pass a reference to the object
);


// Data Store #1
ds = new Ext.data.GroupingStore({ //if grouping
//ds = new Ext.data.Store({ //if not grouping
proxy: new Ext.data.HttpProxy({
url: 'grid-editor.php', //url to data object (server side script)
method: 'POST'
}),
baseParams:{task: "readStock"},//This parameter is passed for any
reader: myReader,
//groupField:'industry', //added for GroupingStore, specifies initial group sort
sortInfo:{field: 'company', direction: "ASC"}
//remoteSort: true,//true if sort from server (false = sort from cache only)
});//end ds

dsIndustry = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
//where to retrieve data
url: 'grid-editor.php', //url to data object (server side script)
method: 'POST'
}),
baseParams:{task: "readIndustry"},//this parameter is passed for any HTTP request
/*2. specify the reader*/
reader: new Ext.data.JsonReader(
{
root: 'results',//name of the property that is container for an Array of row objects
id: 'industryID'//the property within each row object that provides an ID for the record (optional)
},
[
{name: 'industryID'},//name of the field in the stock table (not the industry table)
{name: 'industryName'}
]
),
sortInfo:{field: 'industryName', direction: "ASC"}
}
);//end dsIndustry

};//end setupDataSource

var getColumnModel = function(){
if(!colModel) { //only need to create columnModel if it doesn't already exist

/**
* Date renderer function
* Renders a date
* @param {Object} val
*/
function renderDate(value){
//Ext.util.Format.dateRenderer('m/d/Y')
return value ? value.dateFormat('M d, Y') : '';
};

/**
* Italic Custom renderer function
* takes val and renders it in italics
* @param {Object} val
*/
function italic(val){
return '<i>' + val + '</i>';
};

/**
* Percent Custom renderer function
* takes val and renders it red or green with %
* @param {Object} val
*/
// function renderPctChange(val){
this.renderPctChange = function(val){
if(val >= 0){
//-> this = obj (row from grid, properties of id, name='pctChange', style)
return '<span style="color:green;">' + val + '%</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '%</span>';
}
return val;
};

/**
* Red/Green Custom renderer function
* takes val and renders it red if <0 otherwise renders it green
* @param {Object} val
*/
function renderPosNeg(val){
if(val >= 0){
//-> this = obj (row from grid, properties of id, name='change', style)
return '<span style="color:green;">' + val + '</span>';
}else if(val < 0){
return '<span style="color:red;">' + val + '</span>';
}
return val;
};


/**
* Risk Custom renderer function
* Renders according to risk level
* @param {Object} val
*/
function renderRisk(data, cell, record, rowIndex, columnIndex, store){
switch(data) {
case "high":
cell.css = "redcell";
return "high";//display 'high' in the cell (could be
//we could display anything here
//"High","Hi","yup"...anything
case "medium":
return "medium";
case "low":
return "low";
}
};

/**
* Star Custom renderer function
* Renders a picture according to value
* @param {Object} val
*/
function renderStars(data, cell, record, rowIndex, columnIndex, store){
switch(data) {
case "1": cell.css = "stars1"; return 1;//returns text over the background image
case "2": cell.css = "stars2"; return;//just shows the background image
case "3": cell.css = "stars3"; return;
case "4": cell.css = "stars4"; return;
case "5": cell.css = "stars5"; return;
}
};


this.checkColumn = new Ext.grid.CheckColumn({
header: "Check",
dataIndex: 'check',
width: 9,
sortable: true
});

dsIndustry.load(); //industry column dropdown options

colModel = new Ext.grid.ColumnModel([ //instantiate ColumnModel
{
/*optionally specify the aligment (default = left)*/
align: 'right',

/*[Required] Specify the dataIndex which is the DataStore
* field "name" this column draws its data from */
dataIndex: 'companyID',

header:'ID',//header = text that appears at top of column
//hidden: true, //true to initially hide the column

id: 'classCompanyID',
//locked: false,//no longer supported, see user extensions
sortable: true,//false (default) disables sorting by this column
width: 9 //column width
},{
dataIndex: 'company',
header:"Company",
id: 'classCompany',
locked: false,
sortable: true,
//resizable: false,//disable column resizing (can also use fixed = true)
width: 40,

//TextField editor - for an editable field add an editor
editor: new Ext.form.TextField({
//specify options
allowBlank: false //default is true (nothing entered)
})
},{
align: 'right',//default is to align to the left
dataIndex: 'price',
header: "Price",
sortable: true,
width: 12,

/* optional rendering function to provide customized data
* formatting */
renderer: Ext.util.Format.usMoney,
editor: new Ext.form.NumberField({
//specify options
allowBlank: false, //default is true (nothing entered)
allowNegative: false, //could also use minValue
maxValue: 100
})
},{
align: 'right',
dataIndex: 'tax',
header: "Tax",
renderer: Ext.util.Format.usMoney,
sortable: true,
width: 12
},{
align: 'center',
dataIndex: 'change',
header: "Change",
//custom renderer specified by reference:
renderer: renderPosNeg,
sortable: true,
width: 12
},{
dataIndex: 'pctChange',
header: "% Change",
renderer: this.renderPctChange,
sortable: true,
width: 15
},{
dataIndex: 'lastChange',
header: "Last Updated",
renderer: renderDate,
sortable: true,
width: 20,
editor: new Ext.form.DateField({ //DateField editor
//specify options

//allow to leave blank? default is true (allow blanks)
allowBlank: false,

//prevents typing a new date violating criteria
minValue: '10/15/07',
disabledDays: [0, 3, 6],
disabledDaysText: 'Closed on this day'
})
},{
dataIndex: 'industryID',
header: "Industry",
sortable: true,
width: 23,

//create a dropdown based on server side data (from db)
editor: new Ext.form.ComboBox({
//if we enable typeAhead it will be querying database
//so we may not want typeahead consuming resources
typeAhead: false,
triggerAction: 'all',

//By enabling lazyRender this prevents the combo box
//from rendering until requested
lazyRender: true,//should always be true for editor

//where to get the data for our combobox
store: dsIndustry,

//the underlying data field name to bind to this
//ComboBox (defaults to undefined if mode = 'remote'
//or 'text' if transforming a select)
displayField: 'industryName',

//the underlying value field name to bind to this
//ComboBox
valueField: 'industryID'
}),
renderer: //custom rendering specified inline
function(data) {
record = dsIndustry.getById(data);
if(record) {
return record.data.industryName;
} else {
//return data;
return 'missing data';
}
}
},{
dataIndex: 'risk',
header: "Risk",
renderer: renderRisk,
sortable: true,
width: 11,

//dropdown based on client side data (from html)
editor: new Ext.form.ComboBox({
typeAhead: true,
triggerAction: 'all',

//look for this id to transform the html option values
//to a dropdown
transform:'riskID',
lazyRender:true,

//css class to apply to the dropdown list element
listClass: 'x-combo-list-small'
})
},{
align: 'center',
dataIndex: 'stars',
header: "Stars",
renderer: renderStars,
sortable: true,
width: 8
},

//this column is passed in by reference (see above)
checkColumn

]);//end colModel

this.filters = new Ext.ux.grid.GridFilters({
//need to specify if want local filtering (filter the store),
//otherwise defaults to server side filtering
local:true,//specify true if you want to filter client side

filters:[
{dataIndex: primaryKey, type: 'numeric'},
{dataIndex: 'company', type: 'string'},
{dataIndex: 'price', type: 'numeric'},
{dataIndex: 'tax', type: 'numeric'},
{dataIndex: 'change', type: 'numeric'},
{dataIndex: 'pctChange', type: 'numeric'},
{dataIndex: 'lastChange', type: 'date'},
{dataIndex: 'industryID', type: 'string'},
{dataIndex: 'risk', type: 'list',
active:false,//whether filter value is activated
value:'low',//default filter value
options: ['low','medium','high'],

//if local = false or unspecified, phpMode has an effect
phpMode: false},
{dataIndex: 'stars', type: 'numeric'},
{dataIndex: 'check', type: 'boolean'}
]
});//end filters setup


/**
* Paging Plugin
* Author = devnull / modified by Andrie
*/
this.pagingPlugin = new Ext.ux.Andrie.pPageSize({
afterText: 'records at a time'
});

}//end if colModel

return colModel;//if colModel already exists return it

}//end getColumnModel


var buildGrid = function(){

/**
* Handler for Adding a Record
*/
function addRecord() {
var r = new myRecordObj({
//specify default values

//will use this to trigger special handling when updating
companyID: 0,

//you can't comment out this line if you want the editor
//to start there, as it will show the html tags
company: '',
price: 0.00,
tax: 0.00,
change: 0.00,
pctChange: 0.00,
lastChange: (new Date()).clearTime(),
industry: '',
risk: '',
stars: '0'
});
grid.stopEditing();//stops any acitve editing

//very similar to ds.add, with ds.insert we can specify
//the insertion point
ds.insert(0, r); //1st arg is index,
//2nd arg is Ext.data.Record[] records

//start editing the specified rowIndex, colIndex
//make sure you pick an editable location
//otherwise it won't initiate the editor
grid.startEditing(0, 1);
}; // end addRecord


function callDelete(item) {
Ext.MessageBox.alert('Request','You selected '+this.text);
};


function callTrade(item) {
Ext.MessageBox.alert('Request','You selected '+this.text);
};


function callPrintPreview(item) {
Ext.MessageBox.alert('Request','You selected '+this.text);
};


/**
* Function for Deleting record(s)
* @param {Object} btn
*/
function deleteRecord(btn) {
if(btn=='yes')
{
/* block of code if we just want to remove 1 row
var selectedRow = grid.getSelectionModel().getSelected();//returns record object for the most recently selected
//row that is in data store for grid
if(selectedRow){
ds.remove(selectedRow);
} //end of block to remove 1 row
*/

//returns record objects for selected rows (all info for row)
var selectedRows = grid.selModel.selections.items;

//returns array of selected rows ids only
var selectedKeys = grid.selModel.selections.keys;

//note we already did an if(selectedKeys) to get here

//encode array into json
var encoded_keys = Ext.encode(selectedKeys);
//submit to server
Ext.Ajax.request( //alternative to Ext.form.FormPanel? or Ext.BasicForm.submit
{ //specify options (note success/failure below that receives these same options)
waitMsg: 'Saving changes...',
//url where to send request (url to server side script)
url: 'grid-editor.php',

//params will be available via $_POST or $_REQUEST:
params: {
task: "delete", //pass task to do to the server script
companyID: encoded_keys,//the unique id(s)
key: primaryKey//pass to server same 'id' that the reader used
},

callback: function (options, success, response) {
if (success) { //success will be true if the request succeeded
Ext.MessageBox.alert('OK',response.responseText);//you won't see this alert if the next one pops up fast
var json = Ext.util.JSON.decode(response.responseText);

Ext.MessageBox.alert('OK',json.del_count + ' record(s) deleted.');

//You could update an element on your page with
//the result from the server
//(e.g.<div id='total'></div>)
//var total = Ext.get('total');
//total.update(json.sum);

} else{
Ext.MessageBox.alert('Sorry, please try again. [Q304]',response.responseText);
}
},

//the function to be called upon failure of the request (server script, 404, or 403 errors)
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
//ds.rejectChanges();//undo any changes
},
success:function(response,options){
//Ext.MessageBox.alert('Success','Yeah...');
//commit changes and remove the red triangle which
//indicates a 'dirty' field
ds.reload();
}
} //end Ajax request config
);// end Ajax request initialization
};//end if click 'yes' on button
}; // end deleteRecord


/**
* Function for updating Tax shown in grid
* @param {Object} oGrid_Event
*/
function getTax(oGrid_Event) {

//submit to server
Ext.Ajax.request( //alternative to Ext.form.FormPanel? or Ext.BasicForm
{
//waitMsg: 'Saving changes...',
//url where to send request (url to server side script)
url: 'grid-editor.php',
//method: 'POST',

//params will be available via $_POST or $_REQUEST:
params: {
task: "calcTax", //pass task to do to the server script
price: oGrid_Event.value//the updated value
},//end params
//the function to be called upon failure of the request
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
//ds.rejectChanges();//undo any changes
},//end failure block
success:function(response,options){
//Ext.MessageBox.alert('Success','Yeah...');
var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server

//extract the value provided by the server
var myTax = responseData.tax;
//oGrid_Event.record.data.tax = myTax;//assign the tax to the record
//oGrid_Event.record.tax= myTax;//assign the id to the record
oGrid_Event.record.set('tax',myTax);

//commit changes (removes the red triangle which
//indicates a 'dirty' field)
ds.commitChanges();
}//end success block
}//end request config
); //end request
}; //end getTax


/**
* Handler for Deleting record(s)
*/
function handleDelete() {

//returns array of selected rows ids only
var selectedKeys = grid.selModel.selections.keys;
if(selectedKeys.length > 0)
{
Ext.MessageBox.confirm('Message','Do you really want to delete selection?', deleteRecord);
}
else
{
Ext.MessageBox.alert('Message','Please select at least one item to delete');
}//end if/else block
}; // end handleDelete


/**
* Handler to control grid editing
* @param {Object} oGrid_Event
*/
function handleEdit(editEvent) {
//determine what column is being edited
var gridField = editEvent.field;

//start the process to update the db with cell contents
updateDB(editEvent);

//I don't want to wait for server update to update the Total Column
if (gridField == 'price'){
getTax(editEvent);//start the process to update the Tax Field
}
}

/**
* onCheckColumn handler
* @param {Object} element
* @param {Object} e
* @param {Object} record
*/
function onCheckColumn(element, e, record) {
//remember 'on' is just a shortcut for 'addListener'
//maybe this should listen to 'dblclick' instead?

//alert(record.get('check'));
var myField = this.dataIndex;//the field name
var check = record.data[this.dataIndex];//same as record.data.check (but more abstract)
var checkStatus = check ? 'checked' : 'unchecked';
var checkItem = record.data.company;
var checkID = record.data.companyID;
Ext.example.msg('Item Check', 'You {0} the "{1}" check box, ID = {2}.', checkStatus, checkItem, checkID);
var myMsg = 'You <b>'+ checkStatus + '</b> the "<i>' + checkItem + '</i>" check box, ID = ' + '<span style="color:blue;">' + checkID + '</span>.';
Ext.MessageBox.alert('Item Check', myMsg);
var checkBoolean = check ? 1 : 0;

//update the database
Ext.Ajax.request(
{ //ajax request configuration
waitMsg: 'Saving changes...',
url: 'grid-editor.php', //url to server side script
params: { //these will be available via $_POST or $_REQUEST:
task: "update", //pass task to do to the server script
key: primaryKey,//pass to server same 'id' that the reader used
keyID: checkID,//for existing records this is the unique id (we need this one to relate to the db)
//newRecord: isNewRecord,//pass the new Record status indicator to server for special handling
field: myField,//the column name
value: checkBoolean,//the updated value
originalValue: !checkBoolean//the original value (oGrid_Event.orginalValue does not work for some reason)
},//end params
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
},//end failure block
success:function(response,options){
//Ext.MessageBox.alert('Success','Yeah...');
if(checkID == 0){
var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
var newID = responseData.newID;//extract the ID provided by the server
record.set('newRecord','no');//reset the indicator since update succeeded
record.set('companyID',newID);//assign the id to the record
ds.commitChanges();//commit changes (removes the red triangle which indicates a 'dirty' field)
} else {
ds.commitChanges();//commit changes (removes the red triangle which indicates a 'dirty' field)
}
}//end success block
}//end ajax request config
); //end ajax request
}; // end onCheckColumn handler


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




/* CHECK 1044 line to enable this
// var tpl = new Ext.XTemplate(
var tpl = new Ext.XTemplate(
'<div class="quote-item">' +
'<h2>{company}</h2>' +
'<img src="../images/user.png" alt="Logo" style="float:right;margin:4px;" />' +
'<label>Price:</label>${price}<br />' +
'<label>Change:</label>{change}<br />' +
'<label>% Change:</label>{pctChange}<br />' +
'<label>last updated:</label>{lastChange}<br />' +
'</div>'
);

var p = new Ext.Panel({
title: 'Basic Template',
width: 300,
html: '<p><i>Apply the template to see results here</i></p>',
tbar: [
{
text: 'Apply Data',
handler: function(){
tpl.overwrite(p.body, data);
p.body.highlight('#c3daf9', {block:true});
}
},
{
text: 'Do Something Else',
handler: function(){
// code here
}
}
],
renderTo: 'property-win'
});


/**
* properties
* Method to display record data in a popup tabbed window
* @param {Object} item
-/
function properties(item) {
var sel = grid.getSelectionModel().getSelected();
var selIndex = ds.indexOf(sel);
var seldata=sel.data;

seldata.lastChange=Ext.util.Format.date(seldata.lastChange,'m/d/Y');

/* //Scope problem trying to access the predefined custom renderer functions
seldata.pctChange = this.renderPctChange(seldata.pctChange);
seldata.change=renderPosNeg(seldata.change);
-/
tpl.overwrite(p.body, seldata);

// create the window on the first click and reuse on subsequent clicks
if(!win){
win = new Ext.Window({
el:'property-win',
layout:'fit',
width:500,
height:300,
closeAction:'hide',
plain: true,
items: p,
buttons: [{
text:'Submit',
disabled:true
},{
text: 'Close',
handler: function(){
win.hide();
}
}]
});
}
win.show(this);
p.body.highlight('#c3daf9', {block:true});

}; // end properties



//callback function for the right click event
function onMessageContextMenu(grid, rowIndex, e) {
e.stopEvent();
var coords = e.getXY();

//OK, we have our record, now how do we pass
//it to the referenced handler?
var record = grid.getStore().getAt(rowIndex);

var messageContextMenu = new Ext.menu.Menu({
id: 'messageContextMenu',
items: [
{
text: 'Properties',
handler: properties,
scope: this
},
{
text: 'I like Ext',
//when checked has a boolean value,
//it is assumed to be a CheckItem
checked: true,
checkHandler: onItemCheck
}
]
});

//predefine a menu item
var menuItem = new Ext.menu.Item({text: '<i>New Item</i>'});

//shows how to add items dynamically
var item = messageContextMenu.add(
'-',
menuItem, //add item by reference
{
//handler: onMessageContextItemClick(this,['open']),
//handler: function(){
// this.viewer.openTab(this.ctxRecord);
//},
iconCls: 'add',
text: '<u>Insert above</u>',
tooltip: 'Insert a row above this line'
},
{text: '<b>Print</b>', menu: new Ext.menu.Menu({// <-- submenu by nested config object
items: [
{text: 'PDF', handler:function(){callPrintPreview("PDF");} },
{text: 'EXCEL',handler:function(){callPrintPreview("EXCEL ");} },
{text: 'HTML', handler:function(){callPrintPreview("HTML") ;} },
{text: 'WORD', handler:function(){callPrintPreview("WORD") ;} }
]
})},
{text: '<b>Save Preferences</b>',handler: function(){saveUserPref(Ext.encode(colModel.config));}}
);

messageContextMenu.showAt([coords[0], coords[1]]);
e.preventDefault();//to disable the standard browser context menu
}

*/
/**
* Function for Refreshing Grid
*/
function refreshGrid() {
ds.reload();//
}; // end refresh


function SaveToExcel(item) {
Ext.MessageBox.alert('Request','You selected '+this.text);
};


/**
* toggleDetails
* @param {Object} btn
* @param {Object} pressed
*/
function toggleDetails(btn, pressed){
/*
var view = grid.getView();
view.showPreview = pressed;
view.refresh();
*/
}


/**
* Function for updating database
* @param {Object} oGrid_Event
*/
function updateDB(oGrid_Event) {

/**
* Do we need to disable a new record from further editing while
* the first request is being made since the record may not have
* the new companyID in time to use to properly handle other
* updates of the same record?
*
*
* Dates come through as an object instead of a string or
* numerical value, so do a check to prep the new value for
* transfer to the server side script
*/
if (oGrid_Event.value instanceof Date)
{ //format the value for easy insertion into MySQL
var fieldValue = oGrid_Event.value.format('Y-m-d H:i:s');
} else
{
var fieldValue = oGrid_Event.value;
}

//submit to server
Ext.Ajax.request( //alternative to Ext.form.FormPanel? or Ext.BasicForm
{ //Specify options (note success/failure below that
//receives these same options)
waitMsg: 'Saving changes...',
//url where to send request (url to server side script)
url: 'grid-editor.php',

//If specify params default is 'POST' instead of 'GET'
//method: 'POST',

//params will be available server side via $_POST or $_REQUEST:
params: {
task: "update", //pass task to do to the server script
key: primaryKey,//pass to server same 'id' that the reader used

//For existing records this is the unique id (we need
//this one to relate to the db). We'll check this
//server side to see if it is a new record
keyID: oGrid_Event.record.data.companyID,

//For new records Ext creates a number here unrelated
//to the database
//-bogusID: oGrid_Event.record.id,

field: oGrid_Event.field,//the column name
value: fieldValue,//the updated value

//The original value (oGrid_Event.orginalValue does
//not work for some reason) this might(?) be a way
//to 'undo' changes other than by cookie? When the
//response comes back from the server can we make an
//undo array?
originalValue: oGrid_Event.record.modified

},//end params

//the function to be called upon failure of the request
//(404 error etc, ***NOT*** success=false)
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
//ds.rejectChanges();//undo any changes
},//end failure block

//The function to be called upon success of the request
success:function(response,options){
//Ext.MessageBox.alert('Success','Yeah...');


//if this is a new record need special handling
if(oGrid_Event.record.data.companyID == 0){
var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server

//Extract the ID provided by the server
var newID = responseData.newID;
//oGrid_Event.record.id = newID;

//Reset the indicator since update succeeded
oGrid_Event.record.set('newRecord','no');

//Assign the id to the record
oGrid_Event.record.set('companyID',newID);
//Note the set() calls do not trigger everything
//since you may need to update multiple fields for
//example. So you still need to call commitChanges()
//to start the event flow to fire things like
//refreshRow()

//commit changes (removes the red triangle which
//indicates a 'dirty' field)
ds.commitChanges();

//var whatIsTheID = oGrid_Event.record.modified;

//not a new record so just commit changes
} else {
//commit changes (removes the red triangle
//which indicates a 'dirty' field)
ds.commitChanges();
}
}//end success block
}//end request config
); //end request
}; //end updateDB


///////////////////////////////////////////////////////////////////////////


/**
* 3.2. Create (instantiate) the Grid
* This creates the actual GUI for the Grid.
* We specify here where, how, and when to render the Grid.
*/

//grid = new Ext.grid.GridPanel({ //to instantiate normal grid
grid = new Ext.grid.EditorGridPanel({ //to instantiate editor grid
autoExpandColumn: 'company', //which column to stretch in width to fill up the grid width and not leave blank space
//autoSizeColumns: true,//deprecated as of Ext2.0
clicksToEdit:2,//number of clicks to activate cell editor, default = 2
colModel: getColumnModel(), //gets the ColumnModel object to use (cm: is shorthand)
//footer: true,
//frame:true,//add a frame around the grid; defaults to no frame
//autoHeight:true,//autoHeight resizes the height to show all records
height:350,//you must specify height or autoHeight
iconCls: 'icon-grid',//we create our own css with a class called 'icon-grid'
id: 'myGridID',//unique id of this component (defaults to an auto-assigned id).
//el:'grid-company', //html element (id of the div) where the grid will be rendered
//'renderTo' does the same as 'el', except eliminated the need to explicitly call render()
//renderTo: 'grid-company',//could also render it directly to document.body
loadMask: true,//use true to mask the grid while loading (default = false)
plugins:[this.checkColumn, this.filters],//object or array of objects (filters = enable filtering of records)
//plugins: filters,//example with just one plugin
//Enable a Selection Model. The Selection Model defines the selection behavior,
//(single vs. multiple select, row or cell selection, etc.)
selModel: new Ext.grid.RowSelectionModel({singleSelect:false}),//true to limit row selection to 1 row})
store: ds, //the DataStore object to use (ds: is shorthand)
stripeRows: true,//applies css classname to alternate rows, defaults to false
title:'Products',

//trackMouseOver: true,//highligts rows on mousever (default = false for editor grid)
width:740,
/**
* The config options above create the following html
*
* <div id="grid-company">
* <div id="myGridID" class="x-panel x-grid-panel"
* style="width: 740px;">
* </div>
* </div>
*/
//Add a bottom bar
bbar: new Ext.PagingToolbar({
plugins: [this.pagingPlugin, this.filters],
pageSize: myNameSpace.myModule.perPage,//default is 20
store: ds,
displayInfo: true,//default is false (to not show displayMsg)
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No data to display",//display message when no records found
items:[
'-', {
pressed: true,
enableToggle:true,
text: 'Show Preview',
cls: 'x-btn-text-icon details',
toggleHandler: toggleDetails
}]
}),
//Add a top bar
tbar: [
{
text: 'Add Record',
tooltip: 'Click to Add a row',

//We create our own css with a class called 'add'
//.add is a custom class not included in
// ext-all.css by default, so we need to define the
// attributes of this style ourselves
iconCls:'add',
handler: addRecord //what happens when user clicks on it
}, '-', //add a separator
{
text: 'Delete Selected',
tooltip: 'Click to Delete selected row(s)',

//function to call when user clicks on button
handler: handleDelete,
iconCls:'remove'
}, '->', // next fields will be aligned to the right
{
text: 'Refresh',
tooltip: 'Click to Refresh the table',
handler: refreshGrid,
iconCls:'refresh'
}
],

//this is the key to showing the GroupingStore
view: new Ext.grid.GroupingView({
forceFit:true,
//custom grouping text template to display the number of
//items per group
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
})
});//end grid


///////////////////////////////////////////////////////////////////////////


/**
* 3.3 Add listeners to the Grid
*/

/**
* Add right click event
* rowcontextmenu fires when a row is right clicked
*/
// grid.addListener('rowcontextmenu', onMessageContextMenu);


/**
* Add an event/listener to handle any updates to grid
*/
grid.addListener('afteredit', handleEdit);//give event name, handler (can use 'on' shorthand for addListener)


//instead of adding listeners individually could have also loaded together like so:
/*
grid.addListener({ //same as saying grid.on
'rowcontextmenu': onMessageContextMenu,
'afteredit': handleEdit
//note other listeners are same just without the 'on' (mousever, mouseout, click, etc.)
});
*/


/**
* Add an event/listener to column check boxes
*/
this.checkColumn.on('click', onCheckColumn);


}//end function buildGrid




///////////////////////////////////////////////////////////////////////////




/**
* 5.0 Render the Grid
* Explicitly rendering the grid is only required if "renderTo" is not
* specified in the configuration of the grid object above.
* In Ext2.0, every component automatically supports "lazy" (on demand)
* rendering. The rendering pipeline is managed automatically if you use
* "renderTo" in the grid constructor.
* Instead of using "renderTo" you can explicitly render the grid when you
* want using render(). This gives you the flexibility / power to control
* the rendering process (lazy render). In addition to render() you can
* also use the beforerender() event (see Ext.Component).
* Rendering the grid does not necessarily mean building rows. If there
* is no data, the rest of the grid layout gets built (e.g. headers,
* footers, etc.)
*/
var renderGrid = function() {
grid.render('imdbgrid-win');//1st argument is the container,
//2nd argument is the position within
//the div (end of the container is default)

/**
* Grid rendering effects
* if we want to render rows depending on values in row
*/
grid.getView().getRowClass = function(record, index) {
switch (record.data.stars) {
case '0': //this is the default when adding records
//Right now I shade the row yellow when stars = '0' to signify
//the row has not been saved yet. You might want to choose
//another option, like maybe when 'companyID' is no longer
//zero. For now I just decided to 'watch' the last column
//thinking that would be the last to get updated and I wanted
//the row to stay yellow until the row was completely updated.
return "yellowrow"
break
case '5':
return "greenrow"
break
case '4':
return "pinkrow"
break
default:
//something else?
}
};//end row rendering


};//end function renderGrid




///////////////////////////////////////////////////////////////////////////




/**
* 6.0 Load the Store (loadStore)
* Method created to enable loading the stores on demand
*
* "Store loading is the process of gettingthe data and building it's
* records, it has nothing to do with rendering. Store fires the load
* event when it's done building Records (not grid rows). The grid
* listens to events from the store (e.g. 'load') to know when the data is
* done loading - this drives the porcess of the grid building the HTML
* rows." - Tim Ryan
*/
var loadStore = function() {
/**
* Allegedly the proper order is to load the store after the grid is
* rendered. You'll see examples done both ways.
* I have noticed situations where it seemed to work better if the store
* returned before the execution gets to the grid render() line,
* otherwise it will still render the grid but the store will be
* empty and thus display an empty grid. If you use the paging
* toolbar refresh that will probably show all the data because it
* just refreshes the page from the cached data store*/
ds.load({
params: { //this is only parameters for the FIRST page load,
//use baseParams above for ALL pages.
start: 0, //pass start/limit parameters for paging
limit: myNameSpace.myModule.perPage//
}
});
/**Once this line executes the request gets sent to the server.
* Note that this is an asychronous request, this file keeps going
* independent of the server. If you're stepping through firebug,
* it's at this point you'll see the XHR get sent out.
*/

/**
* The following line is to highlight the first row of the grid once it
* is loaded. I've noticed this line is quite finicky though.
* There's probably a better way to do this that is more reliable.
* Allegedly you can't reliably select rows until the store is loaded,
* however I find the next line still doesn't work reliably, even
* when the store is already loaded. I think the next line should maybe
* be called after something else gets finished.
*/
grid.getSelectionModel().selectFirstRow();

};//end loadStore





///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------//
//------------------------------Public Area------------------------------//
//-----------------------------------------------------------------------//
///////////////////////////////////////////////////////////////////////////

return {//returns an object=myNameSpace.myModule with the following
//properties:

///////////////////////////////////////////////////////////////////////////
//---------------------------Public Properties---------------------------//
///////////////////////////////////////////////////////////////////////////
// It is considered good practice to put the following in the public area
// of the module:
// text used by module,
// default dimensions, styles,
// customizable options, etc.

// Example of Public Property (just an example; not needed for the grid
myPublicProperty: "I'm accessible as myNameSpace.myModule.myPublicProperty.",
//To reference this property use:
// this.myPublicProperty (while inside the Public Area)
// myNameSpace.myModule.myPublicProperty (when outside of the
// module)

// Public Properties specific to this module
perPage: 10, //page limit

///////////////////////////////////////////////////////////////////////////
//-----------------------------Public Methods----------------------------//
///////////////////////////////////////////////////////////////////////////
// Public methods can be called from outside the module using
// myNameSpace.myModule.method_name_here
// Public methods can access Private Area

// Example of Public Method (just an example; not needed for the grid

//The following method is accessible as myNameSpace.myModule.myPublicMethod
myPublicMethod: function(){

//note the use of 'this' to refer to Public Property
var myOtherProperty = this.myPublicProperty

//note reference to Private variable does NOT use 'this'
return myPrivateVar;
},

// Public Methods specific to this module

//Initialization Method
init : function(){
//This method is called by the last line below that looks like this:
//Ext.onReady(myNameSpace.myModule.init, myNameSpace.myModule, true);
//So, once the document is fully loaded, that line gets executed
//and we end up here. As a result, this is a good place to put
//DOM dependent tasks since we know the elements are now loaded.


/**
* Set up plugin for a check column
* @param {Object} config
*/
Ext.grid.CheckColumn = function(config){
this.addEvents({
click: true
});
Ext.grid.CheckColumn.superclass.constructor.call(this);

Ext.apply(this, config, {
init : function(grid){
this.grid = grid;
this.grid.on('render', function(){
var view = this.grid.getView();
view.mainBody.on('mousedown', this.onMouseDown, this);
}, this);
},

onMouseDown : function(e, t){
if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){
e.stopEvent();
var index = this.grid.getView().findRowIndex(t);
var record = this.grid.store.getAt(index);
record.set(this.dataIndex, !record.data[this.dataIndex]);
this.fireEvent('click', this, e, record);
}
},

renderer : function(v, p, record){
//the +v type converts to a number (json returns a string
//which always evaluates true)
var checkState = (+v) ? '-on' : '';

p.css += ' x-grid3-check-col-td';

//return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'"> </div>';
return '<div class="x-grid3-check-col'+ checkState +' x-grid3-cc-'+this.id+'"> </div>';
}
});

if(!this.id){
this.id = Ext.id();
}
this.renderer = this.renderer.createDelegate(this);
};

// extend Ext.util.Observable
Ext.extend(Ext.grid.CheckColumn, Ext.util.Observable);

//done with plugin setup
/////////////////////////////////////////////////////////////////

Ext.ux.menu.RangeMenu.prototype.icons = {
gt: 'images/greater_than.png',
lt: 'images/less_than.png',
eq: 'images/equals.png'
};
Ext.ux.grid.filter.StringFilter.prototype.icon = 'images/find.png';

// get our Grid (remember, 'this' refers to properties and methods
// inside the public area
this.getMyGrid();

//Works without this, used for state awareness...
//Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

},//end of init method

/**
* getMyGrid
* This method goes through the steps to create our grid
* 1.0 Initialization
* define icons
* 2.0 Setup the Data Source (setupDataSource)
* define store
* specify filters
* 3.0 Create the Column Model (getColumnModel)
* select rows or do anything else you want with rows
* 4.0 Build the Grid (buildGrid)
* 5.0 Render the Grid (renderGrid)
* 6.0 Load the Store (loadStore)
*/
getMyGrid: function() {


Ext.QuickTips.init();//Enable Quicktips

setupDataSource(); //Setup the Data Source
//getColumnModel();//Create the Column Model
//this is invoked when the grid object is created
buildGrid(); //Build the Grid
renderGrid(); //Render the Grid
loadStore(); //Load the Store

},

//Method to check what is in our Data Store
//You might call this method fromt he firebug console for example
getDataSource: function() {
return ds;
}

}//end of return

//------------------------------Public Area------------------------------//
//-----------------------------------------------------------------------//
///////////////////////////////////////////////////////////////////////////

}

win = desktop.createWindow({
id: 'imdbgrid-win',
title:'IMDB Grid Window',
width:740,
height:480,
iconCls: 'icon-grid',
shim:false,
animCollapse:false,
constrainHeader:true,
layout: 'fit',
items: myNameSpace.myModule.grid
});
}
myNameSpace.myModule.init;
win.show();
}
});

ok i manage to get the window working, but its showing empty.. maybe some expert can help on this atleast.. please

evant
23 Feb 2008, 7:31 PM
Nobody is going to debug your scripts for you. As the poster above has indicated, if you have a specific problem people will help you out. Posting a massive wad of code and saying "it's showing empty help!" is really vague and isn't likely to induce people to help.

abnfire
24 Feb 2008, 8:04 PM
im even willing to pay, to get this done. i been tryign too much and i jst need it working in window and it will solve all my problems.

catacaustic
24 Feb 2008, 10:08 PM
As a bit of an idea on how you can get started off and figure this out yourself, why don't you start with a basic editor grid (I mean no dynamic column models, a simple data store, etc... NO ADDED EXTRAS) and work your way up from there, adding in new parts as you can confirm that you have the basics already displaying and working the way you want them.

What you've got there is a huge mess of code and it's no wonder you're having problems when you don't know what much of it does. As has been said in here before, start off a little bit smaller and work your way up to it. That is the only way that you'll ever get anywhere with this.