Ext JS – A (very simple) email form with character counter

This super simple email form is for when the email recipients are already known and cannot be changed on the email form. I worked out two things I want to remember on this form – created a “tip” to expand the contents of an input field and also have a “amount of chars remaining” counter updating on the form. The counter shows the number of chars remaining and then when the limit is reached, the Ext JS validation “msg” text is shown. Here are some pictures (condensed).

Note: Ext JS 4 version at https://gist.github.com/aghuddleston/5357858.

Now the code snippets of the interesting parts. This is condensed a bit. The formpanel is in an Ext JS window, that I extended. The code for that is not here, but all the important bits and pieces should be.


	// snip
		new Ext.form.FormPanel({
			labelWidth: 167,
			defaultType: 'displayfield',
			baseCls: 'x-plain',
			itemId: 'emailform',
			items: [
				{
					xtype: 'container',
					layout: 'form',
					labelWidth: 55,
					anchor: '100%',
					items: {
						xtype: 'trigger',
						itemId: 'sendto',
						ref: '../../sendto',
						fieldLabel: 'Send To',
						value: this.getSendTos(),
						// name: 'to',
						submitValue: false,
						anchor: '-5',
						editable: false,
						scope: this,
						onTriggerClick : this.onSendToClick.createDelegate(this)
					}
				},
				{
					id: 'emailbody',
					itemId: 'emailbody',
					xtype: 'textarea',
					hideLabel: true,
					name: 'message',
					msgTarget: 'under',
					maxLength: 2000,
					anchor: '-5 -53',
					enableKeyEvents: true,
					listeners : {
						scope : this,
						keydown: this.updateTextCtr,
						keyup: this.updateTextCtr,
						focus: this.closeSendToTip
					}
				},
				{
					xtype: 'displayfield',
					itemId: 'textCtr',
					fieldLabel: 'Allowed characters remaining',
					hideParent: true,
					anchor: '-10'
				} 
			]
		});
	// snip

	buildSendToTip : function () {
		return new Ext.Tip({
			html: this.getSendTos(),
			closable: true,
			width: 400 // initial width needed to make the sizing work
		});
	},

	closeSendToTip : function () {
		if (this.sendToTip.isVisible()) {
			this.sendToTip.hide();
		}
	},
	
	/**
	 * When the user clicks in the send to box, pop open a tooltip that
	 * shows the complete list of the user ids this email is going to.
	 * The tip should cover the send to trigger field, right aligining
	 * with it, up to a maximum of 500px.
	 */
	onSendToClick : function (event) {
		var width = this.sendto.getWidth(),
			position = this.sendto.getPosition(),
			xpos;
		
		// Figure out how wide the tip should be, the max is 500
		if (width > 500) {
			xpos = position[0] + (width - 500);
			position[0] = xpos;
			width = 500;
		}
		
		this.sendToTip.setWidth(width);
		this.sendToTip.doLayout();
		this.sendToTip.showAt(position);
	},


	/**
	 * Update the 'Allowed chars remaining' text as the user types. Once the
	 * limit is reached, the Ext validation tip will display under the 
	 * text area and the allowed char remaining field will be hidden.
	*/
	updateTextCtr : function (body, event) {
		var form = this.getComponent('emailform'),
			ctr = form.getComponent('textCtr'),
			ctrEl = ctr.getEl(),
			text = body.getValue(),
			maxLength = body.maxLength;
			
		if (text.length > maxLength) {
			ctr.hide();
			ctrEl.up('.x-form-item').setDisplayed(false);
		} else {
			if (!ctr.isVisible()) {
				ctr.show();
				ctrEl.up('.x-form-item').setDisplayed(true);
			}
			ctr.setValue(maxLength - text.length);
		}
	}

	// extraInit is called on the window show event 
	extraInit : function () {
		var form = this.getComponent('emailform'),
			body = form.getComponent('emailbody'),
			ctr = form.getComponent('textCtr');
		
		ctr.setValue(body.maxLength);
	}

	// also destroying the tip on the window destroy event

4 comments

  1. Can you show please show me how to extend a simple Window in ExtJS 4, and show it?

    I try this in Firebug but no go:

    Ext.define(‘test.Window’, {
    name: ‘Unknown’
    , extend: ‘Ext.window.Window’
    , config: {
    title: ‘Test’
    , width: 400
    , height: 250
    , html: ‘TEST’
    } // eo config

    , updateHtml: function() {
    this.update(“Updated HTML!”);
    }
    });

    var win = Ext.create(‘test.Window’);
    win;

    1. The examples on the Sencha site are great for learning this. You can look at all the source code of the examples to learn. Try win.show(); after you create it.

  2. Nice work,
    However am having an error –
    this.getSendTos is not a function
    value: this.getSendTos(),

    Is this function get all email addresses from the server side.
    could you please implement it
    thanks you

    1. getSendTos is a function that I have to pull to build a list of user names that are shown on the To list. I already have a store of the users, so I iterate through it and build a comma separated list of the user names. That is used for display. Then when the form is submitted, I submit the data that is needed to actually send the email. This is a bit of an unusual email form b/c the “to” list is pre-selected and can’t be added to once it is shown.

Leave a reply to YangHax Cancel reply