PDA

View Full Version : Improvement of App Design / Code



Windcape
21 Jan 2009, 1:07 PM
Hey

I'm starting to mess around with the framework, but the examples are always written much more different than I would do during development. The documentation seems rather vague on why this is done, so I figured I would ask.

In short, how can I improve the code/application-design of the following code.

A visual result can be seen here: http://twilight-wizard.net/public/media/extjsadmin.png



Ext.BLANK_IMAGE_URL = '../content/ext/resources/images/default/s.gif';

BlogTreePanel = Ext.extend(Ext.tree.TreePanel,
{
title: 'Blog Posts',
width: 200,
height: 400,
rootVisible: false,
border: false,
initComponent: function()
{
Ext.apply(this,
{
root: new Ext.tree.AsyncTreeNode(
{
children: []
})
})
BlogTreePanel.superclass.initComponent.apply(this, arguments);
}
});

var tree = new BlogTreePanel();

var blogId = 0;

var titleTextField = new Ext.form.TextField(
{
xtype: 'textfield',
fieldLabel: 'Title',
width: 740,
name: 'title'
});

var contentEditor = new Ext.form.HtmlEditor(
{
xtype: 'htmleditor',
id: 'contents',
fieldLabel: 'Contents',
name: 'contents',
height: 400,
width: 740
});

var data = new Ext.data.Store(
{
proxy: new Ext.data.HttpProxy({
url: 'Admin.asmx/GetBlogEntities'
}),
reader: new Ext.data.XmlReader({
record: 'BlogEntity',
id: 'BlogId'
},
['BlogId', 'Title', 'PostDate', 'Contents']
),
remoteSort: false
});

data.on('load', function()
{
tree.getRootNode().reload();

var tNode;
for(var i=0;i<data.getTotalCount();i++)
{
tNode = new Ext.tree.TreeNode(
{
text: data.getAt(i).data.Title,
leaf: true,
iconCls: 'blogIcon'
});

tNode.BlogEntity = data.getAt(i).data;

tNode.on('click', function()
{
titleTextField.setValue(this.BlogEntity.Title);
contentEditor.setValue(this.BlogEntity.Contents);
blogId = this.BlogEntity.BlogId;
});

tree.root.appendChild(tNode);
}
});

var contentForm = new Ext.FormPanel(
{
labelAlign: 'top',
id: 'contentForm',
border: false,
autoScroll: true,
title: 'Contents',
bodyStyle: 'padding: 5px 5px 0',
items: [{
border: false,
items:[{
border: false,
layout: 'form',
items: [titleTextField]
}]
},contentEditor,{
border: false,
width: 85,
buttons: [{
text: 'Save',
type: 'submit',
handler: submitHandler
}]
}]
});

function submitHandler()
{
if(titleTextField.getValue() == "" || contentEditor.getValue() == "")
{
return;
}

contentForm.getForm().errorReader = new Ext.data.XmlReader({
record : 'message',
success: '@success'
},[
'id', 'msg'
]);

contentForm.getForm().submit(
{
waitTitle: 'Saving',
waitMsg: 'Saving...',
url: 'Admin.asmx/SaveBlog',
params: {
'blogId': blogId
},
success: function()
{
data.load();
Ext.Msg.alert('Success', "Saved successfull!");
},
failure: function(form, action)
{
Ext.Msg.alert('Error!', action.response.responseText);
}
});
}

function addBlogHandler()
{
blogId = 0;
titleTextField.setValue("");
contentEditor.setValue("");
}

function deleteBlogHandler()
{
if(confirm("Are you sure?"))
{
var conn = new Ext.data.Connection();
conn.request(
{
waitTitle: 'Deleting',
waitMsg: 'Deleting record #' + blogId,
url: 'Admin.asmx/DeleteBlog',
params: {
'blogId': blogId
},
success: function()
{
//blogId = 0;
titleTextField.setValue("");
contentEditor.setValue("");
data.load();
Ext.Msg.alert('Success', "Deleted successfull!");
},
failure: function(form, action)
{
Ext.Msg.alert('Error!', action.response.responseText);
//Ext.Msg.alert('Error!', "Failed to delete record #" + blogId);
}
});
}
}

