Search code examples
restcomboboxxpagestypeahead

xPages REST Service Results into Combobox or Typeahead Text Field


I've read all the documentation I can find and watched all the videos I can find and don't understand how to do this. I have set up an xPages REST Service and it works well. Now I want to place the results of the service into either a combobox or typeahead text field. Ideally I would like to know how to do it for both types of fields.

I have an application which has a view containing a list of countries, another view containing a list of states, and another containing a list of cities. I would like the first field to only display the countries field from the list of data it returns in the XPages REST Service. Then, depending upon which country was selected, I would like the states for that country to be listed in another field for selection, etc.

I can see code for calling the REST Service results from a button, or from a dojo grid, but I cannot find how to call it to populate either of the types of fields identified above.

Where would I call the Service for the field? I had thought it would go in the Data area, but perhaps I've just not found the right syntax to use.

November 6, 2017:

I have been following your suggestion, but am still lost as can be. Here's what I currently have in my code:

x$( "#{id:ApplCountry}" ).select2({
                        placeholder: "select a country",
                        minimumInputLength: 2,
                        allowClear : true,
                        multiple: false,
                        ajax: {
                            dataType: 'text/plain',
                            url: "./Application.xsp/gridData",
                            quietMillis: 250,
                        data: function (params) { 
                            return {  
                                search:'[name=]*'+params.term+'*',       
                                page: params.page
                            };
                        },
                        processResults: function (data, page) {
                            var data = $.map(data, function (obj) {
                            obj.id = obj.id || obj["@entityid"];
                            obj.text = obj.text || obj.name;
                            return obj;
                        });
                        },

            return {results: data};
        }
      }
});

I'm using the dataType of 'text/plain' because that was what I understood I should use when gathering data from a domino application. I have tried changing this to json but it makes no difference.

I'm using processResults because I understand this is what should be used in version 4 of select2.

I don't understand the whole use of the hidden field, so I've stayed away from that.

No matter what I do, although my REST service works if I put it directly in the url, I cannot get any data to display in the field. All I want to display in the field is the country code of the document, which is in the field named "name" (not my choice, it's how it came before I imported the data from MySQL.

I have read documentation and watched videos, but still don't really understand how everything fits together. That was my problem with the REST service. If you use it in Dojo, you just put the name of the service in a field on the Dojo element and it's done, so I don't understand why all the additional coding for another type of domino element. Shouldn't it work the same way?

I should point out that at some points it does display the default message, so it does find the field. Just doesn't display the country selections.


Solution

  • I think the issue may be that you are not returning SelectItems to your select2, and that is what it is expecting. When I do something like you are trying, I actually use a bean to generate the selection choices. You may want to try that or I'm putting in the working part of my bean below.

    The Utils.getItemValueAsString is a method I use to return either the string value of a field, or if it is not on the document/empty/null an empty string. I took out an if that doesn't relate to this, so there my be a mismatch, but I hope not.

    You might be able to jump directly to populating the arrayList, but as I recall I needed to leverage the LinkedHashMap for something.

    You should be able to do the same using SSJS, but since that renders to Java before executing, I find this more efficient.

    For label/value pairs:

    LinkedHashMap lhmap = new LinkedHashMap();
    
    Document doc = null;
                Document tmpDoc = null;
                allObjects.addElement(doc);
                if (dc.getCount() > 0) {
                    doc = dc.getFirstDocument();
                    while (doc != null) {
    
                            lhmap.put(Utils.getItemValueAsString(doc, LabelField, true), Utils.getItemValueAsString(doc, ValueField, true));
                        } 
    
                        tmpDoc = dc.getNextDocument(doc);
                        doc.recycle();
                        doc = tmpDoc;
                    }
    
                }
    
    
    List<SelectItem> options = new ArrayList<SelectItem>();
            Set set = lhmap.entrySet();
            Iterator hsItr = set.iterator();
            while (hsItr.hasNext()) {
                Map.Entry me = (Map.Entry) hsItr.next();
                // System.out.println("after: " + hStr);
                SelectItem option = new SelectItem();
    
                option.setLabel(me.getKey() + "");
                option.setValue(me.getValue() + "");
                options.add(option);
            }
            System.out.println("About to return from generating");
            return options;
        }