PDA

View Full Version : ExtJS and Castle MonoRail (ASP.NET) + ActiveRecord (NHibernate)



LiXin
5 Oct 2008, 3:53 PM
I'd share a example of a grid and a pop-up form to add/edit/delete data. The code provided works with ExtJs 2.0+ and server side MonoRail MVC (ASP.NET) + Castle ActiveRecords (NHibernate).

The codes are generated from SQL Server 2005 Northwind database using LatticeFramework Studio tranformed by xslt style sheets, so you can modify the xslt style sheets to generate the code you want. The .zip is attached.

Constructive criticism is appreciated......

You need install SP1 and CastleProject-1.0-RC3.msi for VS 2005 and add the following references:

1. Castle.ActiveRecord for .NET 2.0
2. Castle.MonoRail.JSONSupport
3. NHibernate
4. Newtonsoft.Json

Here is the screencast for setting up ExtJs + MonoRail for VS 2005:
http://www.latticesoft.com/product/video.aspx

Features:

1. Server side paging and sorting using Castle ActiveRecords (built on top of NHibernate)
2. Pop-up forms for add and update records
3. Text, number, datetime, checkBox, and dropdown combobox fields of pop-up form

LiXin
5 Oct 2008, 3:57 PM
View: Index.vm

<script type="text/javascript">

Ext.BLANK_IMAGE_URL = '../../resources/images/default/s.gif';
Ext.namespace('myNameSpace');

