Wiki source code of AutoSuggest Widget

Version 48.1 by Sergiu Dumitriu on 2012/08/06

Show last authors
1 {{velocity filter="none"}}
2 {{html clean="false" wiki="true"}}
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 ##
9 #startfloatingbox()
10 **Contents**
11
12 {{toc start="2" depth="2" numbered=""/}}
13 #endfloatingbox()
14 <p/>
15 {{info}}This is a Javascript widget bundled by default with the XWiki platform.{{/info}}
16
17 == Usage ==
18
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
21 === Suggest fields from a class defined in the wiki ===
22
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:[email protected]]]
27
28 {{code}}
29 $!xwiki.jsx.use("DevGuide.AutoSuggestWidgetExample")
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>
34 {{/code}}
35
36 The **JavascriptExtension** object from the **DevGuide.AutoSuggestWidgetExample** page contains the Javascript code to enable the widget when focusing on the text field:
37
38 {{code}}
39 (function(){
40 document.observe('dom:loaded', function () {
41 if($('myinput')) {
42 Event.observe($('myinput'), "focus", function() {
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 });
49 });
50 }
51 }); // end of doc observe
52 })();
53 {{/code}}
54
55 ==== Options used in the **suggest.vm** template: ====
56
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.
63
64 ==== Example ====
65
66 * Check out the example for class field values at [[Class Field Example>>DevGuide.AutoSuggestWidgetExample]]
67
68 === Suggest custom information ===
69
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.
71 For example, you can build a list of suggestions that contains the wiki page names within a certain space:
72 <p/>
73 [[image:[email protected]]]
74
75 {{code}}
76 $!xwiki.jsx.use("DevGuide.AjaxSuggestCustomExample")
77 <form method="post" action="#">
78 <label for="myinput">Type the name of an example page from the *DevGuide* space and test the suggest list:</label>
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/>
82 </form>
83 {{/code}}
84
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.
86
87 {{code}}
88 (function(){
89 document.observe('dom:loaded', function () {
90 if($('myinput_suggest')) {
91 Event.observe($('myinput_suggest'), "focus", function() {
92 new XWiki.widgets.Suggest(this, {
93 script: "$xwiki.getURL("DevGuide.SuggestService", "get", "outputSyntax=plain&spacename=DevGuide")&",
94 varname: "input",
95 seps: " ,|",
96 offsety: 13,
97 minchars: 3
98 });
99 });
100 }
101 }); // end of doc observe
102 })();
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}}
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" == "")
118 #set($query = "where doc.space='$spacename' and doc.name<>'WebHome' and doc.name<>'WebPreferences' order by doc.date desc")
119 #else
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")
121 #end
122 #set($searchresults = $xwiki.searchDocuments($query, 30, 0))
123 <results space="$spacename">
124 #foreach($result in $searchresults)
125 #set($resultDoc = $xwiki.getDocument($result))
126 #set($resultDocName = $resultDoc.name)
127 #set($resultDocURL = $resultDoc.getURL())
128 <rs id="1" info="$resultDocURL">$resultDocName</rs>
129 #end
130 </results>
131 {{/code}}
132
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.
134 <p/>
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
137 {{code}}
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, {
155 script: "$xwiki.getURL("Sandbox.AutoSuggest", "get")"+ "?outputSyntax=plain&spacename="+space+"&",
156 varname: "input",
157 seps: " ,|",
158 offsety: 13,
159 minchars: 1
160 });
161 }
162 }
163 {{/code}}
164
165 ==== Example ====
166
167 * Check out the example for custom information at [[Custom Information Example>>DevGuide.AjaxSuggestCustomExample]]
168
169 === Suggest Users or Groups from the wiki ===
170
171 Local or global users and groups from the wiki can be suggested using the **uorgsuggest.vm** template.
172 <p/>
173 Example:
174 <p/>
175 $xwiki.jsx.use("$doc.fullName")##
176
177 <input name="userInput" id="userInput" value="" type="text"/>
178 <p/>
179 Here is the code that made the suggestion of global users from the wiki possible:
180
181 {{code}}
182 ...
183 <input name="userInput" id="userInput" value="" type="text"/>
184 ...
185 {{/code}}
186
187 {{code}}
188 (function(){
189 document.observe('dom:loaded', function () {
190 if($('userInput')) {
191 Event.observe($('userInput'), "focus", function() {
192 new XWiki.widgets.Suggest(this, {
193 script: '$xwiki.getURL("${doc.fullName}", "view")?xpage=uorgsuggest&classname=XWiki.XWikiUsers&wiki=global&uorg=user&',
194 varname: "input",
195 seps: " ,|",
196 delay : 200,
197 timeout: 5000,
198 offsety: 13
199 });
200 });
201 }
202 }); // end of doc observe
203 })();
204 {{/code}}
205
206 == Javascript parameters for the **ajaxsuggest** class ==
207
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.
227
228 == Tips ==
229
230 * Suggest event: **xwiki:suggest:selected**
231
232 {{code}}
233 Event.observe($('myInput'), "xwiki:suggest:selected", function(event) {
234 // do something with event.memo.value or event.memo.id or event.memo.info ...
235 });
236 {{/code}}
237
238 * Check out the code:
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/]]
241
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