function adminViewport()
{
// Load data
var loaded = data.load();

// Render the viewport
var viewport = new Ext.Viewport(
{
layout:'border',
items:
[
new Ext.Panel(
{
region: 'west',
id: 'west-panel',
title: 'Archive',
split: true,
width: 230,
minSize: 175,
maxSize: 400,
collapsible: false,
margins: '0 0 0 5',
layout: 'accordion',
layoutConfig: {
animate: true
},
collapseFirst:false,
tbar: [
{
iconCls: 'add-feed',
text: 'Add',
handler: addBlogHandler,
scope: this
},
{
iconCls: 'delete-icon',
text: 'Remove',
handler: deleteBlogHandler,
scope: this
}],
items: [tree]
}),
new Ext.Panel(
{
region: 'center',
deferredRender: false,
activeTab: 0,
items:[contentForm]
})
]
});
}

21 Jan 2009, 1:45 PM
heh.


new Ext.Panel(
{
region: 'center',
deferredRender: false,
activeTab: 0, // <<--- not needed
items:[contentForm]
})

21 Jan 2009, 1:46 PM
also, you can use xtypes instead of new Ext.Panel. panel is the default type from container on.

21 Jan 2009, 1:46 PM
i would look at launching everything from Ext.onReady as well.

whodat
21 Jan 2009, 1:46 PM
This is a good question as I find myself soon to be challenged to write a huge application using EXT.

I decided to read more on JavaScript OOP and learn how I can leverage the principles I learned in Java to JavaScript.

I hope someone with more knowledge answers..:D

21 Jan 2009, 1:54 PM
:) there are lots of very talented developers on this board. Technically, i think this thread belongs in open discussion.

Windcape
21 Jan 2009, 2:12 PM
I'm launching it from the OnReady method, but that's in the "view" (ie. the aspx page that presents it), I just showed the important codebehind.

Cheers for the responses, I hope they'll be a few more.

Specially the treeview is annoying me, can't seem to make it more "simple", than it is. Can't understand why it needs to be extended, and not just made as a regulare

new TreePanel({config});

21 Jan 2009, 2:15 PM
uh,



new Ext.tree.TreePanel({
title: 'Blog Posts',
width: 200,
height: 400,
rootVisible: false,
border: false,
root: new Ext.tree.AsyncTreeNode({
children: []
})
});

seems fairly easy to me

Windcape
21 Jan 2009, 8:14 PM
I improved the code a bit. Visual result: http://www.twilight-wizard.net/public/media/extjsadmin.png



Ext.BLANK_IMAGE_URL = '../content/ext/resources/images/default/s.gif';

