title: GWT: add filtering to CellTable
body: <p>I've been tasked with implementing sorting &amp; filtering of data displayed in a GWT <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/index.html?overview-summary.html" rel="nofollow noreferrer">CellTable</a>. 
  Thankfully GWT already supports sorting, but it looks like I'll have to hack together my own filtering support.</p>
  
  <p>To be more precise, what I'm trying to support is similar to the filtering offered by Excel, whereby you can click on a drop-down menu in the column headers and (for example) click checkboxes that will allow you to filter the rows based on the values for the filtered column(s). A picture is worth a thousand words:</p>
  
  <p><img src="https://i.stack.imgur.com/MRpOu.png" alt="excel column filtering"></p>
  
  <p><strong>My question</strong>: any suggestions on how to go about implementing this in GWT 2.2? Is it even possible? </p>
  
  <p>One option I'm thinking about is to pass in a custom <a href="http://google-web-toolkit.googlecode.com/svn/javadoc/2.1/com/google/gwt/user/cellview/client/Header.html" rel="nofollow noreferrer">Header</a> object to CellTable.addColumn(). If it's possible, I'll add a ClickHandler to the Header, and then open a Popup that displays a widget for filtering. Not sure how to implement this without negatively affecting the sorting behavior.</p>
  
  <p>Any suggestions gladly welcome.</p>
  
  <p><strong>Edit</strong>:</p>
  
  <p>Thanks to John below, I've got the following <code>FilterableHeader</code> class that allows me to at least put an icon into the header. Unsure how to get a ClickHandler on that icon just yet, as the image is inserted via HTML rather than using GWT widgets.</p>
  
  <pre><code>public class FilterableHeader extends Header&lt;String&gt;
  {
      /**
       * Image resources.
       */
      public static interface Resources extends ClientBundle
      {
          ImageResource downArrow();
          ImageResource upArrow();
      }
  
      private static final Resources RESOURCES = GWT.create(Resources.class);
      private static final int IMAGE_WIDTH = 16;
      private static final String DOWN_ARROW = makeImage(RESOURCES.downArrow());
      private static final String UP_ARROW = makeImage(RESOURCES.upArrow());
  
      private static String makeImage(ImageResource resource)
      {
          AbstractImagePrototype proto = AbstractImagePrototype.create(resource);
          return proto.getHTML().replace("style='", "style='position:absolute;right:0px;top:0px;");
      }
  
      private String text;
  
      public FilterableHeader(String text)
      {
          super(new ClickableTextCell());
          this.text = text;
      }
  
      @Override
      public String getValue()
      {
          return text;
      }
  
      @Override
      public void render(Cell.Context context, SafeHtmlBuilder safe)
      {
          int imageWidth = IMAGE_WIDTH;
  
          StringBuilder sb = new StringBuilder();
          sb.append("&lt;div style='position:relative;cursor:hand;cursor:pointer;");
          sb.append("padding-right:");
          sb.append(imageWidth);
          sb.append("px;'&gt;");
          sb.append(UP_ARROW);
          sb.append("&lt;div&gt;");
          sb.append(text);
          sb.append("&lt;/div&gt;&lt;/div&gt;");
  
          safe.append(SafeHtmlUtils.fromSafeConstant(sb.toString()));
      }
  }
  </code></pre>