Depending on your specific responsibilities, in most cases, most of us programmers do not have to hash out the ideas of what becomes an effective design or work flow in the project or product of what we work on. Thankfully. However, if it is, then the following becomes a lot more common: where Engineering will say to Marketing, this idea just isn’t going to work and we’ll need another 2 weeks further from our already tight deadline. OK so I’m not dealing with any sort of hard deadline other than just wanting to have some sort of completion to the first stage, I did have to go back and come up with ‘a better way to use things.’ Notice I didn’t say ‘do things.’

It came down to the idea of in dealing with normal blogging applications, I didn’t really like the idea of not being able to write out a comment while keeping a portion of the original post open or viewable to be able to write out my thoughts in a systematic way. The typical HTML-based approach is to insert the comments form at the bottom of the post. This means for most posts over a few hundred word count, in order to reference something in the middle or beginning typically you’ll have to scroll back and forth.

So my first iteration and thoughts on how to tackle this looked (when simplified) similar to:

<mx:Box id=“contentWrapper” direction=“{this.getStyle(‘contentDirection’)}” width=“100%” height=“100%”>
<mx:TextArea id=“body” width=“100%” height=“100%”
styleName=“postTextArea” editable=“false” creationComplete=“this.showShortDescription(); “ link=“openSnippetViewer(event);”/>
</mx:Box>

Which produced a result that more or less looked like this (this wasn’t completely refined at the time of the rearrangement of UI but it’s developed enough to get the point):

An example of cramped UI

While it might not look like anything was terribly wrong, in order for the screen real estate to become usable, the app had to be scaled out to a minimum of 1100×1000. Which lets face it, I’d be willing to say that a majority of the eventual users out there still operate on a relatively small monitor and/or medium to large resolution, or for those that do have something that would fit, the app can’t be expected to hog the entire desktop.

So this was one of those, it worked well in theory but not in a practical sense. For those of us who have been doing this long enough, know this is just another case of an iterative pattern approach. So going back to think about this one, since I’ve already used the tab-based feel, why not duplicate that for more organizational goodness. Now, considering I was working in a different area at the time, my brain took a slight vacation when it came to revisit this code, and like most of us, thought: oh #@!#$ just exactly how did I do this?

Here’s an idea of what this change entailed in a before and after.

The three main elements of what had to change:

public function addCommentsPanel():void {
if (!this.commentPanel) { this.commentPanel =new CommentsViewer()}

this.setContentWidth();
this.setContentHeight();
this.contentWrapper.addChild(this.commentPanel);
this.commentPanel.addEventListener(CloseEvent.CLOSE, removeCommentsPanel);
}

public function removeCommentsPanel(event:CloseEvent =null):void {
this.commentPanel.removeEventListener(CloseEvent.CLOSE, removeCommentsPanel);

controlBar.commentsButton.selected =false;
if (this.contentWrapper.contains(this.commentPanel)) {
this.contentWrapper.removeChild(this.commentPanel);
this.body.percentWidth =this.body.percentHeight =100;
}
}

<mx:Box id=“contentWrapper” direction=“{this.getStyle(‘contentDirection’)}” width=“100%” height=“100%”>
<mx:TextArea id=“body” width=“100%” height=“100%” styleName=“postTextArea” editable=“false
creationComplete=“this.showShortDescription();” link=“openSnippetViewer(event);”/>
</mx:Box>

What it looks like now:

public function addCommentsPanel():void {
if (!this.commentPanel) {
this.commentPanel =new CommentsViewer();
this.commentPanel.label =this.formatCommentLabel();
}

this.contentOrganizer.addChild(this.commentPanel);
this.commentPanel.addEventListener(CloseEvent.CLOSE, removeCommentsPanel);
}

public function removeCommentsPanel(event:CloseEvent =null):void {
this.commentPanel.removeEventListener(CloseEvent.CLOSE, removeCommentsPanel);

controlBar.commentsButton.selected =false;
if (this.contentOrganizer.contains(this.commentPanel)) {
this.contentOrganizer.removeChild(this.commentPanel);
}
}

<mx:TabNavigator id=“contentOrganizer” width=“100%” height=“100%”>
<mx:Box label=“Post” id=“contentWrapper” direction=“{this.getStyle(‘contentDirection’)}” width=“100%” height=“100%”>
<mx:TextArea id=“body” width=“100%” height=“100%” styleName=“postTextArea” editable=“false”
creationComplete=“this.showShortDescription();” link=”openSnippetViewer(event);“/>
</mx:Box>
</mx:TabNavigator>

So here comes the Flex ‘best practice’ so to speak, as it became not only clear on how to make such a change, but also it turns out it only took just a few lines of code out of the 400 or so which just control the aspect of a post. While I’m not sure about other languages at this point, but that becomes a key feature to Flex that will only become more apparent over time: the ability to quickly a capability set within a matter of mere minutes instead of days or weeks for a complete re-write.

  • Reference UI elements by their id attribute: This became clear when I was adding the CommentViewer to the overall post. By encapsulating this capability I literally didn’t have to chase down anything that referenced the body TextArea element, even though it became a nest deeper in a new TabNavigator. This is because the id attribute is independent of it’s parent nesting.
  • Maintain UI element internal control: All outside influences that want to add / remove elements must go through ‘helper’ methods, even if it’s just a simple composite wrapper. This ends up paying you back, where you don’t end up with a lot of intertwined code that now has be changed.

Happy coding.