2014-02-14

IE Input Clear Icon

Internet Explorer (IE) has added a convenience mechanism to HTML input boxes to clear the contents as shown here:


This may be a very nice value add feature in most cases, but when you are creating a widget library that already has a themed clear icon for input elements, this becomes a nuisance because you end up with two clear icons as seen here:



It's easy to remove the browser supplied clear icon by adding the following CSS pseudo element
Now, it looks the way you intended.

2014-02-04

IE problems with innerHTML

When writing a Javascript widget library, there is the constant need to test in all browsers. There are times like today that I just have to facepalm because of my findings.

One of the widgets I'm working with needs to have a button pushed inside of generated HTML. Because the button has event handlers, it was thought to just append the element inside the generated HTML.

In most browsers, this works. But in Internet Explorer, it appears that innerHTML wipes the contents of the element you're trying to append. In the following example, the button ends up being empty after setting the subsequent time.



The quick fix is to remove the child elements before calling innerHTML. Example shown below. Notice the lines that remove the child elements of the outer Element. This needs to be done first before calling innerHTML.



From what I can tell, IE must be doing something screwy with clearing content depth first when you set the innerHTML on an element. This makes it remove the contents of Elements you still have a reference to and are planning on reattaching to the DOM at a later time. To be safe, you should always remove the elements you want to reuse.

2011-04-07

Define GXT Templates in UiBinder

For my gxt-uibinder demo, I've been going through the Ext GWT Explorer and carefully converting what Sencha has done programmatically into XML UiBinder representation. There have been many hurdles to jump, but overall, things have been going well.

Recently, I've been in the mood to experiment with UiBinder, specifically with the <ui:...> type elements.  That is the portion of UiBinder I haven't really tapped into (with my other open source project gwt-customuibinder).

My next experiment is going to be to include custom Resource parsers.  This way, you're not limited to just the <ui:data>, <ui:image>, <ui:import>, <ui:style>, and <ui:with>.  I would like to have reusable GXT Templates and XTemplates.  This may look something similar to the following:

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
 xmlns:gxtui='urn:ui:com.jhickman.web.gwt.gxtuibinder'
        ....>

  <gxtui:xtemplate name="stateTemplate">
    <tpl for="."> 
       <div class="x-combo-list-item"
               qtip="{slogan}" qtitle="State Slogan">{name}</div> 
    </tpl> 
  </gxtui:xtemplate>

  ...
  <form:ComboBox
    emptyText="Select a state..."
    displayField="name"
    template="{stateTemplate}"
    width="150"
    store="{stateStore}"
    typeAhead="true"
    triggerAction="ALL" />
    
  ...

</ui:UiBinder>

With the current state of the GWT UiBinder code, it makes it very difficult to extend as most methods and fields are private.  To get my custom ElementParsers working in gwt-customuibinder, I had to use a lot of reflection.

Who knows.  It may give me such a headache, I'll end up reverting my changes and moving on.

2010-11-26

UiBinder Support For ExtGWT (GXT)

I recently wrote about a new open source library I released that supports registering custom UiBinder ElementParser classes called gwt-customuibinder.  As mentioned in that blog post, I have also released an open source library that utilizes this approach to support the ExtGWT library from Sencha (GXT) in UiBinder XML files called gxt-uibinder.

The current version of GXT was created prior to GWT 2.0 UiBinder, so it does not implement the proper interfaces, such as HasWidgets, to behave properly in UiBinder.  This means that when a project needs to add GXT layouts and widgets, it all needs to be done programmatically in the "View" class rather than declaratively in XML.  This causes a huge burden on the developer.

With my recent work on adding custom UiBinder ElementParsers for GWT, I have been able to add new ElementParsers for the ExtGWT framework to make working with GXT widgets in UiBinder much more friendly.  This project has been released as gxt-uibinder.

Getting Started
First, you must inherit the module.  Since this library uses gwt-customuibinder to register custom ElementParser classes, this module must be inherited after all other <inherit> lines.

For example:
<module>

  <inherits name="com.google.gwt.user.User" />
  <inherits name="com.extjs.gxt.ui.GXT" />

  <inherits name="com.jhickman.web.gwt.gxtuibinder.GxtUiBinder" />

  <source path="client" />
  <source path="shared" />
</module>


Supported Components

As this is a fairly new project, not all components are supported.  The most important one, however, is the ContainerParser for subclasses of the Container component.

Container
Since most of the "panels" in GXT (such as LayoutContainer, ContentPanel, etc) extend Container, then all of these these will support nested children.

LayoutContainer
GXT LayoutContainer subclasses Container, so all of the above apply here as well.  The major difference, however, is the ability to apply different "Layouts".

Currently, there are 2 supported Layouts: FitLayout and BorderLayout.   Below shows examples of both.

FitLayout
<gxt:LayoutContainer layout="FitLayout">
  <Label text="Hi" />
</gxt:LayoutContainer>

BorderLayout
BorderLayout supports layout regions as child elements. This means that the children of a LayoutContainer using the BorderLayout must be one of <gxt:center>, <gxt:west>, <gxt:north>, <gxt:east>, and <gxt:south>. Each region can only appear once, but may appear in any order.