myNameSpace.myModule = function(){

var ds;
var grid;
var colModel;
var myRecordObj;
var myReader;
var primaryKey='OrderID';

var setupDataSource = function(){
myRecordObj = Ext.data.Record.create([

{name: 'OrderID', type: 'int'},
{name: 'CustomerID', type: 'string'},
{name: 'EmployeeID', type: 'int'},
{name: 'OrderDate', type: 'date', dateFormat: 'm/d/Y'},
{name: 'RequiredDate', type: 'date', dateFormat: 'm/d/Y'},
{name: 'ShippedDate', type: 'date', dateFormat: 'm/d/Y'},
{name: 'ShipVia', type: 'int'},
{name: 'Freight', type: 'float'},
{name: 'ShipName', type: 'string'},
{name: 'ShipAddress', type: 'string'},
{name: 'ShipCity', type: 'string'},
{name: 'ShipRegion', type: 'string'},
{name: 'ShipPostalCode', type: 'string'},
{name: 'ShipCountry', type: 'string'}
]);

myReader = new Ext.data.JsonReader(
{
root: 'results',
totalProperty: 'total',
id: primaryKey
},
myRecordObj
);

ds = new Ext.data.GroupingStore({
proxy: new Ext.data.HttpProxy({
url: '/Orders/List.castle',
method: 'POST'
}),
baseParams:{task: "readOrders"},
reader: myReader
});

};//end setupDataSource

var getColumnModel = function() {

if(!colModel) {
function italic(val){
return '' + val + '';
};
function renderDate(value){
return value ? value.dateFormat('M d, Y') : '';
};

colModel = new Ext.grid.ColumnModel([

{
header: 'OrderID',
dataIndex: 'OrderID',
width: 50
},
{
header: 'Customer',
dataIndex: 'CustomerID',
width: 50
},
{
header: 'Order Date',
dataIndex: 'OrderDate',
width: 50
},
{
header: 'Required Date',
dataIndex: 'RequiredDate',
width: 50
},
{
header: 'Shipped Date',
dataIndex: 'ShippedDate',
width: 50
},
{
header: 'Ship Postal Code',
dataIndex: 'ShipPostalCode',
width: 50
},
{
header: 'Ship Country',
dataIndex: 'ShipCountry',
width: 50
}
]);//end colModel
}//end if colModel
return colModel;
}//end getColumnModel

var buildGrid = function(){

function addRecord() {

var c_OrderID = new Ext.form.NumberField ({

fieldLabel: 'OrderID',
name: 'OrderID',
width:190,
allowDecimals: true,
allowNegative: false,
blankText: '0',
maxLength: 19

});

var c_CustomerID = new Ext.form.ComboBox ({

fieldLabel: 'Customer',
name: 'CustomerID',
width:190,
typeAhead: true,
triggerAction: 'all',
lazyInit: true,
displayField: 'CompanyName',
valueField: 'CustomerID',
hiddenName:'CustomerID',
forceSelection: true,
mode: 'local',
inputType:'text',
emptyText:'Select a CustomerID...',
selectOnFocus:true,
store : new Ext.data.JsonStore ({

autoLoad: true,
url: '/Orders/List.castle?task=getCustomers',
root: 'results',
fields:['CustomerID', 'CompanyName']
})

});

var c_EmployeeID = new Ext.form.ComboBox ({

fieldLabel: 'EmployeeID',
name: 'EmployeeID',
width:190,
typeAhead: true,
triggerAction: 'all',
lazyInit: true,
displayField: 'LastName',
valueField: 'EmployeeID',
hiddenName:'EmployeeID',
forceSelection: true,
mode: 'local',
inputType:'text',
emptyText:'Select a EmployeeID...',
selectOnFocus:true,
store : new Ext.data.JsonStore ({
autoLoad: true,
url: '/Orders/List.castle?task=getEmployees',
root: 'results',
fields:['EmployeeID', 'LastName']
})

});

var c_OrderDate = new Ext.form.DateField ({

fieldLabel: 'Order Date',
name: 'OrderDate',
width:190,
format : 'm/d/Y'
});

var c_RequiredDate = new Ext.form.DateField ({

fieldLabel: 'Required Date',
name: 'RequiredDate',
width:190,
format : 'm/d/Y'
});

var c_ShippedDate = new Ext.form.DateField ({

fieldLabel: 'Shipped Date',
name: 'ShippedDate',
width:190,
format : 'm/d/Y'
});

var c_ShipVia = new Ext.form.ComboBox ({

fieldLabel: 'ShipVia',
name: 'ShipVia',
width:190,
typeAhead: true,
triggerAction: 'all',
lazyInit: true,
displayField: 'CompanyName',
valueField: 'ShipperID',
hiddenName:'ShipperID',
forceSelection: true,
mode: 'local',
inputType:'text',
emptyText:'Select a ShipVia...',
selectOnFocus:true,
store : new Ext.data.JsonStore ({
autoLoad: true,
url: '/Orders/List.castle?task=getShippers',
root: 'results',
fields:['ShipperID', 'CompanyName']
})

});

var c_Freight = new Ext.form.NumberField ({

fieldLabel: 'Freight',
name: 'Freight',
width:190,
allowDecimals: true,
allowNegative: false,
blankText: '0',
maxLength: 19
});

var c_ShipName = new Ext.form.TextField ({

fieldLabel: 'ShipName',
name: 'ShipName',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var c_ShipAddress = new Ext.form.TextField ({

fieldLabel: 'ShipAddress',
name: 'ShipAddress',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var c_ShipCity = new Ext.form.TextField ({

fieldLabel: 'ShipCity',
name: 'ShipCity',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var c_ShipRegion = new Ext.form.TextField ({

fieldLabel: 'ShipRegion',
name: 'ShipRegion',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var c_ShipPostalCode = new Ext.form.TextField ({

fieldLabel: 'Ship Postal Code',
name: 'ShipPostalCode',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var c_ShipCountry = new Ext.form.TextField ({

fieldLabel: 'Ship Country',
name: 'ShipCountry',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});


var newForm = new Ext.FormPanel({

baseCls: 'x-plain',
labelWidth: 100,
url:'/Orders/New.castle',
items: [

c_OrderID,
c_CustomerID,
c_EmployeeID,
c_OrderDate,
c_RequiredDate,
c_ShippedDate,
c_ShipVia,
c_Freight,
c_ShipName,
c_ShipAddress,
c_ShipCity,
c_ShipRegion,
c_ShipPostalCode,
c_ShipCountry
]
});

var newWin = new Ext.Window({
title: 'Add a new Orders',
width: 390,
height:500,
minWidth: 300,
minHeight: 250,
layout: 'fit',
plain:true,
bodyStyle:'padding:5px;',
buttonAlign:'center',
items: newForm,
buttons: [{
text: 'Save',
handler: function() {
if (newForm.form.isValid()) {
newForm.form.submit({
waitMsg:'In processing',
failure: function(form, action) {
Ext.MessageBox.alert('Error Message', action.result.errorInfo);
},
success: function(form, action) {
Ext.MessageBox.alert('Success:', action.response.responseText);
refreshGrid();
newWin.hide();
}
});
}
else {
Ext.MessageBox.alert('Errors', 'Please fix the errors noted.');
}
}
},{
text: 'Cancel',
handler: function(){
newForm.getForm().reset();
}
}]
});

newWin.on('minimize', function(){
newWin.toggleCollapse();
});
newWin.show(this);

}; // end addRecord

function deleteRecord(btn) {
if(btn=='yes') {
var selectedKeys = grid.selModel.selections.keys;

Ext.Ajax.request({
waitMsg: 'Saving changes...',
url: '/Orders/Delete.castle',
params: {
data: selectedKeys,
key: primaryKey
},
callback: function (options, success, response) {
if (success) {
Ext.MessageBox.alert('OK',response.responseText);
var json = Ext.util.JSON.decode(response.responseText);
Ext.MessageBox.alert('OK',json.del_count + ' record(s) deleted.');
} else{
Ext.MessageBox.alert('Sorry, please try again. [Q304]',response.responseText);
}
},
failure:function(response,options){
Ext.MessageBox.alert('Warning','Oops...');
},
success:function(response,options){
refreshGrid();
}
});
}
};

function handleDelete() {

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 handleDelete

function refreshGrid() {
ds.reload();//
}; // end refresh

function toggleDetails(btn, pressed){

var view = grid.getView();
view.showPreview = pressed;
view.refresh();

}

grid = new Ext.grid.GridPanel({
clicksToEdit:2,
colModel: getColumnModel(),
height:350,
//iconCls: 'icon-grid',
id: 'myGridID',
loadMask: true,
selModel: new Ext.grid.RowSelectionModel({singleSelect:false}),
store: ds,
stripeRows: true,
title:'Orders List',
width:600,
bbar: new Ext.PagingToolbar({

pageSize: myNameSpace.myModule.perPage,
store: ds,
displayInfo: true,
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No data to display",
items:[
'-', {
pressed: true,
enableToggle:true,
text: 'Show Preview',
cls: 'x-btn-text-icon details',
toggleHandler: toggleDetails
}]
}),
tbar: [
{
text: 'Add',
tooltip: 'Click to Add a row',

iconCls:'add',
handler: addRecord
}, '-', //add a separator
{
text: 'Delete',
tooltip: 'Click to Delete selected row(s)',

//function to call when user clicks on button
handler: handleDelete,
iconCls:'remove'
}, '->',
{
text: 'Refresh',
tooltip: 'Click to Refresh the table',
handler: refreshGrid,
iconCls:'refresh'
}
],
view: new Ext.grid.GroupingView({
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
})
});//end grid

grid.on('rowdblclick', function(grid, rowIndex, e) {
var id = ds.data.items[rowIndex].id;

var u_OrderID = new Ext.form.NumberField({
fieldLabel: 'OrderID',
name: 'OrderID',
width:190,

allowDecimals: true,
allowNegative: false,
blankText: '0',
maxLength: 19

});

var u_CustomerID = new Ext.form.ComboBox({
fieldLabel: 'Customer',
name: 'CustomerID',
width:190,

typeAhead: true,
triggerAction: 'all',
lazyInit: true,
displayField: 'CompanyName',
valueField: 'CustomerID',
hiddenName:'CustomerID',
forceSelection: true,
mode: 'local',
inputType:'text',
emptyText:'Select a CustomerID...',
selectOnFocus:true,
store : new Ext.data.JsonStore({
autoLoad: true,
url: '/Orders/List.castle?task=getCustomers',
root: 'results',
fields:['CustomerID', 'CompanyName']
})

});

var u_EmployeeID = new Ext.form.ComboBox({
fieldLabel: 'EmployeeID',
name: 'EmployeeID',
width:190,

typeAhead: true,
triggerAction: 'all',
lazyInit: true,
displayField: 'LastName',
valueField: 'EmployeeID',
hiddenName:'EmployeeID',
forceSelection: true,
mode: 'local',
inputType:'text',
emptyText:'Select a EmployeeID...',
selectOnFocus:true,
store : new Ext.data.JsonStore({
autoLoad: true,
url: '/Orders/List.castle?task=getEmployees',
root: 'results',
fields:['EmployeeID', 'LastName']
})

});

var u_OrderDate = new Ext.form.DateField({

fieldLabel: 'Order Date',
name: 'OrderDate',
width:190,
format : 'm/d/Y'
});

var u_RequiredDate = new Ext.form.DateField({

fieldLabel: 'Required Date',
name: 'RequiredDate',
width:190,
format : 'm/d/Y'
});

var u_ShippedDate = new Ext.form.DateField({

fieldLabel: 'Shipped Date',
name: 'ShippedDate',
width:190,
format : 'm/d/Y'
});

var u_ShipVia = new Ext.form.ComboBox({

fieldLabel: 'ShipVia',
name: 'ShipVia',
width:190,
typeAhead: true,
triggerAction: 'all',
lazyInit: true,
displayField: 'CompanyName',
valueField: 'ShipperID',
hiddenName:'ShipperID',
forceSelection: true,
mode: 'local',
inputType:'text',
emptyText:'Select a ShipVia...',
selectOnFocus:true,
store : new Ext.data.JsonStore({
autoLoad: true,
url: '/Orders/List.castle?task=getShippers',
root: 'results',
fields:['ShipperID', 'CompanyName']
})

});

var u_Freight = new Ext.form.NumberField({

fieldLabel: 'Freight',
name: 'Freight',
width:190,
allowDecimals: true,
allowNegative: false,
blankText: '0',
maxLength: 19

});

var u_ShipName = new Ext.form.TextField({

fieldLabel: 'ShipName',
name: 'ShipName',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var u_ShipAddress = new Ext.form.TextField({

fieldLabel: 'ShipAddress',
name: 'ShipAddress',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var u_ShipCity = new Ext.form.TextField({

fieldLabel: 'ShipCity',
name: 'ShipCity',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var u_ShipRegion = new Ext.form.TextField({

fieldLabel: 'ShipRegion',
name: 'ShipRegion',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var u_ShipPostalCode = new Ext.form.TextField({

fieldLabel: 'Ship Postal Code',
name: 'ShipPostalCode',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});

var u_ShipCountry = new Ext.form.TextField({

fieldLabel: 'Ship Country',
name: 'ShipCountry',
width:190,
maskRe: /([a-zA-Z0-9\s]+)$/
});


var updateForm = new Ext.FormPanel({

baseCls: 'x-plain',
labelWidth: 100,
url:'/Orders/Edit.castle',
reader: new Ext.data.JsonReader(
{ root: 'results'},
[

{name: 'OrderID', type: 'int'},
{name: 'CustomerID', type: 'string'},
{name: 'EmployeeID', type: 'int'},
{name: 'OrderDate', type: 'date', dateFormat: 'm/d/Y'},
{name: 'RequiredDate', type: 'date', dateFormat: 'm/d/Y'},
{name: 'ShippedDate', type: 'date', dateFormat: 'm/d/Y'},
{name: 'ShipVia', type: 'int'},
{name: 'Freight', type: 'float'},
{name: 'ShipName', type: 'string'},
{name: 'ShipAddress', type: 'string'},
{name: 'ShipCity', type: 'string'},
{name: 'ShipRegion', type: 'string'},
{name: 'ShipPostalCode', type: 'string'},
{name: 'ShipCountry', type: 'string'}
]),
items: [

u_OrderID,
u_CustomerID,
u_EmployeeID,
u_OrderDate,
u_RequiredDate,
u_ShippedDate,
u_ShipVia,
u_Freight,
u_ShipName,
u_ShipAddress,
u_ShipCity,
u_ShipRegion,
u_ShipPostalCode,
u_ShipCountry
]
});

updateForm.form.load({
url:'/Orders/List.castle?task=loadOrders&id='+id,
waitMsg:'Loading'
});

var window = new Ext.Window({
title: 'Edit Existing Orders',
width: 390,
height:500,
minWidth: 300,
minHeight: 250,
layout: 'fit',
plain:true,
bodyStyle:'padding:5px;',
buttonAlign:'center',
items: updateForm,
buttons: [{
text: 'Save',
handler: function() {
if (updateForm.form.isValid()) {
updateForm.form.submit({
params:{id : id},
waitMsg:'In processing',
failure: function(form, action) {
Ext.MessageBox.alert('Error Message', action.result.errorInfo);
},
success: function(form, action) {
Ext.MessageBox.alert('Confirm', action.response.responseText);
window.hide();
ds.load({params:{start:0, limit:10}});
}
});
}
else{
Ext.MessageBox.alert('Errors', 'Please fix the errors noted.');
}
}
},
{
text: 'Cancel',
handler: function(){window.hide();}
}]
});
window.show();

});
}//end function buildGrid

var renderGrid = function() {
grid.render('OrdersList');
}; //end function renderGrid

var loadStore = function() {
ds.load({
params: {
start: 0,
limit: myNameSpace.myModule.perPage
}
});
grid.getSelectionModel().selectFirstRow();
}; //end loadStore

return {
perPage: 10,
init : function(){
this.getMyGrid();

}, //end of init method
getMyGrid: function() {

Ext.QuickTips.init();
setupDataSource();
buildGrid();
renderGrid();
loadStore();
},
getDataSource: function() {
return ds;
}
}//end of return
}();

Ext.onReady(myNameSpace.myModule.init, myNameSpace.myModule, true);
</script>
<div id="OrdersList" ></div>

LiXin
5 Oct 2008, 3:59 PM
Controller: OrdersController.cs

[CODE]#region OrdersController.cs -- Copyright

LiXin
5 Oct 2008, 4:00 PM
Model: Orders.cs

[CODE]#region Orders.cs -- Copyright

imtihan
10 Jul 2010, 6:34 PM
Model: Orders.cs

[CODE]#region Orders.cs -- Copyright
can u give me link of the video, coz i need the tutorial.thanks