Introducing React ReExt – Sencha Ext JS Components in React! LEARN MORE

Customizing GXT Grid for Data Centric Applications

March 23, 2016 128 Views
Show

The GXT Grid is one of the most popular components for enterprise applications. It offers powerful built-in features including:

  • local or remote filtering
  • local or remote sorting
  • column grouping
  • a tree view (TreeGrid)
  • paging and “infinite” scrolling
  • editable cells
  • extensible column header menus

GXT Grid

In this article, we’ll look at three ways you can customize the Javascript Grid for typical enterprise use cases:

  • Create a custom hyperlink cell
  • Enable editing per row / per cell
  • Extend column header menus

Create a Custom Hyperlink Cell

GXT provides numerous types of cells that can be used in a GXT Grid. All of these extend the GWT AbstractCell class, so they are interchangeable with GWT cell widgets. That is, you can use a GXT cell in a GWT CellTable or use a GWT cell in a GXT Grid.

One cell type that is not included in GWT nor GXT is a simple hyperlink cell which displays a clickable link based on some attribute of the underlying record. In this example, we’ll create such a cell. We’ll create an AnchorLinkCell that extends the GWT AbstractCell type and defines an AnchorListener interface that will be used to handle a click on the link. The result will look like this:

Custom Hyperlink Cell

The name column uses our new AnchorLinkCell.

package com.example.project.client.customcell;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.sencha.gxt.core.client.ValueProvider;

/**
 * Displays a hyperlink anchor in a cell and provides an interface
 * to handle onClick.
 */
public class AnchorLinkCell extends AbstractCell {

    public interface AnchorListener {
        void onClick(T value);
    }
    
    private final ValueProvider<T, String> vp;
    private final AnchorListener listener;

    public AnchorLinkCell(ValueProvider<T, String> vp, AnchorListener listener) {
        // consume click event
        super("click");
        this.listener = listener;
        this.vp = vp;
    }

    @Override
    public void render(com.google.gwt.cell.client.Cell.Context context, T obj, SafeHtmlBuilder sb) {
        sb.appendHtmlConstant("

“); } @Override public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context, Element parent, T value, NativeEvent event, ValueUpdater valueUpdater) { super.onBrowserEvent(context, parent, value, event, valueUpdater); if (parent.getFirstChildElement().isOrHasChild(Element.as(event.getEventTarget()))) { listener.onClick(value); } } }

The AnchorLinkCell constructor supplies a GXT ValueProvider that will be used to obtain the hyperlink text. In addition, it supplies the AnchorListener to handle clicks. The render() method creates a <div> containing an <a> element. For simplicity in this example, we’re using inline styles. The default hyperlink style gets overridden by the GXT reset.css, so we need to recreate the standard hyperlink appearance. The onBrowserEvent() is overridden to delegate all consumed events (in this case, only mouse clicks) to the ActionListener.

Now let’s look at how to wire up the AnchorLinkCell for a column. Let’s assume we already have an Employee class representing the model type of the data in the Grid and its corresponding PropertyAccess interface. To use the cell, we just need to create a ColumnConfig and set the cell type to our custom AnchorLinkCell:

        EmployeePropertyAccess epa = GWT.create(EmployeePropertyAccess.class);
        ...
        ColumnConfig<Employee, Employee> nameCol = new ColumnConfig<Employee, Employee>(epa.identity(), 100, "name");
        nameCol.setCell(new AnchorLinkCell(epa.name(), new AnchorListener() {
            @Override
            public void onClick(Employee emp) {
                Info.display("onClick", "You selected employee # " + emp.getId());
            }
        }));
      ...

Note the type parameters of the ColumnConfig. Both the column type parameter and cell type parameter are the model type, Employee. This ensures that the Employee record can be passed through all the way to the AnchorListener. In order for this to work, the ValueProvider type in the ColumnConfig constructor must be the IdentityProvider for the Employee class. If we wanted to supply more info to the AnchorLinkCell class, such as the Employee ID to be used in the hyperlink URL, we could alter the AnchorLinkCell constructor to receive the whole PropertyAccess interface instead of just a single ValueProvider.

Enable Editing by Row

The inline editing grid is a powerful GXT feature that allows you to click or double-click on a cell to edit the value in place. To enable editing, we create an instance of GridInlineEditing and then add an Editor to it for the specific column we want to enable:

        ColumnConfig<Employee, String> notesCol = new ColumnConfig<Employee, String>(epa.notes(), 100, "notes");
        final Grid grid = new Grid(listStore, columnModel);
        GridEditing editing = new GridInlineEditing(grid);
        editing.addEditor(notesCol, new TextField());
