Feature #703
closedWSuggestionPopup and WStringListModel UserRole problem
0%
Description
WSuggestionPopup is using a WStringListModel by default. Since WStringListModel does not support a UserRole (only a DisplayRole), a problem arises in WSuggestionPopup::modelRowsInserted, that tries to set the "sug" attribute of the suggestion popup list items to the UserRole value of the model. The "sug" attribute always ends up being the empty string. This is a problem when doActivate is called, when a list item is selected.
Updated by Koen Deforche almost 14 years ago
- Status changed from New to Feedback
Hey,
When UserRole is not defined, then the following code below (from WSuggestionPopup.C) copies the DisplayRole as the "sug" attribute though ?
Do you have an example that illustrates the wrong behaviour you see ?
boost::any d = model_->data(i, modelColumn_);
WText *value = new WText(asString(d), PlainText);
boost::any d2 = model_->data(i, modelColumn_, UserRole);
if (d2.empty())
d2 = d;
line->addWidget(value);
value->setAttributeValue("sug", asString(d2));
Updated by Koen Deforche over 13 years ago
Hey Marios,
(In reaction to your private email), I now see that I interpreted your question wrongly. You diagnosis of the situation is correct:
Here is an example:
WLineEdit* le = new WLineEdit();
le->setTextSize(80);
le->setFocus();
m_pSP = new
WSuggestionPopup(WSuggestionPopup::generateMatcherJS(contactOptions),
WSuggestionPopup::generateReplacerJS(contactOptions), this);
m_pSP->filterModel().connect(this, &Webphone::filter);
m_pSP->activated().connect(this, &Webphone::select);
m_pSP->forEdit(le);
...
m_pSP->addSuggestion("text", "value");
...
void Webphone::select(...)
{
// "sug" attribute here is equal to "text" and not "value"
// this is counter-intuitive.
// The reason: the default WSuggestionPopup model is an instance of
WStringListModel, which does not implement DisplayRole and UserRole.
}
The problem is not in WSuggestionPopup.C. The problem is in
WStringListModel.C. WStringListModel does not "honor" the DisplayRole
and UserRole properties. If I use setModel to set the WSuggestionPopup
model to, let's say, a WStandardItemModel, then UserRole will work as
expected. But, from a user stand point I would expect the UserRole
functionality (implicitly invoked by a call to "addSuggestion" that
requests for text and value parameters) to work out of the box. Now it
does not. I pass a different text and value string to addSuggestion, and
I get back a "sug" value equal to the text suggestion. The value
suggestion is completely lost.After looking into the WStringListModel code, I am not sure if the right
thing to do is to extend WStringListModel to use the UserRole property,
or to simply change the default model of WSuggestionPopup to be a
WStandardItemModel instead (I chose this solution for now), or to simple
document this fact and leave things as is, then let the user can change
the default model if they need to use the "sug" value.
I would prefer the improve-the-documentation approach. WStringListModel should be kept simple !
Since you are looking into this, another suggestion is to allow the
users to customize the suggestionClicked and refilter javascript
functions of WSuggestionPopup.js the same way that the user can
customize the matcher and replacer functions. For example, in my
application I search by edit distance and the contents of the popup keep
changing as the user is typing letters. The suggestions are not fixed. I
wanted to refilter anytime a letter was clicked, irrespective of the
filter length. I wanted refilter to keep being called. I was not able to
do that (without changing WSuggestionPopup.min.gs to fit my needs...)
Anyway, just a thought :)
Can this not be done with an insanely long filter length ?
Regards,
koen
Updated by Koen Deforche over 13 years ago
- Status changed from Feedback to InProgress
> Can this not be done with an insanely long filter length ?
>I don't think so. I need to call a server side function every time a
letter is pressed. Currently, the suggestion list is populated once, and
every time a letter is clicked, the client filters the list. For my
purposes, the list might change completely every time a letter is
entered, which requires client server communication.Surprisingly, I was able to implement that at interactive speed. I have
a search box that goes back to the server and retrieves all strings from
the database within edit distance 3 of the entered text, populates the
suggestions list and displays the results, before the user can enter two
more characters. If feels almost as good as a simple prefix completion.
Here is the same idea implemented by someone else:
http://ipubmed.ics.uci.edu/Also, think of what Google search box is doing. They do not populate the
client suggestion list beforehand with the complete query log and
dictionary. Every time a letter is pressed they probably query a suffix
tree on the server.I understand though that WSuggestionPopup was not designed with
something like this in mind.
I see that now. But WSuggestionPopup almost provides this ability --- see filterModel(), it already provides the ability to do server-side filtering of the model (changing the data as you want) based on input. This is already used in the way you want it when setting the edit trigger to DropDownIcon.
We could change setFilterLength() so that the default value (currently 0) becomes --1 which has the effect of not having any server-side filtering, assign a semantic to 0 which implies that each input is subject to server-side filtering, and keep the meaning for positive values. That breaks the API in a minor way but I believe it is for the good.
Regards,
koen
Updated by Koen Deforche about 13 years ago
- Status changed from InProgress to Resolved
- Assignee set to Koen Deforche
- Target version set to 3.1.11
Hey,
We've implemented the --1 value interpretation.
Regards,
koen
Updated by Koen Deforche about 13 years ago
- Status changed from Resolved to Closed
Resolved in Wt 3.1.11