1. #1
    Sencha User
    Join Date
    Nov 2009
    Posts
    71
    Vote Rating
    0
    valery.stroeder is on a distinguished road

      0  

    Default Xtemplate + Hashmap [SOLVED]

    Xtemplate + Hashmap [SOLVED]


    Hello,

    I need to use an hashMap in my combobox's template.


    Code:
    Map map = new HashMap<String,String>();
    map.put("test","it works!");
    
    ComboBox<MyObject> combo = new ComboBox<MyObject>();
    combo.setTemplate(getTemplate());
    Code:
    private native String getTemplate(final Map<String, String> map) /*-{
                return ['<tpl for="."> ' +                    
                        '<div>' + map.get("test") + '</div>' +
                        '</tpl>'].join("");
    }-*/;
    resulted stackTrace
    com.google.gwt.core.client.JavaScriptException: (null): null

    Anyone know how to deal with HashMap in native methods parameter?

    Thanks,

    Valery.
    Last edited by valery.stroeder; 30 Nov 2011 at 1:48 AM. Reason: SOLVED (maybe move the post to 2.X ?)

  2. #2
    Sencha User
    Join Date
    Jul 2011
    Posts
    45
    Vote Rating
    0
    raivis is on a distinguished road

      0  

    Default


    I am not sure if this works, didn't have time to check it out, but take a look at this link and the way they call java methods in native js methods

    http://stackoverflow.com/questions/9...-method-in-gwt

  3. #3
    Sencha User
    Join Date
    Nov 2009
    Posts
    71
    Vote Rating
    0
    valery.stroeder is on a distinguished road

      0  

    Default Xtemplate + Hashmap

    Xtemplate + Hashmap


    They used the $wnd object but it's only to call some javascript methods for example a jQuery function. It does not help me to access my hasMap available in parameter I think.

  4. #4
    Sencha Premium Member
    Join Date
    Feb 2011
    Location
    Amsterdam
    Posts
    54
    Vote Rating
    1
    sblommers is infamous around these parts

      0  

    Default Same problem but a bit more complex

    Same problem but a bit more complex


    Hi there, I use a custom Formatter to get my stuff from my Maps. (nested)
    I annotate a XTemplates custom renderer with my Custom Formatter

    Code:
    @FormatterFactories(@FormatterFactory(factory=MapFormatterFactory.class,methods={@FormatterFactoryMethod(name="get", method="get")}))
    
        public interface CustomRenderer extends XTemplates {
            @XTemplate(source = "record_custom.html")
            public SafeHtml render(TestRecord data);    
        }
        
        protected static class MapFormatter implements Formatter<Map<String, Serializable>> {
            private String path;
            
            protected MapFormatter(String path) {
                this.path = path;
            }
            
            public static MapFormatter get(String path) {
                return new MapFormatter(path);
            }
    
    
            @Override
            public String format(Map<String, Serializable> data) {
                final Serializable field = data.get(path);
                return field == null ? "" : field.toString();
            }
        }
    my template to see all:
    Code:
    <tpl for="data.keys"><b>{.}:</b> {data.values:get({.})}<br/></tpl>
    data.keys is a getter helper function on my data that returns a String[] of keys.

    Maybe you can use it. Good luck!

    Sebastiaan
    Last edited by sblommers; 28 Nov 2011 at 3:41 AM. Reason: Typo

  5. #5
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,734
    Vote Rating
    90
    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


    @sblommers, yes, that is the correct way to do this in GXT 3.

    @valery.stroeder It appears you've accidently posted in the 3.x discussion, though you seem to have a 2.x question. Short answer is that you have a JSNI method (Javascript as the body of a Java method), so need to take care when calling external java methods. See http://code.google.com/webtoolkit/do...I.html#calling for some specifics for your situation.

    Likely your resulting code will look like this:
    Code:
    private native String getTemplate(final Map<String, String> map) /*-{
        return [
            '<tpl for="."> ',
            '<div>', 
            map.@java.util.Map::get(Ljava/lang/Object;)("test"),
            '</div>',
            '</tpl>'
        ].join("");
    }-*/;
    It is possible that Ljava/lang/Object; should be Ljava/lang/String;, I haven't tested the code.

    If you have the Google Plugin for Eclipse installed (and are using eclipse), it can help by offering autocomplete when calling java methods from within javascript.

    p.s. When building an array and .join('')ing it, dont forget to skip the +'s, and just use commas. Doing so makes the string building faster in many browsers.

  6. #6
    Sencha User
    Join Date
    Nov 2009
    Posts
    71
    Vote Rating
    0
    valery.stroeder is on a distinguished road

      0  

    Default


    @blommers Thanks for your help.
    @Colin Alworth Thank you very much for this interesting information.

    In my case I need to
    • Add some non-selectable items («user input values» and «other values»)
    • For every item : display a key and its translation
    Finally I used a mix of 2 solutions
    • XTemplate for non-selectable items
    • ModelProcessor to display key and it's translation
    1) set a custom template to display non selectable items
    Code:
    combo.setTemplate(getCustomTemplate(CALCULATED_VALUES_OR_USER_INPUT_TEXT,   OTHER_POSSIBLE_VALUES_TEXT,  POSSIBLE_VALUES_SEPARATOR));
    2) add «user input» values in the comboBox store
    Code:
    combo.addValue("userInputA");
    combo.addValue("userInputB");
    3) add a separator text in the store to know when display the «other possible values» text
    Code:
    combo.addValue(POSSIBLE_VALUES_SEPARATOR);
    4) add «other possible» values in the comboBox store
    Code:
    combo.addValue("otherPossibleValueA");
    combo.addValue("otherPossibleValueB");
    5) Add a translation to the model
    Code:
    // Create a translation  property to use in the combo  template
                 this.getListView().setModelProcessor(new  ModelProcessor<SimpleComboValue<String>>()  {
                      @Override
                     public SimpleComboValue<String>  prepareData(SimpleComboValue<String> model)  {
                         if (!POSSIBLE_VALUES_SEPARATOR.equals(model.getValue()))  {
                             model.set("translation",  translate(model.getValue()));
                          }
                         return  model;
                      }
                 });
    6) the custom template
    Code:
    /**
              * Customize the field's drop menu  to
              * - display non selectable items like 'user input' and 'other available   values'
              * - display description if  available
               *
              * @param userInputValuesText      text that explain that following values are calculated or user  input
               * @param otherPossibleValuesText text that explain that following   values all possible values not contained in the previous  list
              * @param possibleValuesSeparator separator text used to know where to  place the  otherPossibleValuesText
               *                                 map containing menu item names and  descriptions
              * @return the XTemplate as HTML  string
              */
    private  native String getCustomTemplate(final String  userInputValuesText,  final String otherPossibleValuesText, final String   possibleValuesSeparator)  /*-{
                 return ['<div  class=\"text\" style=\"color:gray;  line-height:12pt;\">' +  userInputValuesText +  '</div>'  +
                         '<tpl for="."> '  +
                     // If separator text is found  then
                         '<tpl if="\'' + possibleValuesSeparator + '\' == value">'   +
                     // put a blank selectable and invisible item to respect store  order
                          '<div class=\"x-combo-list-item\" style=\"height:0; width:0;   position: absolute; top:0; right:0; text-indent:-20000px;   z-index:-1\"></div>'  +
                     // put a non-selectable text to separate «user input values» and «other  possible  values»
                          '<div class=\"text\" style=\"color:gray;  line-height:12pt;\">' +  otherPossibleValuesText +  '</div>'  +
                         '</tpl>'  +
                          '<tpl if="\'' + possibleValuesSeparator + '\' != value  &&  \'' + userInputValuesText + '\'!=null">'  +
                         '<div class=x-combo-list-item  qtip="{translation}">{value} - {translation}</div>'   +
                         '</tpl>'  +
                          '</tpl>'].join("");
             }-*/;
    7) Avoid the separator selection
    Code:
    // Avoid the otherPossibleValuesSeparator item  selection
                 this.addSelectionChangedListener(new  SelectionChangedListener<SimpleComboValue<String>>()   {
                      @Override
                     public void  selectionChanged(SelectionChangedEvent<SimpleComboValue<String>>  se)  {
                         if (POSSIBLE_VALUES_SEPARATOR.equals(se.getSelectedItem().getValue()))  {
                              setValue(null);
                          }
                      }
                 });
    I hope it could help someone else.
    Feel free to share some better solutions.