Also note that each region, except <gxt:center> must specify a size attribute, specified in pixels. These regions also support the folling attributes:
  • split
    • boolean value. true if resizable split panel is needed.
  • collapsible
    • boolean value. true if the panel should contain the collapse button.
  • margins
    • can be specified as a single integer (ie margins="5") to make all margins the same, or a comma separated list of 4 integers (ie margins="0,5,0,0"). The order is top, right, bottom, left

<gxt:LayoutContainer layout="BorderLayout">
  <gxt:north size="30">
    <gxt:ContentPanel>...</gxt:ContentPanel>
  </gxt:north>
  <gxt:center>
    <gxt:ContentPanel>...</gxt:ContentPanel>
  </gxt:center>
  <gxt:east size="50" split="true" collapsible="true">
    <gxt:ContentPanel>...</gxt:ContentPanel>
  </gxt:east>
</gxt:LayoutContainer>

ContentPanel
GXT ContentPanel subclasses LayoutContainer, so all of the above apply here as well.  The ContentPanel supports specifying top and bottom components.  This is typically used for status bars or toolbars.  This can be done by using the child elements: <gxt:topcomponent> and <gxt:bottomcomponent>.  These are optional children, and may appear only once each.

For example:
<gxt:ContentPanel heading="Admin Scripting Console">
  <gxt:topcomponent>
    <menu:MenuBar borders="true" /><!-- menu explained below -->
  </gxt:topcomponent>
</gxt:ContentPanel>

Menus


GXT menus are also supported.  Here is an example of its usage:

<gxt:ContentPanel heading="Some Panel">
  <gxt:topcomponent>
    <menu:MenuBar borders="true">
      <menu:MenuBarItem text="File">
        <menu:Menu>
          <menu:MenuItem text="New" ui:field="newMenuItem" />
          <menu:MenuItem text="Open" ui:field="openMenuItem" />
          <menu:MenuItem text="Save"  ui:field="saveMenuItem" />
          <menu:MenuItem text="Save As" ui:field="saveAsMenuItem" />
          <menu:CheckMenuItem checked="true" />
        </menu:Menu>
      </menu:MenuBarItem>
    </menu:MenuBar>
  </gxt:topcomponent>
  <gxt:LayoutContainer layout="BorderLayout">
    <gxt:center>
      <gxt:LayoutContainer layout="FitLayout">
        <gxt:Label>
      </gxt:LayoutContainer>
    </gxt:center>
  </gxt:LayoutContainer>
</gxt:ContentPanel>

Custom Event Handling

The GXT event model differs from GWT.  This means that the @UiHandler annotation cannot be directly used to apply widget event handlers back to the owning view class.

For this, I have created a new annotation that can be used for GXT widget event binding.   It's called @GxtUiHandler.

For example, let's say in the UiBinder XML, you have a GXT button that needs to execute.  In the XML, the ui:field is used as normal.

<gxt:Button text="submit" ui:field="submitButton" />

In the owning view Java class, a method to receive the event will have the @GxtUiHandler annotation applied as such:

@GxtUiHandler(uiField="submitButton", eventType=GxtEvent.Select)
public void submitForm(ButtonEvent event) {
  System.out.println("form Submitted");
}

Unlike the @UiHandler annotation, we have to tell the compiler what Event type it relates to.  This is the major difference between @GxtUiHandler and @UiHandler annotations.

Summary

This library is still in early development, so does not yet support all GXT widgets and properties, but it may have enough for any project to get started with using GXT in their UiBinder XML files.



2010-11-23

Custom UiBinder ElementParsers for GWT

The other day, I released two new open source projects for GWT development to make it easier to adapt GWT widget libraries to UiBinder.

GWT UiBinder was introduced in GWT 2.0 as a declarative approach to building user interfaces.  Rather than programmatically instantiating objects and adding objects to containers, a new XML structure was added.  This approach not only saves hours of development time, but it also reduces the complexities of many application layouts.

Unfortunately, UiBinder wasn't made to support registering custom ElementParsers, thus only supporting core GWT widgets.  This means that if you're planning on using widgets in UiBinder XML, they must conform to the GWT rules. For example, "containers" must implement the HasWidgets interface to support nested children.

After doing a little bit of research, I have found that some people have tried modifying GWT classes (such as UiBinderWriter) and use ClassLoader tricks (changing class path search order) to get their modified versions of the GWT code loaded first, thus giving them the ability to use custom ElementParsers. Typically, this involves editing the UiBinderWriter every time you add a new ElementParser.

I have also recently come across discussions on a new annotation called @ElementParserToUse. With this annotation, a developer would be able to add it to any widget class to specify a specific ElementParser to use. This is a great step towards registering custom ElementParsers.

Unfortunately, this approach does not help me as I'm currently using Ext GWT from Sencha (GXT).  The current version of GXT was created prior to GWT 2.0 UiBinder, thus not implementing the proper interfaces, so when adding GXT widgets into your app, you are basically required to use a programmatic approach to the UI layouts.