Editing by Row

Click the notes column to edit in place.

This code above enables all cells in the notes column for inline editing. But what if we wanted to enable only select rows for editing? It turns out we can do this by overriding a method in the GridEditing class.

        ColumnConfig<Employee, String> notesCol = new ColumnConfig<Employee, String>(epa.notes(), 100, "notes");
        final Grid grid = new Grid(listStore, columnModel);
        GridEditing editing = new GridInlineEditing(grid) {
            // disable editing on select rows
            public void startEditing(Grid.GridCell cell) {
                editEmployee = getEditableGrid().getStore().get(cell.getRow());
                // Only names that start with S are editable
                if (editEmployee.getName().startsWith("S")) {
                    super.startEditing(cell);
                }
            };
        };
        editing.addEditor(notesCol, new TextField());

The startEditing() method gets invoked whenever the user clicks on an editable column. However, it must call super.startEditing() to actually begin editing the cell. We can use this to effectively disable editing for certain rows. In this case, editing for any row is enabled only if the employee name starts with “S.” We could also use the cell.getCol() property to obtain the column descriptor to decide whether to allow editing for a specific row and column.

Extend Column Header Menus

The third customization we’ll look at it is how to add items to a column header dropdown menu. Ordinarily, GXT builds the menu for you based on the Grid features such as sorting that you’ve enabled.

GXT-generated Column Header Menu

GXT-generated column header menu allows sorting, column selection.

To add a custom menu item to the column header context menu, we simply override the createContextMenu() method in the GridView class. In this example, we’ll add a custom action to the header menu for all columns:

        // Custom header menu items
        final Grid grid = new Grid(listStore, columnModel, new GridView() {
            @Override
            protected Menu createContextMenu(int colIndex) {
                Menu menu = super.createContextMenu(colIndex);
                menu.add(new MenuItem("custom1", new SelectionHandler() {
                    @Override
                    public void onSelection(SelectionEvent event) {
                        Info.display("test", "You clicked custom1");
                    }
                }));
                return menu;
            }
        });

The result looks like this:

New Custom Menu Item

The new custom menu item appears after the built-in menu items.

In addition, if we want to completely replace the contents of the custom context menu, we can do this by simply replacing the call to super.createContextMenu():

            ...
            protected Menu createContextMenu(int colIndex) {
                Menu menu = new Menu();
                menu.add(new MenuItem("custom1", new SelectionHandler() {
            …

The result looks like this:

Custom Menu Replaces Built-in Menu

A custom menu can completely replace the built-in menu.

Conclusion

The Grid is a powerful and highly extensible component of GXT and one of the most popular in enterprise applications. By extending the powerful GridEditing and GridView classes, you can further customize the functionality to create rich web applications with powerful UIs.

GXT
Show
Start building with Ext JS today

Build 10x web apps faster with 140+ pre-build components and tools.

Latest Content
Discover the Top 07 Architecture Patterns used in Modern Enterprise Software Development
Discover the Top 07 Architecture Patterns used in Modern Enterprise Software Development

Developing software without an architecture pattern may have been an option back then. However, that’s…

JavaScript Design Patterns: A Hands-On Guide with Real-world Examples
JavaScript Design Patterns: A Hands-On Guide with Real-world Examples

As a web developer, you know how popular JavaScript is in the web app development…

Virtual JS Days 2024のハイライト
Virtual JS Days 2024のハイライト

2024年2月20日~22日、第3回目となる「Virtual JavaScript Days」が開催されました。JavaScript の幅広いトピックを採り上げた数多くのセッションを実施。その内容は、Senchaの最新製品、ReExt、Rapid Ext JSまで多岐にわたり、JavaScriptの最新のサンプルも含まれます。 このカンファレンスでは多くのトピックをカバーしています。Senchaでセールスエンジニアを務めるMarc Gusmano氏は、注目すべきセッションを主催しました。Marc は Sencha の最新製品「ReExt」について、詳細なプレゼンテーションを実施。その機能とメリットを、参加者に理解してもらうべく詳細に説明しました。 カンファレンスは、Senchaのジェネラルマネージャを務めるStephen Strake氏によるキーノートでスタートしました。キーノートでは、会社の将来のビジョンについての洞察を共有しています。世界中から JavaScript 開発者、エンジニア、愛好家が集まるとてもエキサイティングなイベントとなりました。これは、JavaScript…

See More