TwilightAdmin = function()
{
///
/// The Current open Blog. 0 = No selected blog.
///
this.blogId = 0;

///
/// Fetches the available Blog Entries from a WebService.
///
this.blogStore = new Ext.data.Store(
{
proxy: new Ext.data.HttpProxy({
url: 'Admin.asmx/GetBlogEntities'
}),
reader: new Ext.data.XmlReader({
record: 'BlogEntity',
id: 'BlogId'
},
['BlogId', 'Title', 'PostDate', 'Contents']
),
remoteSort: false
});

///
/// Blog Tree List.
///
this.blogList = new Ext.tree.TreePanel(
{
id: 'blog-tree',
title: 'Blogs',
width: 200,
height: 400,
rootVisible: false,
border: false,
root: new Ext.tree.AsyncTreeNode({
children: []
})
});

///
/// Input form for editing and creating Blog Entries.
///
this.submitButton = new Ext.Button({
text: 'Save',
minWidth: 95,
type: 'submit'
});

this.adminForm = new Ext.FormPanel(
{
labelAlign: 'top',
id: 'contentForm',
border: false,
autoScroll: true,
title: 'Contents',
bodyStyle: 'padding: 5px 5px 0',
items:
[
new Ext.Panel(
{
border: false,
items:[
{
border: false,
layout: 'form',
items: [new Ext.form.TextField(
{
fieldLabel: 'Title',
name: 'title',
id: 'title',
width: 740
})]
}]
}),
new Ext.form.HtmlEditor(
{
fieldLabel: 'Contents',
name: 'contents',
id: 'contents',
height: 400,
width: 740
}),
new Ext.Panel(
{
border: false,
width: 100,
items: [this.submitButton]
})
]
});

///
/// Creates or Updates a Blog Entry.
///
this.blogSubmitHandler = function()
{
if(this.adminForm.getForm().findField('title').getValue() == ""
|| this.adminForm.getForm().findField('contents').getValue() == "")
{
return;
}

this.adminForm.getForm().errorReader = new Ext.data.XmlReader({
record : 'message',
success: '@success'
},[
'id', 'msg'
]);

var owner = this;

this.adminForm.getForm().submit(
{
waitTitle: 'Saving',
waitMsg: 'Saving...',
url: 'Admin.asmx/SaveBlog',
params: {
'blogId': this.blogId
},
success: function()
{
owner.blogStore.load();
Ext.Msg.alert('Success', "Saved successfull!");
},
failure: function(form, action)
{
Ext.Msg.alert('Error!', action.response.responseText);
}
});
}
this.submitButton.on('click', this.blogSubmitHandler, this);

///
/// Reset the form, allowing for a new Blog Entry.
///
this.addBlogHandler = function()
{
this.blogId = 0;
this.adminForm.getForm().findField('title').setValue("");
this.adminForm.getForm().findField('contents').setValue("");
}

///
/// Removes a Blog Entry.
///
this.deleteBlogHandler = function()
{
if(this.blogId == 0) { return; }

var owner = this;

if(confirm("Are you sure?"))
{
var conn = new Ext.data.Connection();
conn.request(
{
waitTitle: 'Deleting',
waitMsg: 'Deleting record #' + this.blogId,
url: 'Admin.asmx/DeleteBlog',
params: {
'blogId': this.blogId
},
success: function()
{
this.blogId = 0;
owner.adminForm.getForm().findField('title').setValue("");
owner.adminForm.getForm().findField('contents').setValue("");
owner.blogStore.load();
Ext.Msg.alert('Success', "Deleted successfull!");
},
failure: function(form, action)
{
Ext.Msg.alert('Error!', action.response.responseText);
}
});
}
}

///
/// Loads the Blog Entries into the tree.
///
this.onDataLoad = function()
{
this.blogList.getRootNode().reload();

var owner = this;

var tNode;
for(var i=0;i<this.blogStore.getTotalCount();i++)
{
tNode = new Ext.tree.TreeNode(
{
text: this.blogStore.getAt(i).data.Title,
leaf: true,
iconCls: 'blogIcon'
});

tNode.BlogEntity = this.blogStore.getAt(i).data;

tNode.on('click', function()
{
owner.adminForm.getForm().findField('title').setValue(this.BlogEntity.Title);
owner.adminForm.getForm().findField('contents').setValue(this.BlogEntity.Contents);
owner.blogId = this.BlogEntity.BlogId;
});

this.blogList.root.appendChild(tNode);
}
}
this.blogStore.on('load', this.onDataLoad, this);

///
/// Load the data
///
this.blogStore.load();

///
/// Return the visual ViewPort result.
///
return new Ext.Viewport(
{
layout: 'border',
items:
[
new Ext.Panel(
{
region: 'west',
id: 'blog-panel',
title: 'Archive',
split: true,
width: 230,
minSize: 175,
maxSize: 400,
collapsible: false,
margins: '0 0 0 5',
layout: 'accordion',
layoutConfig: {
hideCollapseTool: true,
titleCollapse: false
},
collapseFirst: false,
tbar: [
{
iconCls: 'add-feed',
text: 'Add',
handler: this.addBlogHandler,
scope: this
},
{
iconCls: 'delete-icon',
text: 'Remove',
handler: this.deleteBlogHandler,
scope: this
}],
items: [this.blogList]
}),
new Ext.Panel(
{
region: 'center',
deferredRender: false,
items: [this.adminForm]
})
]
});
};