Hub Nexus

উন্নত করার কিছু দেখছেন? একটি পরিবর্তন প্রস্তাব করুন।

সমর্থন

প্রকাশনা: XForms · 137টির মধ্যে 59 নম্বর পাতা

Motivation

You have a text field that the users types text into. You want to show a list of possible suggested items as the user types. This feature is also known as autocomplete.

Method

Use a standard input control and set the incremental="true" attribute. Use the xforms-value-changed event to trigger a submission that puts possible values in a list. When the user select a value from the suggestion list it will replace the text value in the field.

We will also add a bind rule so that the selection view will only be visible if there is at least one suggested item.

nodeset="instance('conditional-views')/suggest-view"
relevant="count(instance('suggest-results')//item) > 1"/>

This program depends on a server-side REST web service that you pass in a single parameter "prefix" such as the following that returns recipe ingredients that begin with ba:

http://www.cems.uwe.ac.uk/xmlwiki/XForms/suggest-ingredient.xq?prefix=ba

This program returns an XML file that is restricted to the suggested ingredients that begin with the prefix passed to the XQuery web service:

Ba
Baking powder
Bananas
Barbecue Sauce
Barley
Barley, malt
Basil
Bass
Bay leaves

Screen Image

The following example shows that as the user types in the letter "c", a list of possible ingredients instantly appears in the right column. The user can continue typing and the list will be restriced to the suggestions that start with the letters typed. When the user selects an item it will fill in the prior selected field.

Suggestions displayed in the right margin of a form (Image: The original uploader was Dmccreary at English Wikibooks ., CC BY-SA 3.0)

NOTE: To get this program to run you will first have to add our server to the XForms "Trusted Sites" list.

To do this in FireFox, go to your Tools/Options/Security menu and add www.cems.uwe.ac.uk and googlecode.com to your allowed sites list. This allows the form (loaded from the googlecode domain) to pull data from the server at www.cems.uwe.ac.uk.

After you do this click the link below:

Load XForms Application

Sample Program

xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns="http://www.w3.org/1999/xhtml">;

Suggest Event Test
type="text/css">
@namespace xf url("http://www.w3.org/2002/xforms");
body {font-family: Helvetica, sans-serif}
#suggest {
position: absolute;
top: 0;
margin: 0 0 0 300px;
width: auto;
border: 1px solid blue;
}
#showlog {
position: absolute;
width: auto;
font-size: 8pt;
color: SlateGray;
background-color: lavender;
border: 1px solid SlateGray;
}

xmlns="" id="my-form">

xmlns="" id="conditional-views">

nodeset="instance('conditional-views')/suggest-view"
relevant="count(instance('suggest-results')//ingredient) > 1"/>

id="suggest-query">
xmlns="">

xmlns="" id="selected-word">

id="suggest-results" xmlns="">

id="get-suggestions" action="http://www.cems.uwe.ac.uk/xmlwiki/XForms/suggest-ingredient.xq"
method="get" separator="&"
ref="instance('suggest-query')"
replace="instance" instance="suggest-results">
ev:event="xforms-submit">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]"
value="concat('getting suggestions for: ', instance('suggest-query')/prefix)"/>

id="log">
xmlns="">

ev:event="xforms-ready">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'xforms-ready'"/>
control="field-1"/>

Suggest Event Test
ref="instance('my-form')/element[1]" incremental="true" id="field-1">
Term 1:
ev:event="DOMFocusIn">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'Focus into input 1'"/>

ev:event="xforms-value-changed">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'Value changed in input 1'"/>
ref="instance('suggest-query')/prefix" value="instance('my-form')/element[1]"/>
submission="get-suggestions"/>

ev:event="DOMFocusOut">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'Out of input 1'"/>
ref="instance('selected-word')/calling-element" value="'1'"/>

ref="instance('my-form')/element[2]" incremental="true" id="field-2">
Term 2:
ev:event="DOMFocusIn">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'FocusIn input 2'"/>

