Am 07.02.12 22:57, schrieb Michael Hofer:
>>> Not exactly what I want. Any ideas how to access/store the id of the
>>> selected entry for later retrieval (while displaying the displayValue)?
>>> Is there a way to access the textbox from within the
>>> 'ProviderAutoCompleteResult' (nsIAutoCompleteResult) to attach something
>>> like a 'selectedId' attribute to it?
>>
>> I'm now trying to use the comment field of the autocomplete textbox for
>> my id property (accessible via textbox.controller.getCommentAt(index)).
> [...]
>> Any ideas on how to get the selected index?
>
> I finally found a way. There is an 'autocomplete-did-enter-text'
> notification which can be observed. Because this notification is sent
> before the popup closes (as opposed to the ontextentered event), the
> index of the selected element is still available in the observer. So the
> comment (or other fields) from the chosen entry can be retrieved via
>
> subject.controller.getCommentAt(subject.popup.selectedIndex)
Somebody asked me for a code example for this. Here it is:
XUL (Autocomplete Textbox):
--------------------------------------------------------------
<panel id="kunde_popup_autocomplete" type="autocomplete"
noautofocus="true" />
<textbox id="kunde"
type="autocomplete"
autocompletepopup="kunde_popup_autocomplete"
autocompletesearch="json-autocomplete"
completedefaultindex="true" forcecomplete="true"
enablehistory="true"
showcommentcolumn="true"
autocompletesearchparam='[]'"/>
- The separate panel set via the autocompletepopup attribute on the
textbox is not strictly necessary. But without it I got popup display
problems in some places. Place the panel separately from the textbox
(like on the top level of the document) if you've got display problems.
- "json-autocomplete" is my custom autosearch component implemented
basically like described on
https://developer.mozilla.org/en/How_to_implement_custom_autocomplete_search_component#Basic_example_for_Gecko_2.0_and_up_%28Firefox_4_.2F_Thunderbird_3.3_.2F_SeaMonkey_2.1%29
- The autcocompletesearchparam on the textbox is set via script on init
to a string containing json encoded data (with the data key containing
an an array of hashes each having fields for displayValue, comment,
id,...) -> See
http://pastebin.com/emg0nzWc for an according
startSearch-implementation (autocompletesearchparam is received as
searchParam there). In that implementation getValueAt(index)
(nsIAutoCompleteResult) would return
this.results[index]['displayValue']
while getCommentAt(index) would return
this.results[index]['comment']
(or ['id'] if you used the comment field for the id)
Observer (for receiving the index of the selected entry)
----------------------------------------------------------
function myObserver()
{
this.register();
}
myObserver.prototype = {
observe: function(subject, topic, data) {
var id = subject.controller.getCommentAt(subject.popup.selectedIndex);
alert( 'id of selected element (read from comment field): ' + id );
},
register: function() {
var observerService =
Components.classes["@
mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.addObserver(this, "autocomplete-did-enter-text",
false);
},
unregister: function() {
var observerService =
Components.classes["@
mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.removeObserver(this, "autocomplete-did-enter-text");
}
};
var testObserver = new myObserver();
This will be called after autocomplete was at work (but before the popup
closes, so the selectedIndex is still available here). There are more
undocumented notifications like this in
toolkit/components/autocomplete/nsAutoCompleteController.cpp:
'autocomplete-will-enter-text', 'autocomplete-will-revert-text',
'autocomplete-did-revert-text'
Improvements
----------------------------------------------------------------
It's generally a good idea to have the xulrunner or firefox source code
available for reference when working on these less documented features.
Also: Don't mess around too much with internals when you are not in
control of your xulrunner-environment (like when writing plugins).
1) To implement additional fields (like a getIdAt(index)-function in
your nsiAutoCompleteResult) it seems to be necessary to also extend
(implement your own?) nsIAutoCompleteController. Without that, all you
have available from the controller is comment, image, label/value and style.
I didn't do that yet. Code examples anyone?
2) The default panel associated with the autocomplete textbox uses a
tree with two columns (one for the value, one for the comment) for
display. Using a richlistbox gives better formatting options + free
search string highlighting in the result list (similar to awesomebar in
firefox). But
<panel id="kunde_popup_autocomplete" type="autocomplete-richlistbox" />
(as described in the tutorial) doesn't work properly for me (xulrunner
2.0), but
<panel style="-moz-binding:
url(chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup)"
id="kunde_popup_autocomplete" type="autocomplete" noautofocus="true" />
does (You'd better define a corresponding css class for that style).
To modify the structure of the individual richlistitems, you can extend
the XBL:
XBL
----
<binding id="my-autocomplete-richlistitem"
extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-richlistitem">
<content>
<!-- copy/modify the content from
chrome://global/content/bindings/autocomplete.xml#autocomplete-richlistitem
here -->
</content>
</binding>
CSS
---
.autocomplete-richlistitem {
-moz-binding:
url('/path/to/my-autocomplete.xml#my-autocomplete-richlistitem');
}
For modifying the popup (which is creating the
autocomplete-richlistitems) also extend
chrome://global/content/bindings/autocomplete.xml#autocomplete-rich-result-popup.
Hope this helps somebody.
regards,
Michael