TheNakedPirate
28 Jan 2008, 7:40 PM
I call myself a C# programmer. I was introduced to all the fuss around AJAX around 6 months ago and found Jack's library pretty soon after that. I really like it BUT...
There is a lot of code and its not perfect but it works and it illustrates a lot of things that I wish I knew about EXT before I started.
I would appreciate your comments and improvements if you have them as I want to will make a tutorial one day to explain it all a bit better.
The core JSON call manager
Ext.apply(Application, {
SITE_ROOT: ''
/*
* Show Exception
*/
, showException : function(msg){
var exmsg = 'The last action failed with this message <br/> <br/><code>' + msg + '</code> <br/> If the problem persists please report it to application support.';
Ext.MessageBox.show({
title:'An Exception has Occurred'
, msg: exmsg
, buttons: Ext.Msg.OK
, width: 440
});
}
/*
* Show Are You Sure
*/
, showAreYouSurePrompt: function(container, form){
var dirt = form.isDirty();
if(dirt)
{
Ext.Msg.show({
title:'Save Changes?'
, msg: 'There could be unsaved changes. <br/>Would you like to save your changes?'
, buttons: Ext.Msg.YESNOCANCEL
, fn: function(button){
switch(button)
{
case 'yes':
Application.submitForm(container, form);
break;
case 'no':
container.close();
break;
}
}
, icon: Ext.MessageBox.QUESTION
});
}
else { container.close(); }
}
/*
* Submit Form
*/
, submitForm : function(container, form){
if (form.isValid()) {
form.submit({
waitMsg: 'Processing your request...'
, success: function (f, a) {
if(container){
container.onSuccess(a);
}
}
, failure: function (f, a) {
if(container){
container.onFailure(a);
}
var r = a.result;
if(r) {
if(r.exception !== null) {
Application.showException(r.exception.message);
}
else {
for(i = 0; i < f.items.length; i++)
{
for(v = 0; v < r.data.length; v++)
{
var it = f.items.items[i];
var val = r.data[v];
var fieldName = it.name;
var l = fieldName.indexOf(".");
if(l > 0){
fieldName = it.name.substring(l + 1);
}
if( fieldName == val.propertyname){
it.markInvalid(val.message);
}
}
}
}
}
else {
Ext.MessageBox.alert('Action Failed', 'A server-side problem occured while performing the last action. If the problem persists please report it to application support.');
}
}
, scope:this
});
} else {
Ext.MessageBox.alert('Errors', 'Please fix the errors noted.');
}
}
});
A base Edit Window class
EditWindow = function(config){
Ext.apply(this, config);
this.addEvents({
'save' : true
, 'fail' : true
});
EditWindow.superclass.constructor.call(this, {
modal: true
, plain: true
, shim: false
, layout:'fit'
, defaults: {
msgTarget: 'side'
}
, buttons:[
this.saveButton = new Ext.Button({
text:'Save'
, handler: this.onSaveButton
, scope: this
, minWidth: 80
})
, this.cancelButton = new Ext.Button({
text: 'Cancel'
, handler: this.onCancelButton
, scope: this
, minWidth: 80
})]
});
};
Ext.extend(EditWindow, Ext.Window, {
form : Ext.emptyFn
, onSuccess: function(action) {
this.fireEvent("save", action);
}
, onFailure: function(action) {
this.cancelButton.enable();
this.fireEvent("fail", action);
}
, onSaveButton: function(action) {
this.cancelButton.disable();
if(this.form){
Application.submitForm(this, this.form.getForm());
}
}
, onCancelButton: function(action) {
if(this.form){
Application.showAreYouSurePrompt(this, this.form.getForm());
}
}
});
an implementation of a window
MyEditWindow = function(config){
Ext.apply(this, config);
this.form = new Ext.form.FormPanel({
url : Application.SITE_ROOT + '/MyEditView/CreateUpdate.rails'
, height: 480
, trackResetOnLoad: true // Important to track isDirty()
, defaults: {
// applied to each contained item
width: 330
, msgTarget: 'side'
}
, reader: new Ext.data.JsonReader({
totalProperty: 'totalrecords'
, root: 'data'
, id: 'id'
}
, Ext.data.Record.create([
{name: 'id'}
, {name: 'Obj.Number', mapping: 'number'}
, {name: 'Obj.Type', mapping: 'type'}
, {name: 'Obj.Date', mapping: 'expirydate'}
])
)
, items: [
new Ext.form.Hidden({name: 'ParentId', value: this.parentId})
, new Ext.form.Hidden({name: 'Obj.Id', value: this.recordId})
, new Ext.Panel({
border:false
, baseCls : 'helpText'
, html:'<div class="res-block"><div class="res-block-inner">'
+ '<h3>Instructions</h3><ul>'
+ '<li>All fields on this page must be filled in before a record can be created.</li>'
+ '</ul></div></div>'
})
, new Ext.form.TextField({name: 'Obj.Number', fieldLabel: 'Number' })
, new Ext.form.ComboBox({store: Ext.StoreMgr.get('Options'), editable: false, name: 'Obj.Type', fieldLabel: 'Type'})
, new Ext.form.DateField({name: 'Obj.Date', fieldLabel: 'Date'})
]
});
MyEditWindow.superclass.constructor.call(this, {
title: 'Passport'
, items: this.form
, listeners :{
'render': function(c) {
if(this.recordId > 0){
this.form.getForm().load({
url: Application.SITE_ROOT + '/MyEditView/GetRecord.rails'
, params: {'id': this.recordId}
, waitMsg: 'Loading'
, success: function(f, a) {
}
, failure : function(f, a) {
}
, scope : this
});
}
}
, scope: this
}
});
Ext.StoreMgr.get('Options').load();
};
Ext.extend(MyEditWindow, EditWindow);
The call to create the edit window
, showWindow: function(recordId){
if(this.window){
this.window.close();
}
this.window = new MyEditWindow({
parentId: this.parentId
, recordId: recordId
});
this.window.on('save', function(action){
this.window.close();
this.refreshStore();
}, this);
this.window.show(this);
}
a typical success message would come back in the form
{"totalrecords":0,"success":true,"exception":null,"data":[]}
if success = true and exception is null the Transport object is serialised in the data array.
if success = false and exception is null a series of validation errors are serialised in the data array. this code then take the form and applies the server side messages to the form if it can.
if success = false and exception is true the exception is serialized in the data array
There is a lot of code and its not perfect but it works and it illustrates a lot of things that I wish I knew about EXT before I started.
I would appreciate your comments and improvements if you have them as I want to will make a tutorial one day to explain it all a bit better.
The core JSON call manager
Ext.apply(Application, {
SITE_ROOT: ''
/*
* Show Exception
*/
, showException : function(msg){
var exmsg = 'The last action failed with this message <br/> <br/><code>' + msg + '</code> <br/> If the problem persists please report it to application support.';
Ext.MessageBox.show({
title:'An Exception has Occurred'
, msg: exmsg
, buttons: Ext.Msg.OK
, width: 440
});
}
/*
* Show Are You Sure
*/
, showAreYouSurePrompt: function(container, form){
var dirt = form.isDirty();
if(dirt)
{
Ext.Msg.show({
title:'Save Changes?'
, msg: 'There could be unsaved changes. <br/>Would you like to save your changes?'
, buttons: Ext.Msg.YESNOCANCEL
, fn: function(button){
switch(button)
{
case 'yes':
Application.submitForm(container, form);
break;
case 'no':
container.close();
break;
}
}
, icon: Ext.MessageBox.QUESTION
});
}
else { container.close(); }
}
/*
* Submit Form
*/
, submitForm : function(container, form){
if (form.isValid()) {
form.submit({
waitMsg: 'Processing your request...'
, success: function (f, a) {
if(container){
container.onSuccess(a);
}
}
, failure: function (f, a) {
if(container){
container.onFailure(a);
}
var r = a.result;
if(r) {
if(r.exception !== null) {
Application.showException(r.exception.message);
}
else {
for(i = 0; i < f.items.length; i++)
{
for(v = 0; v < r.data.length; v++)
{
var it = f.items.items[i];
var val = r.data[v];
var fieldName = it.name;
var l = fieldName.indexOf(".");
if(l > 0){
fieldName = it.name.substring(l + 1);
}
if( fieldName == val.propertyname){
it.markInvalid(val.message);
}
}
}
}
}
else {
Ext.MessageBox.alert('Action Failed', 'A server-side problem occured while performing the last action. If the problem persists please report it to application support.');
}
}
, scope:this
});
} else {
Ext.MessageBox.alert('Errors', 'Please fix the errors noted.');
}
}
});
A base Edit Window class
EditWindow = function(config){
Ext.apply(this, config);
this.addEvents({
'save' : true
, 'fail' : true
});
EditWindow.superclass.constructor.call(this, {
modal: true
, plain: true
, shim: false
, layout:'fit'
, defaults: {
msgTarget: 'side'
}
, buttons:[
this.saveButton = new Ext.Button({
text:'Save'
, handler: this.onSaveButton
, scope: this
, minWidth: 80
})
, this.cancelButton = new Ext.Button({
text: 'Cancel'
, handler: this.onCancelButton
, scope: this
, minWidth: 80
})]
});
};
Ext.extend(EditWindow, Ext.Window, {
form : Ext.emptyFn
, onSuccess: function(action) {
this.fireEvent("save", action);
}
, onFailure: function(action) {
this.cancelButton.enable();
this.fireEvent("fail", action);
}
, onSaveButton: function(action) {
this.cancelButton.disable();
if(this.form){
Application.submitForm(this, this.form.getForm());
}
}
, onCancelButton: function(action) {
if(this.form){
Application.showAreYouSurePrompt(this, this.form.getForm());
}
}
});
an implementation of a window
MyEditWindow = function(config){
Ext.apply(this, config);
this.form = new Ext.form.FormPanel({
url : Application.SITE_ROOT + '/MyEditView/CreateUpdate.rails'
, height: 480
, trackResetOnLoad: true // Important to track isDirty()
, defaults: {
// applied to each contained item
width: 330
, msgTarget: 'side'
}
, reader: new Ext.data.JsonReader({
totalProperty: 'totalrecords'
, root: 'data'
, id: 'id'
}
, Ext.data.Record.create([
{name: 'id'}
, {name: 'Obj.Number', mapping: 'number'}
, {name: 'Obj.Type', mapping: 'type'}
, {name: 'Obj.Date', mapping: 'expirydate'}
])
)
, items: [
new Ext.form.Hidden({name: 'ParentId', value: this.parentId})
, new Ext.form.Hidden({name: 'Obj.Id', value: this.recordId})
, new Ext.Panel({
border:false
, baseCls : 'helpText'
, html:'<div class="res-block"><div class="res-block-inner">'
+ '<h3>Instructions</h3><ul>'
+ '<li>All fields on this page must be filled in before a record can be created.</li>'
+ '</ul></div></div>'
})
, new Ext.form.TextField({name: 'Obj.Number', fieldLabel: 'Number' })
, new Ext.form.ComboBox({store: Ext.StoreMgr.get('Options'), editable: false, name: 'Obj.Type', fieldLabel: 'Type'})
, new Ext.form.DateField({name: 'Obj.Date', fieldLabel: 'Date'})
]
});
MyEditWindow.superclass.constructor.call(this, {
title: 'Passport'
, items: this.form
, listeners :{
'render': function(c) {
if(this.recordId > 0){
this.form.getForm().load({
url: Application.SITE_ROOT + '/MyEditView/GetRecord.rails'
, params: {'id': this.recordId}
, waitMsg: 'Loading'
, success: function(f, a) {
}
, failure : function(f, a) {
}
, scope : this
});
}
}
, scope: this
}
});
Ext.StoreMgr.get('Options').load();
};
Ext.extend(MyEditWindow, EditWindow);
The call to create the edit window
, showWindow: function(recordId){
if(this.window){
this.window.close();
}
this.window = new MyEditWindow({
parentId: this.parentId
, recordId: recordId
});
this.window.on('save', function(action){
this.window.close();
this.refreshStore();
}, this);
this.window.show(this);
}
a typical success message would come back in the form
{"totalrecords":0,"success":true,"exception":null,"data":[]}
if success = true and exception is null the Transport object is serialised in the data array.
if success = false and exception is null a series of validation errors are serialised in the data array. this code then take the form and applies the server side messages to the form if it can.
if success = false and exception is true the exception is serialized in the data array