ev:event="xforms-value-changed">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'Value changed in input 2'"/>
ref="instance('suggest-query')/prefix" value="instance('my-form')/element[2]"/>
submission="get-suggestions"/>

ev:event="DOMFocusOut">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'FocusOut input 2'"/>
ref="instance('selected-word')/calling-element" value="2"/>

ref="instance('my-form')/element[3]" incremental="true" id="field-3">
Term 3:
ev:event="DOMFocusIn">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'FocusIn input 3'"/>

ev:event="xforms-value-changed">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'Value changed in input 3'"/>
ref="instance('suggest-query')/prefix" value="instance('my-form')/element[3]"/>
submission="get-suggestions"/>

ev:event="DOMFocusOut">
ref="instance('selected-word')/calling-element" value="'3'"/>

ref="instance('conditional-views')/suggest-view">
id="suggest">
suggestions:
id="results-repeat" nodeset="instance('suggest-results')/ingredient">

ref="."/>

ev:event="DOMActivate">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="concat('Clicked on a suggestion word:',
instance('suggest-results')/word[index('results-repeat')])"/>
ref="instance('my-form')/element[number(instance('selected-word')/calling-element)]"
value="instance('suggest-results')/ingredient[index('results-repeat')]"/>

ref="instance('selected-word')/calling-element">Prior-field:

id="showlog">

Event Log

id="log-repeat" nodeset="instance('log')/event">
ref="."/>

Discussion

The above example also has several lines of event logging that can be removed in a production application.

As the user is typing and they see a suggestion they like in the suggestion view they will click on the suggested item trigger. When
the focus moves out of the field we must keep track of the element that they just left. This is done by the following:

ev:event="DOMFocusOut">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="'Out of input 1'"/>
ref="instance('selected-word')/calling-element" value="'1'"/>

This example attempts to reuse the selection functions for many elements. To do this we have to get the items selected into the right field. In this example we just set an integer value for the element.

Although this works if all your elements have the same element name you will have to replace the last setvalue with
an equivalent string expression if you have many complex items in a form that need suggested values.

Setting the Field Value

The following action is used when the use clicks on suggestion:

ev:event="DOMActivate">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]"
value="concat('Clicked on a suggestion word:', instance('suggest-results')/word[index('results-repeat')])"/>
ref="instance('my-form')/element[number(instance('selected-word')/calling-element)]"
value="instance('suggest-results')/word[index('results-repeat')]"/>

The first two values are only for logging. The last setvalue sets the field of the element that has the calling-element value. So for the second element the value would be instance('my-form')/element[2].

Sample XQuery

As an example XQuery, we have a collection of "Term" elements with "TermName" subelements. The following XQuery is use for our server side script. If you use eXist just place it in the same collection as the form and call it "suggest-item.xq"

xquery version "1.0";
declare namespace exist="http://exist.sourceforge.net/NS/exist";
declare option exist:serialize "method=xml media-type=text/xml indent=yes";
let $collection-path := '/db/mdr/glossaries/data'
let $search-str := request:get-parameter('prefix', '')
return
{
for term in collection(collection-path)/Term[starts-with(TermName/text(),$search-str)]
return {$term/TermName/text()}
}

Load Non-logging XForms Application

Version with no logging

xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns="http://www.w3.org/1999/xhtml">;

Suggest Event Test
type="text/css">
@namespace xf url("http://www.w3.org/2002/xforms");
body {font-family: Helvetica, sans-serif}
#suggest {
position: absolute;
top: 0;
margin: 0 0 0 300px;
width: auto;
border: 1px solid blue;
}

xmlns="" id="my-form">

xmlns="" id="conditional-views">

nodeset="instance('conditional-views')/suggest-view"
relevant="count(instance('suggest-results')//ingredient) > 1"/>

id="suggest-query">
xmlns="">

xmlns="" id="selected-word">

id="suggest-results" xmlns="">

id="get-suggestions" action="http://www.cems.uwe.ac.uk/xmlwiki/XForms/suggest-ingredient.xq"
method="get" separator="&"
ref="instance('suggest-query')"
replace="instance" instance="suggest-results">

