Wiki source code of AutoSuggest Widget

Version 48.1 by Sergiu Dumitriu on 2012/08/06

Hide last authors
Sergiu Dumitriu 48.1 1 {{velocity filter="none"}}
2 {{html clean="false" wiki="true"}}
Jerome 35.1 3 ##
4 ## TODO:
5 ## - Document the REST usage of the suggest (this is the recommanded way of using the suggest now - when possible)
6 ## - Merge the example document in this one (why are there 2 documents ?)
7 ## - Migrate this page to syntax 2.0
8 ##
ElenaOanaTabaranu 1.1 9 #startfloatingbox()
Sergiu Dumitriu 48.1 10 **Contents**
11
12 {{toc start="2" depth="2" numbered=""/}}
ElenaOanaTabaranu 1.1 13 #endfloatingbox()
Sergiu Dumitriu 48.1 14 <p/>
15 {{info}}This is a Javascript widget bundled by default with the XWiki platform.{{/info}}
ElenaOanaTabaranu 1.1 16
Sergiu Dumitriu 48.1 17 == Usage ==
ElenaOanaTabaranu 1.1 18
ElenaOanaTabaranu 14.1 19 The suggest widget can be triggered when typing something in a text field. The suggested list can contain field values from a class defined in your wiki or any custom information you provide.
20
Sergiu Dumitriu 48.1 21 === Suggest fields from a class defined in the wiki ===
ElenaOanaTabaranu 14.1 22
Sergiu Dumitriu 48.1 23 Use information from a predefined class in your wiki (e.g. **XWiki.TagClass**, **XWiki.XWikiUsers**, etc.) or from a class defined by yourself.
24 For example, use **XWiki.TagClass** to suggest tags from the wiki tag cloud:
25 <p/>
26 [[image:DevGuide.AutoSuggestWidget@suggest.png]]
ElenaOanaTabaranu 14.1 27
Sergiu Dumitriu 48.1 28 {{code}}
ElenaOanaTabaranu 7.1 29 $!xwiki.jsx.use("DevGuide.AutoSuggestWidgetExample")
ElenaOanaTabaranu 1.1 30 <form method="post" action="#">
31 <label for="myinput">Type the name of a tag and test the suggest list:</label>
32 <input id="myinput" size="20" type="text" value=""/>
33 </form>
Sergiu Dumitriu 48.1 34 {{/code}}
ElenaOanaTabaranu 1.1 35
Sergiu Dumitriu 48.1 36 The **JavascriptExtension** object from the **DevGuide.AutoSuggestWidgetExample** page contains the Javascript code to enable the widget when focusing on the text field:
ElenaOanaTabaranu 1.1 37
Sergiu Dumitriu 48.1 38 {{code}}
ElenaOanaTabaranu 1.1 39 (function(){
40 document.observe('dom:loaded', function () {
41 if($('myinput')) {
42 Event.observe($('myinput'), "focus", function() {
Jerome 34.1 43 new XWiki.widgets.Suggest(this, {
44 script: '$xwiki.getURL("${doc.space}.WebHome", "view")?xpage=suggest&classname=XWiki.TagClass&fieldname=tags&secCol=-&',
45 varname: "input",
46 seps: " ,|",
47 offsety: 13
48 });
ElenaOanaTabaranu 1.1 49 });
50 }
51 }); // end of doc observe
52 })();
Sergiu Dumitriu 48.1 53 {{/code}}
ElenaOanaTabaranu 1.1 54
Sergiu Dumitriu 48.1 55 ==== Options used in the **suggest.vm** template: ====
ElenaOanaTabaranu 17.1 56
Sergiu Dumitriu 48.1 57 |=Option|=Details
58 |xpage|Must use **xpage=suggest** because suggest.vm template is used to manage the request.
59 |classname|The name of the class for the elements of the suggest list.
60 |fieldname|The field name from the class considered for the suggest list.
61 |firCol|First column of the list of results.
62 |secCol|Second column of the list of results. For a user defined query, use **-** value for one column and no hidden input. Otherwise the list of results will have two columns and a hidden input.
ElenaOanaTabaranu 17.1 63
Sergiu Dumitriu 48.1 64 ==== Example ====
ElenaOanaTabaranu 17.1 65
Sergiu Dumitriu 48.1 66 * Check out the example for class field values at [[Class Field Example>>DevGuide.AutoSuggestWidgetExample]]
ElenaOanaTabaranu 18.1 67
Sergiu Dumitriu 48.1 68 === Suggest custom information ===
ElenaOanaTabaranu 1.1 69
Sergiu Dumitriu 48.1 70 When the information you want to suggest is not available through a class field or you generate it using a custom query, you need to create a service (plain wiki page called with the **get** action and with **outputSyntax=plain** parameter in the url, eg: //xwiki/bin/get/Space/Page?outputSyntax=plain//) that maps your results to the **xml** input accepted by the **autosuggest** class.
ElenaOanaTabaranu 14.1 71 For example, you can build a list of suggestions that contains the wiki page names within a certain space:
Sergiu Dumitriu 48.1 72 <p/>
73 [[image:DevGuide.AutoSuggestWidget@customsuggest.png]]
ElenaOanaTabaranu 30.1 74
Sergiu Dumitriu 48.1 75 {{code}}
ElenaOanaTabaranu 15.1 76 $!xwiki.jsx.use("DevGuide.AjaxSuggestCustomExample")
ElenaOanaTabaranu 14.1 77 <form method="post" action="#">
ElenaOanaTabaranu 19.1 78 <label for="myinput">Type the name of an example page from the *DevGuide* space and test the suggest list:</label>
Raluca Stavro 31.1 79 <input id="myinput_suggest" size="20" type="text" value=""/>
80 <input id="myinput" type="hidden" />
81 <input id="mybutton" type="button" value="Go" /><br/>
ElenaOanaTabaranu 14.1 82 </form>
Sergiu Dumitriu 48.1 83 {{/code}}
ElenaOanaTabaranu 14.1 84
Sergiu Dumitriu 48.1 85 The **JavascriptExtension** object from the **DevGuide.AjaxSuggestCustomExample** page contains the Javascript code to enable the widget when focusing on the text field. Also, the **script** option uses the url for the results page.
ElenaOanaTabaranu 14.1 86
Sergiu Dumitriu 48.1 87 {{code}}
ElenaOanaTabaranu 14.1 88 (function(){
89 document.observe('dom:loaded', function () {
Raluca Stavro 31.1 90 if($('myinput_suggest')) {
91 Event.observe($('myinput_suggest'), "focus", function() {
Jerome 34.1 92 new XWiki.widgets.Suggest(this, {
Guillaume Delhumeau 47.1 93 script: "$xwiki.getURL("DevGuide.SuggestService", "get", "outputSyntax=plain&spacename=DevGuide")&",
Jerome 33.1 94 varname: "input",
95 seps: " ,|",
96 offsety: 13,
97 minchars: 3
98 });
ElenaOanaTabaranu 14.1 99 });
100 }
101 }); // end of doc observe
102 })();
Sergiu Dumitriu 48.1 103 {{/code}}
104
105 The service page uses a query to get all the pages from the space provided using **spacename** parameter in the url. The generated response must be a **xml** file that has **<results>** as a root node and **<rs>** as children.
106
107 {{code}}
ElenaOanaTabaranu 14.1 108 ##
109 ## Service to generate the suggest list of files from a certain space.
110 ## @spacename
111 ## @input
112 ##
113 #set($input = $request.get("input").toLowerCase())
114 #set($spacename = $request.get("spacename"))
115 $response.setContentType("text/xml") ## generate a xml file
116 ## select pages
117 #if("$!input" == "")
Raluca Stavro 31.1 118 #set($query = "where doc.space='$spacename' and doc.name<>'WebHome' and doc.name<>'WebPreferences' order by doc.date desc")
ElenaOanaTabaranu 14.1 119 #else
Raluca Stavro 31.1 120 #set($query = "where doc.space='$spacename' and doc.name<>'WebHome' and doc.name<>'WebPreferences' and lower(doc.name) like '%" + $input + "%' order by doc.date desc")
ElenaOanaTabaranu 14.1 121 #end
Raluca Stavro 31.1 122 #set($searchresults = $xwiki.searchDocuments($query, 30, 0))
ElenaOanaTabaranu 14.1 123 <results space="$spacename">
124 #foreach($result in $searchresults)
Raluca Stavro 31.1 125 #set($resultDoc = $xwiki.getDocument($result))
126 #set($resultDocName = $resultDoc.name)
127 #set($resultDocURL = $resultDoc.getURL())
128 <rs id="1" info="$resultDocURL">$resultDocName</rs>
ElenaOanaTabaranu 14.1 129 #end
130 </results>
Sergiu Dumitriu 48.1 131 {{/code}}
ElenaOanaTabaranu 17.1 132
MensoHeus 45.1 133 To provide autosuggest to several elements on the form, you can use JavaScript to loop through all the form elements and provide autosuggest if they meet certain conditions. In the example below, if there are form elements with id 'Supplier' in the 'inline' form, they get assigned an autosuggest that uses the Suppliers space as its source. If the element id matches 'Product' the autosuggest is told to use the 'Products' space as it's source instead.
Sergiu Dumitriu 48.1 134 <p/>
MensoHeus 45.1 135 This method can be very useful when a form contains a lot of similar elements that require autosuggest. If you make sure the naming is done consistently, you can also use javascript to assign autosuggest based on part of the element id, for example 'all elements ending with _foo' or 'all elements starting with Bar_'. You can use the velocity code from the example above with the code below.
136
Sergiu Dumitriu 48.1 137 {{code}}
MensoHeus 45.1 138 (function(){
139 document.observe('dom:loaded', function () {
140 myForm = document.getElementById('inline').elements;
141 for(i=0; i<myForm.length; i++){
142 if(myForm[i].id =='Supplier'){
143 mySuggest(myForm[i], 'Suppliers');
144 }
145 if(myForm[i].id=='Product'){
146 mySuggest(myForm[i], 'Products');
147 }
148 }
149 }); // end of doc observe
150 })();
151
152 function mySuggest(element, space) {
153 if (!element.suggest) {
154 element.suggest = new XWiki.widgets.Suggest(element, {
Guillaume Delhumeau 47.1 155 script: "$xwiki.getURL("Sandbox.AutoSuggest", "get")"+ "?outputSyntax=plain&spacename="+space+"&",
MensoHeus 45.1 156 varname: "input",
157 seps: " ,|",
158 offsety: 13,
159 minchars: 1
160 });
161 }
162 }
Sergiu Dumitriu 48.1 163 {{/code}}
MensoHeus 45.1 164
Sergiu Dumitriu 48.1 165 ==== Example ====
ElenaOanaTabaranu 18.1 166
Sergiu Dumitriu 48.1 167 * Check out the example for custom information at [[Custom Information Example>>DevGuide.AjaxSuggestCustomExample]]
ElenaOanaTabaranu 18.1 168
Sergiu Dumitriu 48.1 169 === Suggest Users or Groups from the wiki ===
Oana Florea 38.1 170
Sergiu Dumitriu 48.1 171 Local or global users and groups from the wiki can be suggested using the **uorgsuggest.vm** template.
172 <p/>
Oana Florea 38.1 173 Example:
Sergiu Dumitriu 48.1 174 <p/>
Oana Florea 38.1 175 $xwiki.jsx.use("$doc.fullName")##
176
177 <input name="userInput" id="userInput" value="" type="text"/>
Sergiu Dumitriu 48.1 178 <p/>
Oana Florea 44.1 179 Here is the code that made the suggestion of global users from the wiki possible:
Oana Florea 38.1 180
Sergiu Dumitriu 48.1 181 {{code}}
Oana Florea 38.1 182 ...
183 <input name="userInput" id="userInput" value="" type="text"/>
184 ...
Sergiu Dumitriu 48.1 185 {{/code}}
Oana Florea 38.1 186
Sergiu Dumitriu 48.1 187 {{code}}
Oana Florea 38.1 188 (function(){
189 document.observe('dom:loaded', function () {
190 if($('userInput')) {
191 Event.observe($('userInput'), "focus", function() {
192 new XWiki.widgets.Suggest(this, {
Oana Florea 43.1 193 script: '$xwiki.getURL("${doc.fullName}", "view")?xpage=uorgsuggest&classname=XWiki.XWikiUsers&wiki=global&uorg=user&',
Oana Florea 38.1 194 varname: "input",
195 seps: " ,|",
196 delay : 200,
197 timeout: 5000,
198 offsety: 13
199 });
200 });
201 }
202 }); // end of doc observe
203 })();
Sergiu Dumitriu 48.1 204 {{/code}}
Oana Florea 38.1 205
Sergiu Dumitriu 48.1 206 == Javascript parameters for the **ajaxsuggest** class ==
ElenaOanaTabaranu 1.1 207
Sergiu Dumitriu 48.1 208 |=Parameter|=Details
209 |minchars|The minimum number of characters after which to trigger the suggest. Default value is 1.
210 |get|The HTTP method for the AJAX request.
211 |varname|The name of the request parameter holding the input stub. Default value is **input**.
212 |className|The CSS classname of the suggest list. Default value is **ajaxsuggest**.
213 |timeout|Default value is **2500**.
214 |delay|Default value is **500**.
215 |offsety|Default value is **-5**.
216 |shownoresults|Display a "no results" message, or simply hide the suggest box when no suggestions are available.
217 |noresults|Default displayed message is **No results!**.
218 |maxheight|Default value is **250**.
219 |cache|Default value is **false**.
220 |seps|Default value is "".
221 |resultsParameter|The name of the JSON variable or XML element holding the results.Default value is **results** for the old suggest, **searchResults** for the REST search.
222 |resultId|The name of the JSON parameter or XML attribute holding the result identifier. DEfault value is **id** for both the old suggest and the REST search.
223 |resultValue|The name of the JSON parameter or XML attribute holding the result value.Default **value** for the old suggest, **pageFullName** for the REST page search.
224 |resultInfo|The name of the JSON parameter or XML attribute holding the result auxiliary information. Default value is **info** for the old suggest, **pageFullName** for the REST search.
225 |parentContainer|The id of the element that will hold the suggest element. Default value is **body**.
226 |script|Url for the ajax request that will get the suggested list. Must end with **&** because **varname** parameter will be appended. Use **suggest.vm** to get field values from a wiki class or a custom url to generate the suggested list.
ElenaOanaTabaranu 1.1 227
Sergiu Dumitriu 48.1 228 == Tips ==
ElenaOanaTabaranu 1.1 229
Sergiu Dumitriu 48.1 230 * Suggest event: **xwiki:suggest:selected**
ElenaOanaTabaranu 1.1 231
Sergiu Dumitriu 48.1 232 {{code}}
233 Event.observe($('myInput'), "xwiki:suggest:selected", function(event) {
Oana Florea 46.1 234 // do something with event.memo.value or event.memo.id or event.memo.info ...
235 });
Sergiu Dumitriu 48.1 236 {{/code}}
237
Oana Florea 37.1 238 * Check out the code:
Sergiu Dumitriu 48.1 239 ** for your wiki instance: **{{{http://localhost:8080/xwiki/resources/js/xwiki/suggest/ajaxSuggest.js}}}**.
240 ** the suggest resources on svn(for exemple tag xwiki-web-2.2): [[http://svn.xwiki.org/svnroot/xwiki/platform/web/tags/xwiki-web-2.2/standard/src/main/webapp/resources/js/xwiki/suggest/]]
Oana Florea 36.1 241
Sergiu Dumitriu 48.1 242 == Bugs we know about ==
243
244 * The suggest feature will not work if the page called by the widget is not saved with programming rights: see details on [[http://jira.xwiki.org/jira/browse/XE-539]].
245 <p/>
246
247 {{/html}}
248 {{/velocity}}

Get Connected