I wanted to use GXT for it's rich widgets, but didn't want to fall back to developing my user interface programmatically.  To solve this problem, I started making my own modifications to the UiBinder code generation and released my work as gwt-customuibinder.

Using gwt-customuibinder and Registering Custom ElementParsers

To use gwt-customuibinder in your project, the first thing to do is to <inherit> the module.  This is done like this:
<module>
  ...
  <inherits name="com.jhickman.web.gwt.customuibinder.CustomUiBinder" />
</module>

This inherit line must be the last one for your module (or at least after com.google.gwt.user.User) as it overrides the UiBinderGenerator configuration. If the inherit line comes before, then the GWT UiBinderGenerator will be used, thus not giving you the desired results.

To register custom ElementParsers, you must "extend" a GWT configuration property called "gwt.uibinder.elementparser". This means that there are no code changes needed to support new ElementParser classes.

Here is an example:
<module>
  <extend-configuration-property 
    name="gwt.uibinder.elementparser"
    value="com.foo.client.ui.SomeWidget:com.foo.uibinder.elementparsers.SomeWidgetParser" />
</module>

As you can see from this code snippet, we "extend-configuration-property" called "gwt.uibinder.elementparser".  The value of this property must be a colon separated widget:parser combination.

Note: If you use "set-configuration-property", it will override the previous definitions and not all of the custom ElementParsers will be available.

Using gwt-customuibinder and Registering Custom HandlerEvaluators

Another item I realized when adapting 3rd party widget libraries to GWTs UiBinder is that not all libraries support the same Event model GWT provides. In order to have an equivalent of @UiHandler in the view code, I needed the ability to register a custom HandlerEvaluator. This supports the creation of any handler method annotation needed for your widget library.

Just as registering custom ElementParser classes, we can extend a different configuration property called "gwt.uibinder.customHandlerEvaluator" and use the full classname as the value.

For example:
<module>
  <extend-configuration-property
    name="gwt.uibinder.customHandlerEvaluator"
    value="com.foo.rebind.SomeCustomHandlerEvaluator" />
</module>

The value specified here must implement the "com.jhickman.web.gwt.customuibinder.rebind.CustomHandlerEvaluator" interface.


Conclusion

Although I am glad to start this new open source project as it gives me something fun to work on, I am fully hoping that the project will become unnecessary once the GWT team adds the support for registering custom ElementParsers.


Example Project
The other project I released is called gxt-uibinder. Watch for upcoming blog entry describing that project.

2010-06-10

Interesting Powers of Local Variables

I interviewed a Java developer recently and he had a very interesting (incorrect) interpretation of how local variables work in regards to method calls.

This candidate understands that when you pass an object to a method, the method may modify the data in that object, so that when you look at that object after the method call, it will have changed.   This is correct behavior.   For example:

public void addData(List<String> values) {
  values.add("data");
}

...

List<String> myValues = new ArrayList<String>();
addData(myValues);
assertTrue( myValues.size() == 1 );


Here's the interesting part.  The candidate believes that if you were to return a mutable object from a method and assign it to a local variable, the changes stay with that local variable.  For example:

public class Foo {
  private List<String> values = new ArrayList<String>();

  public List<String> getValues() {
    return values;
  }
}

...

Foo foo = new Foo();
List<String> myValues = foo.getValues();
assertTrue( myValues.isEmpty() );
myValues.add("data");  // mutate "local" variable

assertTrue( foo.getValues().isEmpty() );  // WRONG

The candidate insisted that there was only a single instance of the List, which made the conversation very confusing.  This caused a long discussion.  In the end, I believe that his thoughts are that local variables have the ability to hold object "deltas" in a way that aren't reflected back to the original object.

Although interviewing candidates is very time consuming, there are moments like this that I find fascinating.  It's very interesting to hear other peoples interpretations on how the language works.

2010-06-03

Code Quality Pushed Aside?!

It's probably a good time to move on when your team decides that code quality is the lowest priority task.  I understand that delivering the software is a very high priority as delivery of this software is how the business makes money.

I don't, however, believe that code quality should be pushed aside in "crunch" times.  When you have deadlines looming over head, that is the wrong time to throw peer code reviews and unit tests out the window.   Yes, you may be able to meet your deadlines and deliver the software, but at what cost?

How much will it cost the business when you deliver buggy software?  Not only are there maintenance costs (ie, the cost of having a developer fix the defect and then redeploy the code), but there is also the possibility of losing customers.  Losing customers may not be a big concern for certain software like browsers, email clients, blog software, etc; but it would be a big concern for software for medical equipment, financial, e-commerce, etc.

My team has continually pushed code reviews, unit tests, etc as a very low priority, especially in times of frequent deliveries.  The continual response is, "we'll have more time to do this and fix our processes later."  I have yet to see this mythical "later."

My team also doesn't understand why we get so many defects back from our QA team.  There have been times where management will require weekend work, to work on nothing but defect fixes.  If 80% of our time here is working on defect fixes, why can management not see that something needs to be changed?

If you're a software manager, please take the time to invest in good code quality practices such as unit testing and code reviews.  You'll be thankful you did.