id="log">
xmlns="">

ev:event="xforms-ready">
control="field-1"/>

Suggest Event Test
ref="instance('my-form')/element[1]" incremental="true" id="field-1">
Term 1:
ev:event="xforms-value-changed">
ref="instance('suggest-query')/prefix" value="instance('my-form')/element[1]"/>
submission="get-suggestions"/>

ev:event="DOMFocusOut">
ref="instance('selected-word')/calling-element" value="'1'"/>

ref="instance('my-form')/element[2]" incremental="true" id="field-2">
Term 2:
ev:event="xforms-value-changed">
ref="instance('suggest-query')/prefix" value="instance('my-form')/element[2]"/>
submission="get-suggestions"/>

ev:event="DOMFocusOut">
ref="instance('selected-word')/calling-element" value="2"/>

ref="instance('my-form')/element[3]" incremental="true" id="field-3">
Term 3:
ev:event="xforms-value-changed">
ref="instance('suggest-query')/prefix" value="instance('my-form')/element[3]"/>
submission="get-suggestions"/>

ev:event="DOMFocusOut">
ref="instance('selected-word')/calling-element" value="'3'"/>

ref="instance('conditional-views')/suggest-view">
id="suggest">
suggestions:
id="results-repeat" nodeset="instance('suggest-results')/ingredient">

ref="."/>

ev:event="DOMActivate">
nodeset="instance('log')/event" at="last()" position="after"/>
ref="instance('log')/event[last()]" value="concat('Clicked on a suggestion word:', instance('suggest-results')/word[index('results-repeat')])"/>
ref="instance('my-form')/element[number(instance('selected-word')/calling-element)]"
value="instance('suggest-results')/ingredient[index('results-repeat')]"/>

Using Minimal Trigger Appearance

If you do not like the appearance of the button in the trigger you can
add the appearance="minimal" attribute to the trigger element.

The following CSS will reverse the background and font colors when the user hovers over the trigger:

.suggestion:hover {
background-color: blue;
color: white;
padding: 3px;
font-size: 10pt;
}

Preventing Null Searches

XForms 1.1 added the conditional event attribute. You can use this to only request an suggestion from the server
if the element is at least one character long.

ev:event="xforms-value-changed" if="string-length(instance('save-data')/element[1]) gt 0">
ref="instance('suggest-query')/prefix" value="instance('save-data')/element[1]"/>
submission="get-suggestions"/>

Discussion

The functionality of suggesting items is contained in the Orbeon Autocomplete component Orbon XBL Autocomplete

XSLTForms has an example that uses the JSON results from Wikipedia search to suggest pages:
XSLT Autocomplete example

Where this page came from

This page was imported from Wikibooks. From “XForms” on Wikibooks, by its contributors, under CC BY-SA 4.0. Changed here: set as a page; navigation and edit links left out; each image under its own licence, credited in its caption.

Nobody has written it yet — it is the source material at a new address, which is why search engines are asked to skip it and why no one earns from it. It is up for grabs: take it on, and it is yours to rewrite and to earn from.

যে প্রকাশনাগুলোতে আছেXForms

ভাষাEnglish

লাইসেন্স: CC BY-SA 4.0 · গৃহীত হয়েছে en.wikibooks.org

1

0

0

0

Spinner Logo

মন্তব্য

Spinner Logo
সংস্করণ: 2CC0 1.0 — public domain
The runaway star that left the Tarantula Nebula
সংস্করণ: 2CC0 1.0 — public domain
The Blackwell School, where segregation had no law behind it
সংস্করণ: 2CC0 1.0 — public domain
The Eagle Nebula, seen in the infrared
সংস্করণ: 2CC0 1.0 — public domain
The house where the Equal Rights Amendment was written
সংস্করণ: 2CC0 1.0 — public domain
The Aleutians, the forgotten front of the Second World War
সংস্করণ: 2CC0 1.0 — public domain
The Cosmic Cliffs are not cliffs