Ahmed Kamel
Ahmed Kamel

Reputation: 101

How to add clickhandler on ImageCell in GWT CellTable?

I have tried this but didn't work

Column<ContactInfo, String> imageColumn = new Column<ContactInfo, String>(new ImageCell()) {
       @Override
       public String getValue(ContactInfo object) {
           return "contact.jpg";
          }
        };
        imageColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {

        @Override
        public void update(int index, ContactInfo object, String value) {
        Window.alert("You clicked " + object.firstName);
        }

    });
cellTable.addColumn(imageColumn, SafeHtmlUtils.fromSafeConstant("<br/>"));

Upvotes: 10

Views: 12499

Answers (8)

foamroll
foamroll

Reputation: 813

This worked for me:

public class ButtonImageCell extends ButtonCell{
    @Override
    public void render(com.google.gwt.cell.client.Cell.Context context, 
        String renderedHtmlStr, SafeHtmlBuilder sb) {
        sb.appendHtmlConstant(renderedHtmlStr);
    }
}

In a class containing CellTable table:

TableResources resources = GWT.create(TableResources.class);
ImageResourceRenderer imageRenderer = new ImageResourceRenderer();

...

Column<MyRecord, String> buttonCol = new Column<MyRecord, String>(new ButtonImageCell()) {
    @Override
    public String getValue(MyRecord record) {
        if(record.isOn())
            return imageRenderer.render(resources.getOnImg()).asString();
        else
            return imageRenderer.render(resources.getOffImg()).asString();
    }
};

buttonCol.setFieldUpdater(new FieldUpdater<MyRecord, String>() {
    public void update(int index, MyRecordobject, String value) {
        if (Window.confirm("Do stuff?")) {
            //todo: stuff
        }
    }
});

...

table.addColumn(buttonCol, "");

Where the ImageResource comes from (resources):

public interface TableResources extends CellTable.Resources {

    interface TableStyle extends CellTable.Style {
    }

    @Source("/images/on.png")
    ImageResource getOnImg();

    @Source("/images/off.png")
    ImageResource getOffImg();
}

Upvotes: 0

agelbess
agelbess

Reputation: 4349

I got all the above and added them in my app. Thanks to all. stackoverflow rocks!

    ButtonCell bc = new ButtonCell() {
        @Override
        public void render(Context context, SafeHtml data, SafeHtmlBuilder sb) {
            if (data != null) {
                ImageResource icon = Connector.imageResources.minus();
                Image image = new Image(icon);
                //fix the mouse pointer
                image.getElement().getStyle().setCursor(Cursor.POINTER);
                //Do something with the DATA
                image.setTitle("Delete " + data.asString());
                SafeHtml html = SafeHtmlUtils.fromTrustedString(image.toString());
                sb.append(html);
            }
        }
    };
    Column<InstanceProperty, String> imageColumn = new Column<InstanceProperty, String>(bc) {
        @Override
        public String getValue(InstanceProperty object) {
            //return the DATA
            return object.getKey();
        }
    };
    imageColumn.setFieldUpdater(new FieldUpdater<InstanceProperty, String>() {
        @Override
        public void update(int index, InstanceProperty property,
                String value) {
            //you can also use the DATA to do something
            InstancePropertiesTable.this.dataProvider.getList().remove(index);
        }
    });
    addColumn(imageColumn, "");

Upvotes: 1

vik.barca
vik.barca

Reputation: 41

A good solution for this issue, if you use ActionCell that is able to handle clicking. The use of it is a bit complicatied, but for me it worked pretty well.

First you need to initialize ActionCell with a delegate, in the constructor, write new ActionCell.Delegate<your class>. In this override the method execute and in that write your code that handle the clicking event.

The other thing you need to do is building up a html from the image. The SafeHtmlUtils class gives you a very easy way to do that. It's fromTrustedString method helps you building up the html:

SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create ("Your image from a resource class").getHTML());

This way the SafeHtml field can be initalized and if you give the ActionCell's contructor the SafeHtml and the Delegate, that it will do the work for you.

In this example a button will be initialized with the image from the bundle file in it. You can make it without the button if you override the render method of the ActionCell and append the SafeHtmlBuilder in the method with the same SafeHtml variable as above.

My code looks like the following:

IdentityColumn<Type> imageCell = new IdentityColumn<Type>(new ActionCell<Type>("AnyString", 
                new ActionCell.Delegate<Type>() {

            @Override
            public void execute(final Type item) {
                "your code"
            }
        }) {

            @Override
            public void render(Context context, Type value, SafeHtmlBuilder sb) {
                if (value != null) {
                    SafeHtml html = SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create(resource.image).getHTML());
                    sb.append(html);
                }
            }
        });

You'd rather override the method in an another class but I didn't want to split them for this post. It worked for me very well, I hope it will help other's too.

Upvotes: 1

PVR
PVR

Reputation: 2524

You can try this rather than using ButtonCell or ImageCell. This will work for sure. As I have implemented for my requirement. Let me know how does it goes..

 ClickableTextCell imageCell = new ClickableTextCell() {
        @Override
        public void render(Context context, SafeHtml data, SafeHtmlBuilder sb) {
            if (data != null) {
                String imagePath = "icon.png";
                sb.append(imagePath);
            }
        }
    };

Column<ContactInfo, String> imageColumn = new Column<ContactInfo, String>(imageCell) {
       @Override
       public String getValue(ContactInfo object) {
           return "";
          }
        };
        imageColumn.setFieldUpdater(new FieldUpdater<ContactInfo, String>() {

        @Override
        public void update(int index, ContactInfo object, String value) {
        Window.alert("You clicked " + object.firstName);
        }

    });
cellTable.addColumn(imageColumn, SafeHtmlUtils.fromSafeConstant("<br/>"));

Upvotes: 1

mutexkid
mutexkid

Reputation: 1084

public class ButtonImageCell extends ButtonCell{

    @Override
    public void render(com.google.gwt.cell.client.Cell.Context context, 
            String value, SafeHtmlBuilder sb) {
        SafeHtml html = SafeHtmlUtils.fromTrustedString(new Image(value).toString());
        sb.append(html);
    }
}

in use:

final Column<ReportDTOProxy, String> buttonImageCellTest = new Column<ProxyObject, String>(new ButtonImageCell()) {
    @Override
    public String getValue(ProxyObject row) {
        //url to image
        return row.getImageUrl();
    }
};

Upvotes: 19

Sergey Kulagin
Sergey Kulagin

Reputation: 81

You can extend ImageCell class and override 2 it's methods - getConsumedEvents and onBrowserEvent. Example:

    private class MyImageCell extends ImageCell{

    @Override
    public Set<String> getConsumedEvents() {
        Set<String> consumedEvents = new HashSet<String>();
        consumedEvents.add("dblclick");
        return consumedEvents;
    }

    @Override
    public void onBrowserEvent(Context context, Element parent,
            String value, NativeEvent event,
            ValueUpdater<String> valueUpdater) {
            switch (DOM.eventGetType((Event)event)) {
            case Event.ONDBLCLICK:
                // TODO
                break;

            default:
                break;
            }
    }

}

Upvotes: 8

Lenz
Lenz

Reputation: 398

I did something similar mixing a Button cell with the renderer from an ImageCell....

    ButtonCell bc = new ButtonCell() {
        @Override
        public void render(Context context, SafeHtml data, SafeHtmlBuilder sb) {
            if (data != null) {
                ImageResource icon = Icons.BUNDLE.pieChart();
                SafeHtml html = SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create(icon).getHTML());
                sb.append(html);
            }
        }
    };

You get the idea. The only problem is that it does not display the "hand" icon when you hover over it.... likely it can be fixed by setting the CSS.

Upvotes: 1

Amey
Amey

Reputation: 2214

You need to sinkEvents() with appropriate bits.

Refer to answer of Question Adding ClickHandler to div which contains many other widget.

Upvotes: -1

Related Questions