Forms — widgets and support classes for capturing user information

Auto complete

The WSuggestionPopup class is a widget which pops up to assist in editing a text area or line edit through auto completion. This widget may be associated with one or more WFormWidgets (typically a WLineEdit or a WTextArea).

The popup provides the user with suggestions to enter input. The popup can be used by one or more text editors, using forEdit(). The popup will show when the user starts editing the edit field, or when the user opens the suggestions explicitly using a drop down icon or with the down key. In the example below, the popup positions itself on top of the edit field.

The class is initialized with an Options struct which configures how suggestion filtering and result editing is done. Alternatively, you can provide two JavaScript functions .

To style the suggestions, you should style the <span> element inside this widget, and the <span>."sel" element to style the current selection.

You can also limit the maximum height of the popup by using setMaximumSize(). In this case, scrolling is supported (similar to a combo-box).

Example
source
#include <Wt/WContainerWidget.h>
#include <Wt/WLineEdit.h>
#include <Wt/WSuggestionPopup.h>


auto container = Wt::cpp14::make_unique<Wt::WContainerWidget>();

// Set options for email address suggestions:
Wt::WSuggestionPopup::Options contactOptions;
contactOptions.highlightBeginTag = "<span class=\"highlight\">";
contactOptions.highlightEndTag = "</span>";
contactOptions.listSeparator = ',';
contactOptions.whitespace = " \\n";
contactOptions.wordSeparators = "-., \"@\\n;";
contactOptions.appendReplacedText = ", ";

Wt::WSuggestionPopup *sp =
    container->addWidget(Wt::cpp14::make_unique<Wt::WSuggestionPopup>(
            Wt::WSuggestionPopup::generateMatcherJS(contactOptions),
            Wt::WSuggestionPopup::generateReplacerJS(contactOptions)));

Wt::WLineEdit *le = container->addWidget(Wt::cpp14::make_unique<Wt::WLineEdit>());
le->setPlaceholderText("Enter a name starting with 'J'");
sp->forEdit(le);

// Populate the underlying model with suggestions:
sp->addSuggestion("John Tech <techie@mycompany.com>");
sp->addSuggestion("Johnny Cash <cash@mycompany.com>");
sp->addSuggestion("John Rambo <rambo@mycompany.com>");
sp->addSuggestion("Johanna Tree <johanna@mycompany.com>");

Model

WSuggestionPopup is a MVC class (model-view-controller). By default a WStringListModel is used. The member methods clearSuggestions() and addSuggestion() manipulate this model. You can set another model with setModel(). See the Combo box section for an example.

Server-side filtering

By default, the popup implements all filtering client-side. To support large datasets, you may enable server-side filtering of suggestions based on the input. The server-side filtering may provide a coarse filtering using a fixed size prefix of the entered text, and complement the client-side filtering. To enable server-side filtering, use setFilterLength() and listen to filter notification using the modelFilter() signal. Whenever a filter event is generated you can adjust the model's content according to the filter (e.g. using a WSortFilterProxyModel).

Initializing Options with JavaScript functions

Usually, the popup class is initialized with an Options struct which configures how suggestion filtering and result editing is done. Alternatively, you can provide two JavaScript functions, one for filtering the suggestions (generateMatcherJS()), and one for editing the value of the textarea when a suggestion is selected ( generateReplacerJS()). The matcher function must have the following JavaScript signature:

source
function (editElement) {
    // fetch the location of cursor and current text in the editElement.

    // return a function that matches a given suggestion with the current
    // value of the editElement.
    return function(suggestion) {

	// 1) if suggestion is null, simply return the current text 'value'
	// 2) check suggestion if it matches
	// 3) add highlighting markup to suggestion if necessary

	return { match : ...,      // does the suggestion match ? (boolean)
		 suggestion : ...  // modified suggestion with highlighting
	       };
    }
}

The replacerJS function that edits the value has the following JavaScript signature.

source
function (editElement, suggestionText, suggestionValue) {
    // editElement is the form element which must be edited.
    // suggestionText is the displayed text for the matched suggestion.
    // suggestionValue is the stored value for the matched suggestion.

    // computed modifiedEditValue and modifiedPos ...

    editElement.value = modifiedEditValue;
    editElement.selectionStart = edit.selectionEnd = modifiedPos;
}

Remark

You can find several more advanced examples in the Wt distribution directory examples/feature/suggestionpopup/. In the SuggestionPopup.C class you can explore different functions.

Top