Skip to content

Instantly share code, notes, and snippets.

@esatterwhite
Created April 26, 2011 20:48
Show Gist options
  • Select an option

  • Save esatterwhite/943109 to your computer and use it in GitHub Desktop.

Select an option

Save esatterwhite/943109 to your computer and use it in GitHub Desktop.
ExtJS User Group Modal Form Example
/**
* Base Module for Generic Components
* @module Blackjack
*/
/**
* Class for creating Modal form objects.
* Meant to work with Blackjack.FormFactory
* @extends Ext.Window
* @namespace Blackjack
* @class ModalForm
* @for Blackjack.FormFactory
*
*/
Blackjack.ModalForm = Ext.extend(Ext.Window, {
/**
* If set to true the form will have a textarea for comments
* @config enableDefaults
* @type Boolean
* @default true
*/
enableDefaults:true
/**
* The url used by the form to submit data
* @config url
* @default /
* @type String
*/
,url:'/'
/**
* If set to true, the window will show itself when created
* @config autoShow
* @default false
* @type Boolean
*/
,autoShow:false
/**
* Form action type used when submitting data
* @config method
* @type String
*/
,method:'POST'
/**
* Specifies where to inject the form buttons. `bottom` to inject to the bottom
* @config buttonLocation
* @type String
* @default `top`
*/
,buttonLocation:'top'
/**
* If set to True will prevent the submit / cancel buttons from being added
* @config disableButtons
* @type Boolean
* @default false
*/
,disableButtons:false
/**
* If set to true the window will automatically be closed and removed from the DOM when either the cancel or submit buttons have been clicked
* and their respective handlers have been run
*
* @config closeOnAction
* @type Boolean
* @default true
*/
,closeOnAction:true
/**
* An array of fields or field definition that will be included in every form the factory creates
* @config defaultFields
* @type Array
* @default []
*/
,fileUpload:false
/**
* Defines the fields that will be displayed by default
* @private
* @config defaultFields
* @type Array
* @default []
*/
,defaultFields:[]
/**
* An Array of Ext Form Field config objects to add to the form
* @config fields
* @type {Array}
* @default []
*
*/
,fields:[]
/**
* @config labelAlign
* @type {String}
* @default right
*/
,labelAlign: 'right'
/**
* @config labelWidth
* @type {Integer}
* @default 70
*/
,labelWidth: 70
/**
* Text to display on the Submit button of the window
* @config submitButtonLabel
* @type {String}
* @default Submit
*/
,submitButtonLabel:'Submit'
/**
* If set to true, constrains the window to the viewport area
* @config constrain
* @type Boolean
* @default true
*/
,constrain:true
/**
* @config windowwidth
* @type {Integer}
* @default 350
*/
,windowWidth: 350
/**
* @config windowheight
* @type {Integer}
* @default 270
*/
,windowHeight: 270
,appendTo:'bottom' // `top` or bottom`
/**
* builds the form to be displayed, configurs events, event bubbling and callbacks
* @constructor
*/
,initComponent:function(){
var that = this // capture this in closure
,finalFields // fields to be added to the form
,config // cache for additional configs to deal with optional configs / toolbars
,flds; // holds the default fields
config = {};
// the form events bubble up to `this`
// so this allows you to configure the object with an
// anonymous function of your choice to run on user
// interaction of either button.
this.on('accept', this.onAccept.createDelegate(this));
this.on('cancel', this.onCancel.createDelegate(this));
// do clean up and either user action.
if (this.closeOnAction) {
this.on('useraction', this.cleanUp.createDelegate(this));
}
flds = this.getFormFields();
if ( this.appendTo == "bottom"){
finalFields = flds.append(this.fields);
}else{
finalFields = this.fields.append(flds);
}
this.form = new Ext.form.FormPanel({
xtype: 'form'
,labelAlign: this.labelAlign
,labelWidth: this.labelWidth
,items: finalFields
,fileUpload: this.fileUpload
,padding: '5px'
/*
* defines the object to which events shall bubble to
*/
,getBubbleTarget:function(){
return this; // resolves to Ext.window object
}.createDelegate(this)
});
// Event definition
this.addEvents({
'accept':true
,'cancel':true
,'cleanup':true
,'useraction':true
,'forminvalid':true
,'formvalid':true
,'submitsuccess':true
,'submitfailure':true
});
// Allow for bubbling
this.enableBubble([
'accept'
,'cancel'
,'useraction'
,'forminvalid'
,'formvalid'
,'submitsuccess'
,'submitfailure'
]);
var button_bar = [{
text: this.submitButtonLabel
,scope: this
,handler: function () {
var valid;
valid = this.isValid();
if(!valid){
return false;
}
/**
* fired when the user clicks the accept button on the window
* @event accept
* @param window {Ext.Window} the window panel
*/
that.fireEvent('accept', this);
/**
* fired when a user clicks either button on the window panel
* @event useraction
* @param window {Ext.Window} The window object
*/
that.fireEvent('useraction', this);
}
,iconCls: 'icon-icon icon-accept'
},{
text: 'Cancel'
,scope: this
,handler: function(){
/**
* fired when the user presses the cancel button on the window
* @event cancel
* @param window {Ext.Window} The window Object
*/
that.fireEvent('cancel', this);
that.fireEvent('useraction', this);
that.cleanUp();
}
,iconCls: 'icon-icon icon-decline'
}];
Ext.apply( this, {
width: this.windowWidth
,height: this.windowHeight
,modal: true
,autoScroll: true
,items: [ this.form ]
});
// insert buttons if not disabled
if (!this.disableButtons) {
config[this.buttonLocation == 'bottom' ? 'bbar' : 'tbar'] = button_bar;
Ext.apply(this, config);
}
if( this.autoShow){
this.on('afterrender', function(){
this.show();
}, this, {
single:true
} );
}
Blackjack.ModalForm.superclass.initComponent.apply( this, arguments );
if ( this.title ) {
this.setTitle( this.title );
}
}
/*
*
* var myForm = new Blackjack.ModalForm({
* url:"/documents"
* ,listeners:{
* formvalid: function(){
* // do something magical
* }
* ,submitsuccess: function(){
* // do something when the form is submited successfully
* }
* }
* })
*
* myForm.submit();
*
* myForm.submit({
* method:"PUT"
* });
*
* myForm.submit({
* ajax: true
* ,scope:this
* ,url:'/diff/url
* ,fieldValues:true
* ,success: function(response){
* // do something with the response
* }
*
* })
*/
/**
* Submits the underlying form
* @method submit
* @param config {Object} Options to configure the submit action<br>
* <ul>
* <li><code><b>url ( String )</b></code>: the url used to send the form data to</li><br/>
* <li><code><b>ajax ( Boolean )</b></code>: if true, will send data via ajax</li><br/>
* <li><code><b>scope ( Object )</b></code>: the scope to run success and failure methods in</li><br/>
* <li><code><b>success ( Function )</b></code>: the function to run on a successful form submit</li><br/>
* <li><code><b>failure ( Function )</b></code>: the function to run on a failed form submit</li><br/>
* <li><code><b>method ( String )</b></code>: The form's action method( post / get )</li><br/>
* <li><code><b>fieldValues ( Boolean )</b></code>: if true will use getFieldValues to populate data, otherwise will use getValues</li><br/>
* </ul>
*
*/
,submit: function( config ){
var form_data;
// config is optional
config = config || {};
// set the url
url = config.url || this.url;
if ( !url ) { throw "You must specify a url property: ModalForm.js line 287"; }
// if we don't have a url, or the form is invalid, don't do anything
if ( !this.form.getForm().isValid() ) {
return;
}
// get the form data
form_data = config.fieldValues ? this.getFieldValues() : this.getValues();
// append any additional data if passed in
Object.merge(form_data, ( config.data || {}) );
this.cleanFormData( form_data );
// if configured to be ajax, send an ajax request
if (config.ajax && !this.fileUpload) {
new Blackjack.Ajax({
url: url
,autoSend:true
,method: ( config.method || this.method )
,scope: this
,jsonData: form_data
// calls the success function and fires event
,success: function( response ){
if ( config.success && typeof config.success == 'function'){
config.success.call( (config.scope || this), response );
}
/**
* Fired when the form successfully completes submission
* @event submitsuccess
* @param form {Blackjack.ModalForm} The modal form object
* @param response {Object} the response from the server
*/
this.fireEvent('submitsuccess', this, response);
}
});
// otherwise do straight form post
} else {
this.getForm().submit({
url: url
,jsonData: form_data
,params:config.data
,scope: this
,waitMsg: 'Please wait'
// call the passed in success / failure method if it exists
// and fire an event
,success: function( form, action ){
if ( config.success && typeof config.success == 'function'){
config.success.call( (config.scope || this), form, action );
}
/**
* Fired when the form successfully completes submission
* @event submitsuccess ( ajax )
*/
this.fireEvent( 'submitsuccess', this, action.result );
}
,failure: function(form, action){
if ( config.success && typeof config.success == 'function'){
config.success.call( (config.scope || this), form, action );
}
this.fireEvent('submitfailure', this, action);
}
});
}
}
/**
* shortcut to the form's getValues method
* @method getValues
* @return {Object} object containing the values of the form
* Keys are the id's of the form elements
*/
,getValues:function(){
return this.form.getForm().getValues();
}
/**
* Proxy around the forms getForm method
* @method getForm
* @return {Ext.form.BasicForm} The internal form object
*
*/
,getForm: function(){
return this.form.getForm();
}
/**
* shortcut to the forms getFieldValues method
* @method getFieldValues
* @return {Object} object whos keys are the ides of the form elements and the values are the rad field values
*/
,getFieldValues: function(){
return this.form.getForm().getFieldValues();
}
/**
* Proxy to the forms load method
* @param config {Object}
* @return {Blackjack.ModalForm} The modal form instance
*/
,load: function( config ){
this.form.load( config );
return this;
}
/**
* Proxy to the basicForm loadRecord method
* @param record {Ext.data.Record}
* @return form {Ext.form.BasicForm} the internal form instance
*/
,loadRecord: function ( record ){
return this.form.getForm().loadRecord( record );
}
/**
* returns an array of config object for the default form fields to display
* @private
* @method getFormFields
* @return {Array}
*/
,getFormFields: function(){
return Array.from( this.enableDefaults ? this.defaultFields: [] );
}
,setDefaultFields: function(){}
/**
* callback function executed in response the the accept event
* @config onAccept
* @type Function
* @default Empty Function
*
*/
,onAccept: Ext.emptyFn
/**
* A function run on the form data before it is sent to the server
* Provides an opportunity to sanitze / modify the data before it is sent.
* @method cleanFormData
* @override
* @param data {Object} The form data about to be sent to the server
*/
,cleanFormData: Ext.emptyFn
/**
* Shortcut to the forms isValid function. Also throws events in response to the result
* @method isValid
* @return Boolean
*/
,isValid: function(){
var valid = this.form.getForm().isValid();
if( valid ){
/**
* Fired when the form validation passes
* @event formvalid
*/
this.fireEvent( 'formvalid' );
}
else{
/**
* Fired when the form validation fails
* @event forminvalid
*/
this.fireEvent( 'forminvalid' );
}
return valid;
}
/**
* callback function executed in response to the cancel function
* @config onCancel
* @type Function
* @default Empty Function
*
*/
,onCancel:Ext.emptyFn
/**
* closes the window, removeds all events and destroys it's dom
* @method cleanUp
* @private
* @return {undefined}
*/
,cleanUp:function(){
this.fireEvent('cleanup', this);
this.close();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment