Hybrid View

  1. #1
    Sencha Premium Member
    Join Date
    Oct 2012
    Posts
    209
    Vote Rating
    -1
    vkeswani can only hope to improve

      0  

    Exclamation Unanswered: Displaying a custom image in Grid column headers

    Unanswered: Displaying a custom image in Grid column headers


    Is there an easy way to display image in Grid column headers. So I am able to show text but I want an icon right next to my column header text displayed.

    I tried using SafeHTML but it doesn't seem to work just displays and long text of string.

    Image img = new Image(ExampleImages.INSTANCE.checked());
    SafeHtml headerHtml = SafeHtmlUtils.fromString("<div style=\"text-align:center;\">" + img.toString() + "</div>");
    colConfig = new ColumnConfig<TransactionSummaryProxy, Double>(props.de4TransactionAmount(), 100, headerHtml.asString());

  2. #2
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,734
    Vote Rating
    90
    Answers
    109
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    SafeHtml is a way of saying "Part of my string is safe, and part is unknown, so make it all safe". You can read more at https://developers.google.com/web-to...curitySafeHtml

    In this case, you have a known-safe part, "<div style=\"text-align:center;\">" and "</div>", and something else which may or may not be safe img.toString(). Mixing and matching these, or appending multiple strings is best done in a SafeHtmlBuilder or SafeHtmlTemplates (see the above link) using GWT tools, or the GXT XTemplates tool.

    Then, you are turning the SafeHtml into a String at the end by calling asString() - by doing this you are telling the ColumnConfig that it is no longer trusted, and should be escaped. This constructor already accepts SafeHtml, so there is no need to do this.

    If we assume the img.toString() is safe, we can treat them all in the same way - but this isn't always a good assumption to make. Additionally, you should *not* toString() a widget to get HTML back - it is expensive, and might end up surprising you, like not supporting the event handlers you thought it would.

    The proper way to turn an ImageResource into an html string is to use AbstractImagePrototype or ImageResourceRenderer, both in GWT itself. Using the former, we would change your code to look like this:
    Code:
    SafeHtmlBuilder sb = new SafeHtmlBuilder();
    sb.appendHtmlConstant("<div style=\"text-align:center;\">");
    sb.append(AbstractImagePrototype.create(ExampleImages.INSTANCE.checked()).getSafeHtml());
    sb.appendHtmlConstant("</div>");
    colConfig = new ColumnConfig<TransactionSummaryProxy,  Double>(
            props.de4TransactionAmount(), 100, sb.toSafeHtml());
    Another, slightly easier to read approach could be an XTemplate:
    Code:
    interface MyImageTemplate extends XTemplates {
      @XTemplate("<div style=\"text-align:center;\">{img}</div>")
      SafeHtml render(SafeHtml img);
    }
    ...
    MyImageTemplate template = GWT.create(MyImageTemplate.class);
    ...
    SafeHtml image = AbstractImagePrototype.create(ExampleImages.INSTANCE.checked()).getSafeHtml();
    SafeHtml header = template.render(image);
    colConfig = new ColumnConfig<TransactionSummaryProxy,  Double>(
            props.de4TransactionAmount(), 100, header);

  3. #3
    Sencha User
    Join Date
    May 2012
    Posts
    19
    Vote Rating
    0
    Answers
    4
    BionicGeek is on a distinguished road

      0  

    Default


    Quote Originally Posted by Colin Alworth View Post
    Another, slightly easier to read approach could be an XTemplate:
    Code:
    interface MyImageTemplate extends XTemplates {
      @XTemplate("<div style=\"text-align:center;\">{img}</div>")
      SafeHtml render(SafeHtml img);
    }
    ...
    MyImageTemplate template = GWT.create(MyImageTemplate.class);
    ...
    SafeHtml image = AbstractImagePrototype.create(ExampleImages.INSTANCE.checked()).getSafeHtml();
    SafeHtml header = template.render(image);
    colConfig = new ColumnConfig<TransactionSummaryProxy,  Double>(
            props.de4TransactionAmount(), 100, header);
    This recommended pattern works but results in an undesirable column name when using the column selector on the grid. If you use this method to display an image in the header and you hit the arrow on one of the columns to select which columns to show/hide, there is no resulting label and the show/hide menu displays the entire SafeHtml string (e.g. "<div style=\"text-align:center;\">{img}</div>" with the image information populted in it). Is there a way around this?

  4. #4
    Sencha User
    Join Date
    May 2012
    Posts
    19
    Vote Rating
    0
    Answers
    4
    BionicGeek is on a distinguished road

      0  

    Default possible bug?

    possible bug?


    Is it possible this is a bug? In tracing through the code I don't see a viable workaround when the content provided is an image (specified by SafeHtml).

  5. #5
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,734
    Vote Rating
    90
    Answers
    109
    Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light Colin Alworth is a glorious beacon of light

      0  

    Default


    Code:
    public class Test implements EntryPoint {
    
      public void onModuleLoad() {
    
        ColumnConfig<Object, Object> sampleColumn = new ColumnConfig<Object, Object>(new IdentityValueProvider<Object>());
        sampleColumn.setHeader(SafeHtmlUtils.fromSafeConstant("<img src='http://sencha.com/img/sencha-large.png'>"));
        List<ColumnConfig<Object, ?>> columns = new ArrayList<ColumnConfig<Object, ?>>();
        columns.add(sampleColumn);
        
        ListStore<Object> store = new ListStore<Object>(new ModelKeyProvider<Object>() {
          @Override
          public String getKey(Object item) {
            return "";
          }
        });
        Grid<Object> grid = new Grid<Object>(store, new ColumnModel<Object>(columns));
        
        RootPanel.get().add(grid);
      }
    }
    Very bad sample (grid of object? keys are all ""?!?), but it shows the sencha logo in the column header, and is tested with GWT 2.4.0 and GXT 3.0.1.

  6. #6
    Sencha User
    Join Date
    May 2012
    Posts
    19
    Vote Rating
    0
    Answers
    4
    BionicGeek is on a distinguished road

      0  

    Default same issue

    same issue


    Colin,

    Thanks for the example and it works as the previous example does but with the same issue for the column name. The image displays without a problem - the problem is that when you go to select columns to show/hide it won't display some kind of title, it displays the IMG tag. So in the example you provided, where you might think the column list would show "Logo" (or something like that) when you are selecting columns to show/hide, it actually shows "<img src='http://sencha.com/img/sencha-large.png'>". That's the issue I was trying to describe and unfortunately neither one of these approaches seems to address that issue.