Suggest Widget

The Suggest Widget is bundled with XWiki and it is triggered when typing something in a text field. The list of suggested results is retrieved from:

  • a wiki class
  • a custom document
  • a REST resource

Auto-Suggest Using a Custom Document

In order to use an auto-suggest input field, you first need to create a wiki page containing that input field, for instance "Code.SuggestWidgetTest". The HTML code inside the page would be:

{{velocity}}

(((
{{html}}
<form>
Input: <input type="text" id="suggestWidget" class="withTip"/>
</form>
{{/html}}
)))

{{/velocity}}

The ID of the HTML input is very important because it will be used to bind the text field to the auto-suggest widget. This can be done by using an "XWiki.JavaScriptExtension" object. The "Code" text area will contain the lines below:

document.observe("xwiki:dom:loaded", function(){
  var myInput = $('suggestWidget');
 // Create the suggest widget by instantiating XWiki.widgets.Suggest
  var mySuggest = new XWiki.widgets.Suggest(myInput, {
    script: "$xwiki.getURL('Code.SuggestWidgetTestService', 'get', 'outputSyntax=plain')&",
    varname: "q",
    icon: "$xwiki.getSkinFile('icons/silk/page_white_picture.gif')",
    noresults: "No results",
    json: true,
    resultsParameter : "results",
    resultValue : "value",
  });
});

where:

  • var myInput = $('suggestWidget'); retrieves the input text element by using its ID. Should the ID change in the HTML, it must also be changed here.
  • script is the URL end-point that will provide suggestions and it points to data source. In case you want to retrieve field values from an XWiki class or a custom URL to generate the suggested list, you can use the "/xwiki/templates/suggest.vm" template.
  • varname is the name of the request variable on which to pass the text fragment specified by the user. This query parameter can be used by the script to retrieve what has been typed in the text input and use it to compute the results. The query parameter is appended to the script URL, which makes it very important for the script parameter to end with the & character in case additional query parameters are specified. The default value is input.
  • icon is used to display an small icon with the passed URL, next to each suggestion.
  • noresults is the default displayed message when shownoresults is enabled and when there are no results to display.
  • The json: true attribute states whether the output of the data source will be in the JSON format.
  • resultsParameter and resultValue are used to bind the returned JSON structure to the relevant information to be displayed. The returned JSON should be a map that contains a field whose name is the one specified by the resultsParameter attribute. This field should contain an array where each element is a map with several fields, including the one specified by the resultValue attribute. 

For resultsParameter the accepted values are:

  • results for XML results.
  • searchResults for the REST search.

For resultValue the accepted values are:

  • value for the old suggest.
  • pageFullName for the REST search.

Other Options for the XWiki.widgets.Suggest Constructor

  • cssClass is the name of the CSS class used by the suggest list. The default value is ajaxsuggest.
  • cache is a flag stating whether to cache the list suggestions returned for a specific input for the lifetime of the current page. The default value is false.
  • delay is the time in milliseconds stating how much to wait after a key press before requesting suggestions from the server. The default value is 500.
  • hideButton controls whether a "hide suggestions" button (or 2) is displayed or not. If used, it must be a map with two possible keys:
    • hideButton.positions is an array specifying where to place the hide buttons. The accepted values are top and bottom.
    • hideButton.text is the text that should be displayed.
  • highlight is a flag stating whether the results fragments should be highlighted when matching the typed input. The default value is true.
  • method is the HTTP method for the AJAX request. The default value is get.
  • minChars is the minimum number of characters after which to trigger the suggest. The default value is 1.
  • offsety in the value in pixels representing how much to shift the list of suggestions vertically from the normal position. The reason is to allow the user to add decorations between the input and the list. The default value is 0.
  • parentContainer is the id of the element that will hold the suggest element which is useful when the enhanced input is not statically positioned. The default value is body.
  • propagateEventKeyCodes is a sub-list of key codes computed from the list of keys handled by the widget for which to propagate the keyboard event. This option is useful when another keyboard event listener exists on the input field, even if it may be registered at a different level. The default value is empty list, meaning that none of the handled key events propagate.
  • resultId is the name of the JSON parameter or the XML attribute holding the result identifier. The default value is id.
  • resultsInfo is the name of the JSON parameter or the XML attribute holding the result auxiliary information. The accepted values are:
    • info for the old suggest.
    • pageFullName for the REST search.
  • seps: in case suggestions should be returned for each token instead of the full text in the input, seps should be set to a list of characters that should be used for splitting the input into tokens. If you would rather use the whole text instead, this parameter should be left empty (the default value).
  • shownoresults is a flag stating what to do when no results match the current input: either display a "no results" message when the flag is set to true or hide the suggest box in case no suggestions are available. The default value is true.
  • sources is an array of sources from where to fetch suggestions. If the array is not empty, then the suggest will function in multi-source mode. Every entry should be a map and the parameters should be used as keys in every such map instead of keys in the global options. By default the suggest is in single-source mode.
  • timeout is the time in milliseconds stating for how long to display the list of suggestions. In case the user doesn't select any of the suggestions before the timeout expires, the list will be cleared. The default value is 2500.

Create a Script Service

Finally, you have to create a script service that should be made available at the URL specified by the script attribute of the above JavaScript extension. The service will be available at the get address of the page "Code.SuggestWidgetTestService", i.e. /xwiki/bin/get/Code/SuggestWidgetTestService?outputSyntax=plain which will contain the code below (in "xwiki/2.0" syntax):

{{groovy}}
import groovy.json.JsonOutput;

response.setContentType("application/json");

m = [ "results" :
 [
   [ "value" : "Empty document" ],
   [ "value" : "Page template" ],
   [ "value" : "Space Dashboard" ],
 ]
]

