Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.5
    • Component/s: wtk
    • Labels:

      Description

      This class will be used to facilitate suggestions (i.e. "auto-lookup") for text input components.

        Issue Links

          Activity

          Hide
          Dmitry Mamonov added a comment -

          Hope I understand this issue correct, and it is some sort of autocomplete support for text fields.

          Just as example, here is text fileld "AccountNo" which holds banking account number,
          it might be a millions! of possible values in suggestion list.

          It might be more usefull if it will be implemented within interface like:
          interface SuggestionProvider

          { List<String> getSuggestions(String _curentText); }

          so I could refer to current entered text to provide reasonable amount of suggestions,
          and if user entered "408170810" then I will find "40817781012346543210"
          (note - position 6th is different, and it was intentionally).

          and methods for text field will be:

          public SuggestionProvider getSuggestionsProvider();
          public void setSuggestionsProvider(SuggestionProvider suggestions);

          Show
          Dmitry Mamonov added a comment - Hope I understand this issue correct, and it is some sort of autocomplete support for text fields. Just as example, here is text fileld "AccountNo" which holds banking account number, it might be a millions! of possible values in suggestion list. It might be more usefull if it will be implemented within interface like: interface SuggestionProvider { List<String> getSuggestions(String _curentText); } so I could refer to current entered text to provide reasonable amount of suggestions, and if user entered "408170810" then I will find "40817781012346543210" (note - position 6th is different, and it was intentionally). and methods for text field will be: public SuggestionProvider getSuggestionsProvider(); public void setSuggestionsProvider(SuggestionProvider suggestions);
          Hide
          Greg Brown added a comment -

          That's correct - the intent is to support auto-complete. We discussed using a "pull" interface such as you describe but felt that it would be more flexible (and consistent with Pivot design) to use the push (setter) approach. This way, the caller gets to decide when the suggestions are shown.

          I'll actually probably start working on this ticket fairly soon - I have a need for it in a client app.

          Show
          Greg Brown added a comment - That's correct - the intent is to support auto-complete. We discussed using a "pull" interface such as you describe but felt that it would be more flexible (and consistent with Pivot design) to use the push (setter) approach. This way, the caller gets to decide when the suggestions are shown. I'll actually probably start working on this ticket fairly soon - I have a need for it in a client app.
          Hide
          Dmitry Mamonov added a comment -

          Yes, anyway I could implement List<String> inteface on my own, also referring to target text field like:

          class MySuggestionsList implements List<String> {
          public MySuggestionsList(TextField field)

          { ... preserver reference to text field, to get it's value later, when elements is requested from this list ... }

          }

          so functionality will be the same as I described above.

          Show
          Dmitry Mamonov added a comment - Yes, anyway I could implement List<String> inteface on my own, also referring to target text field like: class MySuggestionsList implements List<String> { public MySuggestionsList(TextField field) { ... preserver reference to text field, to get it's value later, when elements is requested from this list ... } } so functionality will be the same as I described above.
          Hide
          Greg Brown added a comment -

          Updated title to reflect implementation approach.

          This feature is nearly complete. Only outstanding task is the addition of a mapping interface to allow callers to specify a custom toString() method for list items.

          Show
          Greg Brown added a comment - Updated title to reflect implementation approach. This feature is nearly complete. Only outstanding task is the addition of a mapping interface to allow callers to specify a custom toString() method for list items.
          Hide
          Niclas Hedhman added a comment -

          I would recommend against a List for the suggestions and instead provide a simpler interface + a "ListConverter" for such. The interface in question should IMHO be capable of changing the content depending on the typing without adding a listener for keyboard events. For instance;

          public interface SuggestionProvider

          { List<String> suggest( String typedSoFar, char lastChar ); }

          public class ListContentSuggestionProvider
          implements SuggestionProvider
          {
          private final List<String> content;

          public ListContentSuggestionProvider( List<String> content )

          { this.content = Collections.unmodifiableList( content ); }

          public List<String> suggest( String typedSoFar, char lastChar )

          { return content; }

          }

          This would make it a lot easier to do the "Google Search"-kind of textboxes a lot easier to do than with the suggested approach (if at all possible (impl detail)).

          Show
          Niclas Hedhman added a comment - I would recommend against a List for the suggestions and instead provide a simpler interface + a "ListConverter" for such. The interface in question should IMHO be capable of changing the content depending on the typing without adding a listener for keyboard events. For instance; public interface SuggestionProvider { List<String> suggest( String typedSoFar, char lastChar ); } public class ListContentSuggestionProvider implements SuggestionProvider { private final List<String> content; public ListContentSuggestionProvider( List<String> content ) { this.content = Collections.unmodifiableList( content ); } public List<String> suggest( String typedSoFar, char lastChar ) { return content; } } This would make it a lot easier to do the "Google Search"-kind of textboxes a lot easier to do than with the suggested approach (if at all possible (impl detail)).
          Hide
          Greg Brown added a comment -

          There are a couple of issues with the approach you suggest:

          1) Getting a list of suggestions from Google requires a call to the server. The only way the suggest() method could make the server call and return the values would be to block the UI. The UI could conceivably call the suggest() method on a background thread, but this makes the assumption that all suggestions must be obtained asynchronously, which may not be valid. For example, I could write an application that maintains a large data set client-side and performs the filtering locally.

          2) Not all suggestions will be based on the first few characters typed. For example, I can envision an app where the user is presented with a set of suggestions without even typing anything.

          The current solution is an attempt to provide the most flexibility without sacrificing developer convenience.

          G

          Show
          Greg Brown added a comment - There are a couple of issues with the approach you suggest: 1) Getting a list of suggestions from Google requires a call to the server. The only way the suggest() method could make the server call and return the values would be to block the UI. The UI could conceivably call the suggest() method on a background thread, but this makes the assumption that all suggestions must be obtained asynchronously, which may not be valid. For example, I could write an application that maintains a large data set client-side and performs the filtering locally. 2) Not all suggestions will be based on the first few characters typed. For example, I can envision an app where the user is presented with a set of suggestions without even typing anything. The current solution is an attempt to provide the most flexibility without sacrificing developer convenience. G
          Hide
          Dmitry Mamonov added a comment -

          >There are a couple of issues with the approach you suggest:

          >1) Getting a list of suggestions from Google requires a call to the server. The only way the suggest() method could make the server call and return the values >would be to block the UI. The UI could conceivably call the suggest() method on a background thread, but this makes the assumption that all suggestions >must be obtained asynchronously, which may not be valid. For example, I could write an application that maintains a large data set client-side and performs >the filtering locally.
          The most obvious solution I see is to add method isAsynchronous() which may return true or false.
          So if it may take a long time to provice completition data list, programmer will return true throug this property
          and UI code will run it in background thread, other way UI will call suggest(...) immediately.

          >2) Not all suggestions will be based on the first few characters typed. For example, I can envision an app where the user is presented with a set of >suggestions without even typing anything.
          True, back to banking account example. It might be case where we need to enter account number which is connected to current client.
          Most of time each client has limited list of accounts 1...5 may be. So we can provide this list once and it will be fine.

          But this example is interesting. What if autocompletition list depends not only on entered text but on text field context too.
          Context could be changed easily. Should I, as programmer, update completition list each time when context is changed
          (when othe client is selected in list, for example) or may be some callback method which will provide completition list is better in this case?
          Don't know.


          On the other hand what if some programmer will try to implement context-sensitive completition list.
          With context I mean current text entered into text field and all other UI components state and so far up to whole application data state.

          1. I can update ArrayList<String> items date each time when affected part of context is changed.
          But it might be too slow and unefficiet.
          2. So I will try to implement some "poll" functionality in List<String> implementation.
          But it is hard. There is a lot of methods: get, add, remove. Most of them are redundant for my purposes,
          I will implement them as

          {throw new RuntimeException("Not implemented. Shold not be called.");}

          And, may be, everithing what is needed from my implementation is to enumerate it's elements.
          Iterable<String> interface implementation provides exactly same functionality.
          (http://java.sun.com/javase/6/docs/api/java/lang/Iterable.html?is-external=true everybody know)
          And then, it will be obvious for me to implement this interface in way I need.

          .

          Show
          Dmitry Mamonov added a comment - >There are a couple of issues with the approach you suggest: >1) Getting a list of suggestions from Google requires a call to the server. The only way the suggest() method could make the server call and return the values >would be to block the UI. The UI could conceivably call the suggest() method on a background thread, but this makes the assumption that all suggestions >must be obtained asynchronously, which may not be valid. For example, I could write an application that maintains a large data set client-side and performs >the filtering locally. The most obvious solution I see is to add method isAsynchronous() which may return true or false. So if it may take a long time to provice completition data list, programmer will return true throug this property and UI code will run it in background thread, other way UI will call suggest(...) immediately. >2) Not all suggestions will be based on the first few characters typed. For example, I can envision an app where the user is presented with a set of >suggestions without even typing anything. True, back to banking account example. It might be case where we need to enter account number which is connected to current client. Most of time each client has limited list of accounts 1...5 may be. So we can provide this list once and it will be fine. But this example is interesting. What if autocompletition list depends not only on entered text but on text field context too. Context could be changed easily. Should I, as programmer, update completition list each time when context is changed (when othe client is selected in list, for example) or may be some callback method which will provide completition list is better in this case? Don't know. – On the other hand what if some programmer will try to implement context-sensitive completition list. With context I mean current text entered into text field and all other UI components state and so far up to whole application data state. 1. I can update ArrayList<String> items date each time when affected part of context is changed. But it might be too slow and unefficiet. 2. So I will try to implement some "poll" functionality in List<String> implementation. But it is hard. There is a lot of methods: get, add, remove. Most of them are redundant for my purposes, I will implement them as {throw new RuntimeException("Not implemented. Shold not be called.");} And, may be, everithing what is needed from my implementation is to enumerate it's elements. Iterable<String> interface implementation provides exactly same functionality. ( http://java.sun.com/javase/6/docs/api/java/lang/Iterable.html?is-external=true everybody know) And then, it will be obvious for me to implement this interface in way I need. .
          Hide
          Greg Brown added a comment -

          > The most obvious solution I see is to add method isAsynchronous() which may return true or false.

          That may solve the asynchronous issue, but it adds more responsibility to the TextInput class and is still less flexible than the current solution. Specifically, it requires that the TextInput skin define what events trigger suggestions, rather than leaving it up to the caller.

          For example, Google lookup in Safari only happens when characters are inserted into the search field. The suggestion list is hidden when characters are deleted. However, on the Google home page, the list of suggestions is updated both when characters are entered as well as deleted.

          Also, as I mentioned earlier, I may want to show a list of suggestions as soon as the user tabs into a field. The suggest() approach would not support that (unless TextInput always called suggest() on focus gained, which we probably don't want to do).

          In general, Pivot components don't ask for data, they are given data. It is up to the application to decide when and how to provide that data. Putting the responsibility on the component makes components more complex and is ultimately more limiting, because it tends to make too many assumptions about what callers want to do.

          Please take a look at the test application that uses SuggestionPopup. I think you will find it sufficient to meet most of your use cases.

          Show
          Greg Brown added a comment - > The most obvious solution I see is to add method isAsynchronous() which may return true or false. That may solve the asynchronous issue, but it adds more responsibility to the TextInput class and is still less flexible than the current solution. Specifically, it requires that the TextInput skin define what events trigger suggestions, rather than leaving it up to the caller. For example, Google lookup in Safari only happens when characters are inserted into the search field. The suggestion list is hidden when characters are deleted. However, on the Google home page, the list of suggestions is updated both when characters are entered as well as deleted. Also, as I mentioned earlier, I may want to show a list of suggestions as soon as the user tabs into a field. The suggest() approach would not support that (unless TextInput always called suggest() on focus gained, which we probably don't want to do). In general, Pivot components don't ask for data, they are given data. It is up to the application to decide when and how to provide that data. Putting the responsibility on the component makes components more complex and is ultimately more limiting, because it tends to make too many assumptions about what callers want to do. Please take a look at the test application that uses SuggestionPopup. I think you will find it sufficient to meet most of your use cases.
          Hide
          Dmitry Mamonov added a comment -

          http://svn.apache.org/repos/asf/pivot/trunk/tests/src/org/apache/pivot/tests/SuggestionPopupTest.java

          Code in example looks quite flexible, this way I can open SuggestionPopup even on mouse-over,
          and I can fill it with data in any way I need. I like it.

          Show
          Dmitry Mamonov added a comment - http://svn.apache.org/repos/asf/pivot/trunk/tests/src/org/apache/pivot/tests/SuggestionPopupTest.java Code in example looks quite flexible, this way I can open SuggestionPopup even on mouse-over, and I can fill it with data in any way I need. I like it.
          Hide
          Todd Volkert added a comment -

          Added 'api-change' label because toString() was added to a renderer interface for this change.

          Show
          Todd Volkert added a comment - Added 'api-change' label because toString() was added to a renderer interface for this change.

            People

            • Assignee:
              Greg Brown
              Reporter:
              Todd Volkert
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development