<section role="NotInToc" id="rich_suggestionbox">
	<title>
		&lt;
		rich:suggestionbox
		&gt;
		<emphasis role="since">
			<superscript>
				available since
				<emphasis role="version">3.0.0</emphasis>
			</superscript>
		</emphasis>
	</title>
	<section>
		<title>Description</title>
		<para>
			The component adds on-keypress suggestions capabilities to any input
			text component
			like
			<emphasis role="bold">
				<property>&lt;h:inputText&gt;</property>
			</emphasis>
			.
		</para>
		<figure>
			<title>
				<emphasis role="bold">
					<property>&lt;rich:suggestionbox&gt;</property>
				</emphasis>
				component
			</title>
			<mediaobject>
				<imageobject>
					<imagedata fileref="images/suggestionbox_init.png" />
				</imageobject>
			</mediaobject>
		</figure>
	</section>
	<section>
		<title>Key Features</title>
		<itemizedlist>
			<listitem>
				<para>
					Adds
					<emphasis>
						<property>"onkeypress"</property>
					</emphasis>
					suggestions capabilities to any input text component
				</para>
			</listitem>
			<listitem>
				<para>Possible to render table as a popup suggestion</para>
			</listitem>
			<listitem>
				<para>Can be pointed to any Ajax request status indicator of the
					page</para>
			</listitem>
			<listitem>
				<para>Easily customizable look-and-feel</para>
			</listitem>
			<listitem>
				<para>Fully skinnable component</para>
			</listitem>
			<listitem>
				<para>Managing area of components submitted on Ajax request</para>
			</listitem>
			<listitem>
				<para>Flexible list of components to update after Ajax request
					managed by attributes</para>
			</listitem>
			<listitem>
				<para>Setting restriction to Ajax request generation</para>
			</listitem>
			<listitem>
				<para>Keyboard navigation support</para>
			</listitem>
		</itemizedlist>
	</section>
	<section>
		<title>Details of Usage</title>

		<section>
			<title>Main attributes</title>
			<para>There are 3 main component attributes:</para>
			<itemizedlist>
				<listitem>
					<para>
						<emphasis>
							<property>"for"</property>
						</emphasis>
						contains an ID of an input component
						for which the suggestion
						support is provided
					</para>
				</listitem>
				<listitem>
					<para>
						<emphasis>
							<property>"suggestionAction"</property>
						</emphasis>
						defines the method to get a collection of suggestion data on
						request
					</para>
				</listitem>
				<listitem>
					<para>
						<emphasis>
							<property>"var"</property>
						</emphasis>
						defines a collection name that provides an access for the current
						row while iterating through
					</para>
				</listitem>
			</itemizedlist>
			<para>To create the simplest variant on a page use the following
				syntax:</para>
			<programlisting role="XML"><![CDATA[...
				<h:inputText id="city" value="#{capitalsBean.capital}" />
				<rich:suggestionbox for="city" var="result"
				suggestionAction="#{capitalsBean.autocomplete}">
				<h:column>
				<h:outputText value="#{result.name}" />
				</h:column>
				</rich:suggestionbox>
				...
]]></programlisting>
			<para>
				There is a managed bean:
			</para>
			<programlisting role="JAVA"><![CDATA[...
				public class SBbean {

				private ArrayList&lt;Capital&gt; capitals = new ArrayList&lt;Capital&gt;();
				private ArrayList&lt;String&gt; capitalsNames = new
				ArrayList&lt;String&gt;();
				private List&lt;SelectItem&gt; capitalsOptions = new
				ArrayList&lt;SelectItem&gt;();
				private String capital = "";

				public List&lt;Capital&gt; autocomplete(Object suggest) {
				String pref = (String) suggest;
				ArrayList&lt;Capital&gt; result = new ArrayList&lt;Capital&gt;();

				Iterator&lt;Capital&gt; iterator = getCapitals().iterator();
				while (iterator.hasNext()) {
				Capital elem = ((Capital) iterator.next());
				if ((elem.getName() != null &amp;&amp; elem.getName().toLowerCase()
				.indexOf(pref.toLowerCase()) == 0)
				|| "".equals(pref)) {
				result.add(elem);
				}
				}
				return result;
				}

				public SBbean() {
				URL rulesUrl = getClass().getResource("capitals-rules.xml");
				Digester digester = DigesterLoader.createDigester(rulesUrl);
				digester.push(this);
				try {
				digester.parse(getClass().getResourceAsStream("capitals.xml"));
				} catch (IOException e) {
				throw new FacesException(e);
				} catch (SAXException e) {
				throw new FacesException(e);
				}
				capitalsNames.clear();
				for (Capital cap : capitals) {
				capitalsNames.add(cap.getName());
				}
				capitalsOptions.clear();
				for (Capital cap : capitals) {
				capitalsOptions.add(new SelectItem(cap.getName(), cap.getState()));
				}
				}

				public String addCapital(Capital capital) {
				capitals.add(capital);
				return null;
				}
				}	
]]></programlisting>
			<para>
				In the example above when suggestion item (city) is selected it is
				set as a value of
				<code>&lt;h:inputText id="city"/&gt;</code>
				.
			</para>
			<para>
				Here is a result:
			</para>
			<figure>
				<title>
					<emphasis role="bold">
						Simple
						<property>&lt;rich:suggestionbox&gt;</property>
					</emphasis>
				</title>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/suggestionbox_simple.png" />
					</imageobject>
				</mediaobject>
			</figure>

			<para>
				The
				<emphasis role="bold">
					<property>&lt;rich:suggestionbox&gt;</property>
				</emphasis>
				component could get any collection
				and outputs it in a
				popup in
				several columns. The
				<emphasis>
					<property>"fetchValue"</property>
				</emphasis>
				attribute points to the data that is inserted into the input field
				if a particular row is selected
				or clicked from the suggested list.
				Therefore when some string is chosen input
				receives the proper value.
			</para>
			<programlisting role="XML"><![CDATA[...
				<h:inputText id="city" value="#{capitalsBean.capital}" />
				<rich:suggestionbox for="city" var="result"
				fetchValue="#{result.state}"
				suggestionAction="#{capitalsBean.autocomplete}">
				<h:column>
				<h:outputText value="#{result.name}" />
				</h:column>
				<h:column>
				<h:outputText value="#{result.state}" />
				</h:column>
				</rich:suggestionbox>
				...
]]></programlisting>
			<para>
				In the example above if you choose any string input will receive the
				corresponding value
				from the second column containing
				<code>#{result.state}</code>
				.
			</para>
			<para>Here is a result:</para>
			<figure>
				<title>
					<emphasis role="bold">
						<property>&lt;rich:suggestionbox&gt;</property>
					</emphasis>
					with output in several columns
				</title>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/suggestionbox2.png" />
					</imageobject>
				</mediaobject>
			</figure>
			<para>
				There is also one more important attribute named
				<emphasis>
					<property>"tokens"</property>
				</emphasis>
				that specifies separators after which a set of some
				characters
				sequence is defined as a new prefix beginning from this
				separator and
				not from the string beginning.
			</para>
			<para>
				<emphasis role="bold">Example:</emphasis>
			</para>
			<programlisting role="XML"><![CDATA[...
				<h:inputText id="city" value="#{capitalsBean.capital}" />
				<rich:suggestionbox for="city" var="result"
				suggestionAction="#{capitalsBean.autocomplete}"
				tokens=",">
				<h:column>
				<h:outputText value="#{result.name}" />
				</h:column>
				</rich:suggestionbox>
				...
]]></programlisting>
			<para>This example shows that when a city is chosen and a comma and
				first letter
				character are input, Ajax request is called again, but
				it
				submits a
				value starting from the last token:</para>
			<figure>
				<title>
					<emphasis role="bold">
						<property>&lt;rich:suggestionbox&gt;</property>
					</emphasis>
					with chosen word
				</title>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/suggestionbox3.png" />
					</imageobject>
				</mediaobject>
			</figure>
			<para>
				For
				a multiple definition use either "
				<code>,.;[]</code>
				"
				syntax as a value for
				<emphasis>
					<property>"tokens"</property>
				</emphasis>
				attribute or link a parameter to some bean
				property that transmits
				separators collection.
			</para>
		</section>
		<section>
			<title>JavaScript API</title>
			<para>
				There is such feature of the
				<emphasis role="bold">
					<property>&lt;rich:suggestionbox&gt;</property>
				</emphasis>
				component as
				<property>object selection</property>
				.
				If you want to get the selected item as object on the client side
				you should set the value of the
				<emphasis>
					<property> "usingSuggestObjects" </property>
				</emphasis>
				attribute
				to "true".
				After that you should specify
				JavaScript method in
				the
				<emphasis>
					<property> "onobjectchange"</property>
				</emphasis>
				attribute and pass the
				<code>suggestion</code>
				object as a parameter:
			</para>
			<programlisting role="XML"><![CDATA[...
				<h:inputText id="city" value="#{capitalsBean.capital}" />
				<rich:suggestionbox for="city" var="result"
				suggestionAction="#{capitalsBean.autocomplete}"
				onobjectchange="processObjects(suggestion)"
				usingSuggestObjects="true">
				<h:column>
				<h:outputText value="#{result.name}" />
				</h:column>
				</rich:suggestionbox>
				<h:panelGroup>
				<div id="state"></div>
				</h:panelGroup>
				...
]]></programlisting>
			<para>
				When the item is selected you can get it as an object on the client
				side and use
				<code>getSelectedItems()</code>
				method to access any object properties:
			</para>
			<programlisting role="XML"><![CDATA[<script
				type="text/javascript">
				function processObjects(suggestionBox) {
				var items = suggestionBox.getSelectedItems();
				var state;
				if (items &amp;&amp; items.length > 0) {
				for ( var i = 0; i < items.length; i++) {
				state = items[i].state;
				}
				document.getElementById('state').innerHTML = "State: "+state;
				}else{
				document.getElementById('state').innerHTML = '';
				}
				}
				</script> ]]></programlisting>
			<para>
				Here is a result:
			</para>
			<figure>
				<title>
					Usage of
					<code>getSelectedItems()</code>
					method
				</title>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/suggestionboxAPI.png" />
					</imageobject>
				</mediaobject>
			</figure>
		</section>
		<section>
			<title>Other attributes and facets</title>
			<para>
				In addition to attributes common for Ajax action components
				and
				limiting requests quantity and frequency,
				the
				<emphasis role="bold">
					<property>&lt;rich:suggestionbox&gt;</property>
				</emphasis>
				has one more its own attribute
				limiting requests: the
				<emphasis>
					<property>"minChars"</property>
				</emphasis>
				attribute. This attribute defines characters quantity
				inputted into a
				field after which Ajax requests are called to perform
				suggestion.
			</para>


			<para>
				There is possibility to define what is shown if the autocomplete
				returns empty list. Attribute
				<emphasis>
					<property> "nothingLabel" </property>
				</emphasis>
				or facet with the same name could be used for this purpose.
			</para>
			<para>
				<emphasis role="bold">Example:</emphasis>
			</para>
			<programlisting role="XML"><![CDATA[...
				<rich:suggestionbox for="city" var="result"
				suggestionAction="#{capitalsBean.autocomplete}"
				nothingLabel="No cities found">
				<h:column>
				<h:outputText value="#{result.name}" />
				</h:column>
				</rich:suggestionbox>
				...
]]></programlisting>
			<para>Here is a result:</para>
			<figure>
				<title>
					<emphasis role="bold">
						<property>&lt;rich:suggestionbox&gt;</property>
					</emphasis>
					with empty list
				</title>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/suggestionbox4.png" />
					</imageobject>
				</mediaobject>
			</figure>
			<para>
				You can also use facets for the further
				<emphasis role="bold">
					<property>&lt;rich:suggestionbox&gt;</property>
				</emphasis>
				customization:
			</para>
			<programlisting role="XML"><![CDATA[...
				<h:inputText id="city" value="#{capitalsBean.capital}" />
				<rich:suggestionbox for="city" var="result"
				suggestionAction="#{capitalsBean.autocomplete}">
				<f:facet name="nothingLabel">
				<h:outputText value="No cities found" />
				</f:facet>
				<f:facet name="header">
				<h:outputText value="Select your city" />
				</f:facet>
				<h:column>
				<h:outputText value="#{result.name}" />
				</h:column>
				</rich:suggestionbox>
				...
]]></programlisting>
			<para>
				Here is a result:
			</para>
			<figure>
				<title>
					<emphasis role="bold">
						<property>&lt;rich:suggestionbox&gt;</property>
					</emphasis>
					facets
				</title>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/suggestionbox5.png" />
					</imageobject>
				</mediaobject>
			</figure>
			<para>
				Information about the
				<emphasis>
					<property>"process"</property>
				</emphasis>
				attribute usage you can findin the
				<link linkend="process"> "Decide what to process" </link>
				guide section.
			</para>
			<para>
				In RichFaces Wiki article about
				<ulink
					url="http://wiki.jboss.org/wiki/RichFacesSuggestionGettingAdditionalProperties">
					Additional Properties </ulink>
				you can find example of getting additional
				properties.
			</para>
		</section>
	</section>
	<section>
		<title>Reference Data</title>
		<para>
			<ulink url="&tlddoc;rich/suggestionbox.html">Table of
				&lt;rich:suggestionbox&gt;
				attributes</ulink>
			.
		</para>
		<table>
			<title>Component Identification Parameters</title>
			<tgroup cols="2">
				<thead>
					<row>
						<entry>Name</entry>
						<entry>Value</entry>
					</row>
				</thead>
				<tbody>
					<row>
						<entry>component-type</entry>
						<entry>org.richfaces.SuggestionBox</entry>
					</row>
					<row>
						<entry>component-class</entry>
						<entry>org.richfaces.component.html.HtmlSuggestionBox</entry>
					</row>
					<row>
						<entry>component-family</entry>
						<entry>org.richfaces.SuggestionBox</entry>
					</row>
					<row>
						<entry>renderer-type</entry>
						<entry>org.richfaces.SuggestionBoxRenderer</entry>
					</row>
					<row>
						<entry>tag-class</entry>
						<entry>org.richfaces.taglib.SuggestionBoxTag</entry>
					</row>
				</tbody>
			</tgroup>
		</table>
		<table>
			<title>Facets</title>
			<tgroup cols="2">
				<thead>
					<row>
						<entry>Facet name</entry>
						<entry>Description</entry>
					</row>
				</thead>
				<tbody>
					<row>
						<entry>nothingLabel</entry>
						<entry>Redefines the content item if the autocomplete returns
							empty
							list. Related attribute is "nothingLabel"</entry>
					</row>
					<row>
						<entry>popup</entry>
						<entry>Redefines the content for the popup list of the suggestion
						</entry>
					</row>
					<row>
						<entry>header</entry>
						<entry>Defines the header content</entry>
					</row>
					<row>
						<entry>footer</entry>
						<entry>Defines the footer content</entry>
					</row>
				</tbody>
			</tgroup>
		</table>
		<table id="suggBoxC">
			<title>Style classes (selectors) with the corresponding skin parameters</title>
			<tgroup cols="4">
				<thead>
					<row>
						<entry>Class name</entry>
						<entry>Description</entry>
						<entry>Skin Parameters</entry>
						<entry>CSS properties</entry>

					</row>
				</thead>
				<tbody>
					<row>
						<entry morerows="2">.rich-sb-int</entry>
						<entry morerows="2">Defines the styles for a
							suggestion box table
							rows
							&lt;tr&gt;</entry>
						<entry>generalSizeFont</entry>
						<entry>font-size</entry>
					</row>
					<row>
						<entry>generalFamilyFont</entry>
						<entry>font-family</entry>
					</row>
					<row>
						<entry>generalTextColor</entry>
						<entry>color</entry>
					</row>

					<row>
						<entry morerows="3">.rich-sb-int-sel</entry>
						<entry morerows="3">Defines styles for a selected
							row</entry>
						<entry>headerBackgroundColor</entry>
						<entry>background-color</entry>
					</row>
					<row>
						<entry>generalSizeFont</entry>
						<entry>font-size</entry>
					</row>
					<row>
						<entry>generalFamilyFont</entry>
						<entry>font-family</entry>
					</row>
					<row>
						<entry>headerTextColor</entry>
						<entry>color</entry>
					</row>
					
					<row>
						<entry morerows="1">.rich-sb-ext-decor-2</entry>
						<entry morerows="1">Defines styles for the second
							wrapper
							&lt;div&gt;
							element of
							a suggestion box
							exterior</entry>
						<entry>panelBorderColor</entry>
						<entry>border-color</entry>
					</row>
					<row>
						<entry>additionalBackgroundColor</entry>
						<entry>background-color</entry>
					</row>
					
					<row>
						<entry morerows="2">.rich-sb-shadow</entry>
						<entry morerows="2">Defines styles for a suggestion
							box shadow
						</entry>
						<entry>shadowBackgroundColor</entry>
						<entry>background-color</entry>
					</row>
					<row>
						<entry>shadowBackgroundColor</entry>
						<entry>border-color</entry>
					</row>
					<row>
						<entry>shadowOpacity</entry>
						<entry>opacity</entry>
					</row>

				</tbody>
			</tgroup>
		</table>
		
		<table>
			<title>Style classes (selectors) without skin parameters</title>
			<tgroup cols="2">
				<thead>
					<row>
						<entry>Class name</entry>
						<entry>Description</entry>
					</row>
				</thead>
				<tbody>
					<row>
						<entry>.rich-sb-common-container</entry>
						<entry>Defines styles for a wrapper &lt;div&gt; element of a suggestion container</entry>
					</row>
					
					<row>
						<entry>.rich-sb-ext-decor-1</entry>
						<entry>Defines styles for the first wrapper &lt;div&gt;
							element of a suggestion box exterior</entry>
					</row>
					
					<row>
						<entry>.rich-sb-ext-decor-3</entry>
						<entry>Defines styles for the third wrapper &lt;div&gt; element of a suggestion box exterior</entry>
					</row>
					
					<row>
						<entry>.rich-sb-overflow</entry>
						<entry>Defines styles for a inner wrapper &lt;div&gt; element</entry>
					</row>
					
					<row>
						<entry>.rich-sb-int-decor-table</entry>
						<entry>Defines styles for a suggestion box table</entry>
					</row>
					
					<row>
						<entry>.rich-sb-cell-padding</entry>
						<entry>Defines the styles for suggestion box table cells &lt;td&gt;</entry>
					</row>
				</tbody>
			</tgroup>
		</table>
		<para>
			You can find all necessary information about style classes
			redefinition in
			<link linkend="customstyles">Definition of Custom Style Classes</link>
			section.
		</para>
	</section>
	<section>
		<title>Relevant Resources Links</title>
		<para>
			Visit
			<ulink
				url="http://livedemo.exadel.com/richfaces-demo/richfaces/suggestionBox.jsf?c=suggestionBox">
				<emphasis role="bold">
					<property>&lt;rich:suggestionbox&gt;</property>
				</emphasis>
			</ulink>
			page at RichFaces Livedemo for examples of component usage and
			sources.
		</para>
		<para>
			RichFaces cookbook at JBoss Portal includes some articles that cover
			different aspects of working with
			<emphasis role="bold">
				<property>&lt;rich:suggestionbox&gt;</property>
			</emphasis>
			:
		</para>
		<itemizedlist>
			<listitem>
				<para>
					"
					<ulink url="http://www.jboss.org/community/docs/DOC-11851">Creating suggestion box dynamically</ulink>
					";
				</para>
			</listitem>
			<listitem>
				<para>
					"
					<ulink url="http://www.jboss.org/community/docs/DOC-11865">Getting additional properties from
						&lt;rich:suggectionbox&gt;</ulink>
					".
				</para>
			</listitem>
		</itemizedlist>
	</section>
</section>