print JsonOutput.toJson(m);
{{/groovy}}

If you then refresh the page "Code.SuggestWidgetTest" and type something in the input, you should see the following screen:

SuggestWidgetService.png

Auto-Suggest from the XWiki List of Users and Groups

In order to have an auto-suggest from the list of users and groups (both local and global) you can use the xwiki/templates/uorgsuggest.vm template. First, you need to create a wiki page containing that input field as explained in the above section:

{{velocity}}

(((
{{html}}
<form>
Input: <input type="text" id="suggestWidgetUsersGroups" class="withTip"/>
</form>
{{/html}}
)))

{{/velocity}}

The next step is to bind the input field to the auto-suggest wigdet by using an "XWiki.JavaScriptExtension" object. The "Code" text-area will contain the code below:

(function(){
 document.observe('dom:loaded', function () {
   if($('suggestWidgetUsersGroups')) {
      Event.observe($('suggestWidgetUsersGroups'), "focus", function() {
       new XWiki.widgets.Suggest(this, {
              script: '$xwiki.getURL("${doc.fullName}", "view")?xpage=uorgsuggest&classname=XWiki.XWikiUsers&wiki=global&uorg=user&',
             varname: "input",
             seps: " ,|",
             delay : 200,
             timeout: 5000,
             offsety: 13
        });
      });
    }
  }); // end of doc observe
})();

The final result should be: 

SuggestWidgetUsersGroups.png

Auto-Suggest Using the suggest.vm Template

You can use the "/xwiki/templates/suggest.vm" template when you need to have an auto-suggest from an XWiki class (except for the "XWiki.XWikiUsers" class which is presented in the above paragraph) or even from your custom class. Supposing you want to retrieve all the wiki pretty names, the HTML input would be:

{{velocity}}

(((
{{html}}
<form>
Input: <input type="text" id="suggestWidgetWikis" name="suggestWidgetWikis" />
</form>
{{/html}}
)))

{{/velocity}}

The code for the JavaScript Extension will be:

(function(){
 document.observe('dom:loaded', function () {
   if($('suggestWidgetWikis')) {
      Event.observe($('suggestWidgetWikis'), "focus", function() {
       new XWiki.widgets.Suggest(this, {
             script: '$xwiki.getURL("${doc.space}.WebHome", "view")?xpage=suggest&classname=XWiki.XWikiServerClass&fieldname=wikiprettyname&secCol=-&',
             varname: "input",
             seps: " ,|",
             offsety: 13,
             icon: "$xwiki.getSkinFile('icons/silk/arrow_right.gif')"
        });
      });
    }
  }); // end of doc observe
})();

where:

  • classname is the name of the class for the elements of the suggest list ("XWiki.XWikiServerClass" in our case).
  • fieldname is the name of the class property used for the suggest list.
  • secCol is the second column of the list of results. For a user defined query, use - for one column and no hidden input. Otherwise the list of results will have two columns and a hidden input.

The result will then be:

SuggestWidgetWikis.png

Auto-Suggest Using a Custom Query

Supposing you need to remove a particular result from the displayed list, like for instance the "Wiki Template", you won't be able to use "suggest.vm" anymore. The solution is to create a script service that should be made available at the URL specified by the script attribute of the JavaScript extension. For this particular example, the service will be available at the get address of the page "Code.SuggestWidgetWikisService":

{{velocity}}
$response.setContentType("text/xml")
#set($query = "SELECT prop.value FROM XWikiDocument as doc, BaseObject as obj, StringProperty prop WHERE doc.fullName=obj.name
 AND obj.className='XWiki.XWikiServerClass' AND doc.name NOT IN ('XWikiServerTemplatewiki', 'XWikiServerClassTemplate')
 AND prop.id.id=obj.id AND prop.name='wikiprettyname' ORDER by prop.value desc"
)
#set($results = $xwiki.search($query, 0, 0))
<?xml version="1.0" encoding="UTF-8"?>
   <results type="8">
   #foreach($res in $results)
     <rs id="$velocityCount" info="">$!{escapetool.xml($res)}</rs>
   #end
   </results>
{{/velocity}}

The generated response must be an XML file that has <results> as a root node and <rs> as children.

The JavaScript extension code will then become:

(function(){
 document.observe('dom:loaded', function () {
  if($('suggestWidgetWikis')) {
      Event.observe($('suggestWidgetWikis'), "focus", function() {
       new XWiki.widgets.Suggest(this, {
             script: '$xwiki.getURL('Code.SuggestWidgetWikisService', 'get', 'outputSyntax=plain')&',
             varname: "input",
             seps: " ,|",
             offsety: 13,
             icon: "$xwiki.getSkinFile('
icons/silk/arrow_right.gif')"
        });
      });
    }
  }); // end of doc observe
})();

The final result, without "XWikiServerTemplatewiki" and "XWikiServerClassTemplate" will be:

SuggestWidgetWikisCustomQuery.png

Related Pages

Search this space

 

Most popular tags

Failed to execute the [groovy] macro
  1. access rights
  2. activity stream
  3. annotation
  4. attachment
  5. comment
  6. Document Tree Macro
  7. export
  8. Extension Manager
  9. Flamingo skin
  10. global user
  11. Groovy event listener
  12. group
  13. nested page
  14. search
  15. skin
  16. syntax
  17. user
  18. user profile
  19. velocity macros
  20. wiki
  21. wysiwyg
  22. XWiki Applications
  23. xwikiattachment_archive table
  24. xwikiattachment table
  25. xwikiattrecyclebin table
  26. xwikiproperties table

[Display all tags from this space]