Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I render a ClickableTextCell as an anchor in a GWT CellTable?

Tags:

anchor

cell

gwt

I've got a CellTable with multiple columns in simple TextCell()s. Two of the columns are 'clickable' via the ClickableTextCell() class, but I want to change how they look. What's the easiest way to get the cell contents to resemble an anchor tag, while still using a cell in the table?

I've tried the following: 1. Implement a custom renderer to add anchor tags 2. Scouring Google looking for hints 3. Ignoring 'my library does it you just have to change your entire framework' links 4. Rolling my head across they keyboard

It's funny how annoying this simple change is turning out to be.

My current thought is to implement a custom AnchorCell type which puts in an Anchor widget instead of whatever it does in the other ones, but I'm not sure what all would need to be done.

Any help is appreciated.

like image 593
Kieveli Avatar asked Jan 14 '11 13:01

Kieveli


4 Answers

As an example:

public class MyClickableCellText extends ClickableTextCell {

    String style;   
    public MyClickableCellText()
    {
        super();
        style = "myClickableCellTestStyle";
    }


     @Override
      protected void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
        if (value != null) {
          sb.appendHtmlConstant("<div class=\""+style+"\">");
          sb.append(value);
          sb.appendHtmlConstant("</div>");
        }
      }

     public void addStyleName(String style)
     {
         this.style = style; 
     }


}

And the style (without the div, because you are hardcoding the style on it):

.myClickableCellTestStyle{
    text-decoration:underline;

}

You can even create your own cell by not extending ClickableTextCell but extending AbstractCell (more powerful but need more explanation). Ask me if you need it!

like image 183
ramon_salla Avatar answered Oct 18 '22 17:10

ramon_salla


Mentioned solution have the problem, these are no links and stylesheets with a:hover and so on doesn't work.

Here is my solution:

private class SellerName {
    private final String sellerName;
    private final Command cmd;

    private SellerName(String displayName, Command cmd) {
      this.sellerName = displayName;
      this.cmd = cmd;
    }

    public String getDisplayName() {
      return sellerName;
    }

    public Command getCommand() {
        return cmd;
    }
};

private class SellerNameCell extends AbstractCell<SellerName> {

    public SellerNameCell() {
        super("click", "keydown");
    }

    @Override
    public void render(com.google.gwt.cell.client.Cell.Context context, SellerName value, SafeHtmlBuilder sb) {
         if (value != null) {
             sb.appendHtmlConstant("<a href='javascript:;'>");
             sb.appendEscaped(value.getDisplayName());
             sb.appendHtmlConstant("</a>");
         }
    }

    @Override
    public void onBrowserEvent(Context context, Element parent, SellerName value, NativeEvent event, ValueUpdater<SellerName> valueUpdater) {
        if (value == null)
            return;

        super.onBrowserEvent(context, parent, value, event, valueUpdater);
        if ("click".equals(event.getType())) {
            if (value.getCommand() != null)
                value.getCommand().execute();
        }
    }
};

It creates a real anchorcell which is clickable :)

like image 34
thomas Avatar answered Oct 18 '22 18:10

thomas


It would seem that your first instinct (implementing a custom renderer) is way easier:

SafeHtmlRenderer<String> anchorRenderer = new AbstractSafeHtmlRenderer<String>()
    {
        @Override
        public SafeHtml render(String object) {
            SafeHtmlBuilder sb = new SafeHtmlBuilder();
            sb.appendHtmlConstant("<a href=\"javascript:;\">")
                    .appendEscaped(object).appendHtmlConstant("</a>");
            return sb.toSafeHtml();
        }
    };

And then:

Column<YourThingy, String> anchorCol = new Column<YourThingy, String>(
            new ClickableTextCell(anchorRenderer))
    {

        @Override
        public String getValue(YourThingy object) {
            return object.toString();
        }
    };
like image 26
Marcelo Avatar answered Oct 18 '22 18:10

Marcelo


This is what you need:

public class ClickableSafeHtmlCell extends AbstractCell<SafeHtml> {
/**
 * Construct a new ClickableSafeHtmlCell.
 */
public ClickableSafeHtmlCell() {
    super("click", "keydown");
}

@Override
public void onBrowserEvent(Context context, Element parent, SafeHtml value, NativeEvent event,
        ValueUpdater<SafeHtml> valueUpdater) {
    super.onBrowserEvent(context, parent, value, event, valueUpdater);
    if ("click".equals(event.getType())) {
        onEnterKeyDown(context, parent, value, event, valueUpdater);
    }
}

@Override
protected void onEnterKeyDown(Context context, Element parent, SafeHtml value,
        NativeEvent event, ValueUpdater<SafeHtml> valueUpdater) {
    if (valueUpdater != null) {
        valueUpdater.update(value);
    }
}

@Override
public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
    if (value != null) {
        sb.append(value);
    }
}

And then usage:

Column<YourProxy, SafeHtml> nameColumn = new Column<YourProxy, SafeHtml>(
        new ClickableSafeHtmlCell()) {
    @Override
    public SafeHtml getValue(YourProxy object) {
        SafeHtmlBuilder sb = new SafeHtmlBuilder();
        sb.appendHtmlConstant("<a>");
        sb.appendEscaped(object.getName());
        sb.appendHtmlConstant("</a>");
        return sb.toSafeHtml();
    }
};

nameColumn.setFieldUpdater(new FieldUpdater<YourProxy, SafeHtml>() {
        @Override
        public void update(int index, YourProxy object, SafeHtml value) {
             Window.alert("You have clicked: " + object.getName());

        }
    });
like image 21
Arash Avatar answered Oct 18 '22 17:10

Arash