77 thoughts on “Flex AutoComplete: Bug fixes”

  1. Do you have this on SVN/Google code? I would love to contribute to the project or at least be able to update via SVN. Thanks for working on this. Nice component.

  2. Sorry!.. I just saw your post about the Google code site. I will checkout from there. Should we post our bugs/issues/contributions there or would you prefer them to be posted to your blog?

    1. Kevin,

      For now it’d probably be better if you post to the blog. In the future I’m considering moving everything to the google site (I’m waiting to see if people are interested in helping out on the project).

      Thanks,
      Hillel

  3. I noticed a minor bug, but I’ll post it anyway.

    The prompt does not return to the field when you click out of the field after entering something and deleting it. The best way to see this is to do the following:
    Launch the demo, click in the text field and then tab out of it. You will see the prompt return to the field as desired. Now click back in the field, hit spacebar, then delete the space, then tab out of the field. Notice how the prompt does not get reset.

    Thanks, Kevin

  4. Was there ever a fix for the isEqualFunction problem. It seems that this can be tricky if you are entering a new item which has a similar string to an old one. IE.. if my data provider contains the color “Blue” in the list, but I want to add a new color named “Blue Green” it i impossible. I would think that the default behavior should be if isStrict is set to false, then the isEqualFunction is disabled. (Or just have a flag that enables/disables this feature.)

    Actually, I am not sure what isStrict does. I have tried both settings and it doesn’t seem to change. In both cases I seem to be able to add a new item.

    I’ll dig into the code and take a look when I have a little more time. This is a really great component. Thanks.

    1. Kevin

      Thanks for the great feedback. Yup, the prompt should definitely reappear. I’ll have that resolved in the next release. I was planning to rework the isEqualFunction. For now to disable the feature you can create a function which always returns false.

      The isStrict flag seems to work for me. In the demo with “Allow New Values” checked type “1234” then press enter. 1234 should now be added. If you try the same thing with out “Allow New Values”, the value shouldn’t be added.

  5. Ah, yes, I see it works when you press “Enter”, but try this…

    With the “Allow New Values” not selected, type “1234” then tab out of the field.

    I think the bug is in the focusOut handler of the text field. Speaking of focusOut, it would be nice to have focusIn and focusOut events dispatched.

  6. Hillel – amazing component! It fits perfectly into an application we are building here, and it’s flexible enough that we’re able to use it in a few different places. We were all set to build something just like it when a Google search turned it up. Exactly what we needed!

    We seem to be having an issue with setting the selectedItems property, however. We are using it in a Save As dialog as a sort of intelli-type text field and trying to pre-populate it with the tags the user has previously used when saving the active document. When we do something like this.autoComplete.selectedProperties = ac (where ac is an ArrayCollection with several strings in it), only the first item actually appears in the component (and also in the selectedItems property, upon inspection). So, for example, if they had used the tags “OK” and “Investing” before, only “OK” will be pre-populated in the component.

    I was wondering if anyone else had reported similar issues, or if there is a better way to pre-populate with items. Thanks again for providing such a powerful drop-in component.

    1. Ty,

      Nice to hear that the component has saved you some time. I’m not entirely sure I follow your issue, but… here’s an example of using the component with multiple pre-selected items. Please let me know what’s different with the way you’re using it and I’ll to help you sort out your issue.

      <?xml version=”1.0″ encoding=”utf-8″?>
      <mx:Application
      xmlns:mx=”http://www.adobe.com/2006/mxml”
      xmlns:components=”com.hillelcoren.components.*”
      initialize=”init()”>

      <mx:Script>
      <![CDATA[
      import mx.collections.ArrayCollection;

      [Bindable]
      private var _data:ArrayCollection;

      [Bindable]
      private var _selected:ArrayCollection;

      private function init():void
      {
      _data = new ArrayCollection( [ “One”,”Two”,”Three” ] );
      _selected = new ArrayCollection( [ “One”,”Two” ] );
      }
      ]]>
      </mx:Script>

      <components:AutoComplete dataProvider=”{ _data }” selectedItems=”{ _selected }”
      isMultiSelect=”true” multiSelectLayout=”horizontal”/>

      </mx:Application>

  7. Hi, i really love this component.
    is it possible to set the columns you want to show in the browse window?

    thanks

    1. Daniel,

      There currently isn’t a simple way to set which columns to show (but… that’s a good idea which I’ll try to add to a future release). For now you can create your own Browser component and then assign it to the AutoComplete’s browserClass property. The easiest way to do this is to just extend the existing Browser component. Here’s an example:

      // file called MyBrowser.mxml
      <?xml version=”1.0″ encoding=”utf-8″?>
      <Browser
      xmlns=”com.hillelcoren.components.autoComplete.classes.*”
      xmlns:mx=”http://www.adobe.com/2006/mxml”>

      <mx:Script>
      <![CDATA[
      import mx.controls.dataGridClasses.DataGridColumn;
      import mx.controls.DataGrid;

      override public function init():void
      {
      super.init();

      var columns:Array = [];
      columns.push( new DataGridColumn( “name” ) );

      DataGrid( _list ).columns = columns;
      }
      ]]>
      </mx:Script>

      </Browser>

      Then when you use the AutoComplete simply set the browserClass. ie, autoComplete.browserClass = MyBrowser;

      There’s a catch though, the _list property of the Browser component is set as private. In the next release I’ll change this to protected but for now you’ll need to use the source-code and change it yourself. It’s defined in Browser.mxml on line 47.

      Let me know if you have any trouble getting this working,
      Hillel

  8. Hillel,

    Thanks for your quick response. The use case is that we are including the AutoComplete inside a TitleWindow as a “Save As” popup, so we have to send data to the TitleWindow through events from the main app. Among the things we’re sending is an ArrayCollection of strings, the “tags” with which the user tagged this document the last time they saved it.

    Here’s an image of the dialog: http://tinyurl.com/c53ass
    In that image, the selectedItems property of the component is bound to an ArrayCollection containing the strings “OK” and “Investing,” but only “Investing” appears.

    Here is the implementation of the component:

    And here’s the declaration of the ArrayCollection:
    [Bindable]
    private var selectedTags:ArrayCollection = new ArrayCollection([“OK”, “Investing”]);

    Inspecting the variables in debugger after creation is complete show the ArrayCollection still intact with both strings in it, but the selectedItems property of intelliSense shows only a single element, “Investing.”

    After that, the component behaves perfectly, offering suggestions for tags from the allMapViewTags ArrayCollection we get from our DB. As the user adds more tags, the selectedItems property updates as expected. It’s only getting it to pre-populate with the tags the user used last time they saved I’m having trouble with. Applying the model in your example (explicitly declaring two ArrayCollections with some corresponding elements and binding to them) yielded the same results for me, so maybe I am overlooking something. Thanks again for your help.

    1. Ty,

      There was a bug with the older version of the component which would have caused this behavior, are you using the latest version?

  9. Hillel,

    Thank you for pointing that out. I thought I had the latest version, but turns out I didn’t. I attempted the example with the latest version (AutoComplete-0.98.swc) of the component and got the following error:

    Error at com.hillelcoren.components.autoComplete.classes::Combo/setSelectedItem()[/Users/hillel/Code/flex-autocomplete/src/com/hillelcoren/components/autoComplete/classes/Combo.mxml:427]
    at com.hillelcoren.components::AutoComplete/commitProperties()[/Users/hillel/Code/flex-autocomplete/src/com/hillelcoren/components/AutoComplete.mxml:332]
    at mx.core::UIComponent/validateProperties()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:5807]…

    Which is odd because Combo.mxml line 427 is:
    var validItem:Boolean = true;

    Even without setting the selectedItems property in the mxml declaration (which I figured may prevent calling the code which is throwing the error), I still get the error.

    Thanks again for all your help with this, Hillel.

  10. Hillel,

    I just got around to rebuilding the .swc from the source, and it works flawlessly! I’m using the Flex 3.2 SDK, so perhaps that played into the equation. Thanks again for all your patience and help.

    -Ty

    1. Ty,

      I’m sorry I wasn’t clearer. When I wrote do a “clean build” I meant do a clean build of your project (not regenerate the swc). To do a clean build select “Project” in the menubar and then choose “clean…”. When the compiler gives an error pointing to the wrong line very often doing a clean build will help.

      Happy to hear it’s working though

  11. Hillel,

    I had done a project clean since adding the reference to the AutoComplete-0.98.swc and was still getting that strange error. Perhaps my project was caching the old one or something. Anyway, rebuilding the .swc solved the issue, and all is well 🙂

    -Ty

  12. Hillel,
    Is there any way where i can restrict the selected item , Currently i am able to type any thing (‘Abc’) and it creats a new selected item. I am not sure what isStrict does .

    The component is great and we are planning to use it.

    Thanks in advance.

    1. Anupam,

      I think you’ve answered your own question (unless I’m missing something… which I feel like I might be). isStrict is what you’re looking for. Setting it to true means that the component “is strict” and requires that the user selects an item from the dataProvider.

  13. Hillel,
    If you go to your demo link , the system let you add a new word (“Test”) in the input box although isStrict is set to true.

    Thanks once again.

    1. Anupam,

      I think I see what you mean. The main way of selecting items is with the enter key (or comma for multiSelect). If “Allow new values” is unchecked (ie, isStrict is true) these actions will not select the item. However, if you type “Test” then move the focus out of the component it will still select the item. Is this what you’re referring to?

  14. Hillel,
    You got it right , Is there any way to prevent this from happening . Actually it is defeating the purpose which we are trying to accomplish in our application.

    1. Anupam,

      Absolutely, that’s clearly a bug. I should be able to have it resolved by tomorrow.

      Thanks for pointing it out.

  15. Hillel,
    I have one more suggestion , is there any way we can add another property which restrict the number of word that can be selected . We are planning to put a restriction , where our user can not select more than 5 words from the list.
    I know i am getting greedy.
    Thanks for the quick response.

    1. Anupam,

      I could see that feature being useful to other people as well so I’m happy to add it (plus it shouldn’t be too hard to implement). Just so you know, I’m going to check in the changes to the google code site (http://code.google.com/p/flex-autocomplete/), you’ll need to do a checkout to get the latest version of the code.

      I’ll let you know once it’s ready.

    2. Anupam,

      I’ve checked in a fix for the isStrict issue you found, however I’ve had seconds thought about adding a maxNumSelected property. It feels like this should be handle either by a validator or custom code in the change handler. I need to make some improvements to make the change handler easier to write but for now the code below should do the job.

      <?xml version=”1.0″ encoding=”utf-8″?>
      <mx:Application
      xmlns:mx=”http://www.adobe.com/2006/mxml”
      xmlns:components=”com.hillelcoren.components.*”
      xmlns:classes=”com.hillelcoren.components.autoComplete.classes.*”
      verticalAlign=”middle” initialize=”init()”>

      <mx:Script>
      <![CDATA[
      import mx.collections.ArrayCollection;

      [Bindable]
      private var _data:ArrayCollection;

      private static const MAX_NUM_ITEMS:int = 2;

      private function init():void
      {
      _data = new ArrayCollection(
      [
      { “name”:”Bob” },
      { “name”:”Sue” },
      { “name”:”Jim” },
      { “name”:”Dan” }
      ] );
      }

      private function handleChange():void
      {
      while (autoComplete.selectedItems.length > MAX_NUM_ITEMS)
      {
      var index:int = autoComplete.selectedItems.length – 1;

      autoComplete.selectedItems.removeItemAt( index );
      autoComplete.combo.flowBox.removeChildAt( index );
      }
      }

      ]]>
      </mx:Script>

      <components:AutoComplete id=”autoComplete” dataProvider=”{ _data }” width=”250″
      labelField=”name” change=”handleChange()” isMultiSelect=”true” multiSelectLayout=”horizontal”/>

      </mx:Application>

  16. Even with the latest changes, I am still seeing a problem when strict mode is on and multiselect is off when using Enter to select an item. It seems that the item is being selected, but the handleChange() method in Combo.mxml is immediately clearing the selection.

    I have a code change that seems to fix the problem. On line 648 of Combo.mxml, change the “if” to check whether the text box is empty, like this:

    if (selectedItem && !_isMultiSelect && textInput.text != “”)

    1. Abe,

      Thanks for suggesting the change but I’m unable to replicate your problem. I’ve just updated the demo with the latest version of the code. Could you please check to see if the problem happening and if so let me know the steps to take to replicate the issue.

      The code seem right to me. If multiselect is off, then we need to clear out the selection otherwise we’ll end up with two items selected.

      Thanks very much for your help!!

  17. Hillel,

    Sorry if this was asked earlier, I did not find it…
    I was using chooser-0.93 before, and now I wanted to update to autocomplete-0.98.
    In 0.93 it was possible to display the component as a textinput, but now the height is bigger and scrollbars appear if the item is too long.
    Is it possible to set it the same height as a textinput (22px) and not have scrollbars?

    Another question:
    Do you why I receive this message with 0.93:
    warning: unable to bind to property ‘searchText’ on class ‘com.hillelcoren.components::Chooser’

    Thanks,
    Andras

    1. Andras,

      Yeah… that bothered me too. It took me a little while to figure out the height issue but it’s now resolved. The fix has been checked into the code base on google code. The latest code should also resolve your warning.

  18. Hillel,
    I am trying add my selection into autocomplete textbox from an outside control (Link Button). Is there anyway i can accomplish this functionality.

    i created a function for the above
    public function addItem(mycolor:String):void
    {
    _color = new Color(mycolor,autoComplete.selectedItems.length+1);

    autoComplete.selectedItems.addItem(_color);

    }

    1. Anupam,

      It should be easier to do this, I’ll look into improving this in the next release. For now, the following code appears to work.

      var array:Array = autoComplete.selectedItems.source.concat(“new value”)
      autoComplete.selectedItems = new ArrayCollection( array );

  19. Hi Hillel,

    a couple of observations.

    In earlier versions we could clear inputted text via a small cross within the PromptTextInput component, a useful component in itself actually. However this functionality broke during the Chooser to AutoComplete refactor. This can be observed on your demo site too. I did have a quick look at the code but I could not spot what was wrong.

    I still have not been able to get AutoComplete to work with dynamic data without changing Combo.mxml. Essentially I fire an extra handleChange() after commitProperties(). The undesirable side affect of this is that the I lose the prompt text. Any help here would be greatly appreciated.

    Thanks again for a great component.

    Guy.

    1. Guy,

      I’m actually working on the issue with the clear icon for the next release.

      Would it be possible for you to put together a sample app which demonstrates your problem with dynamic data?

  20. Hillel,

    As my comments say below I clear the data in the collection before firing the event, otherwise we would filter against stale data.

    For a sample app I have taken your ColorDemo.mxml as a starting point, replace the line

    private function init():void

    with below, and you have a dynamic data example.

    private function init():void {
    colors = new ArrayCollection();
    }

    private var delayTimer:Timer;

    private function handleTextChange():void {
    if (delayTimer != null && delayTimer.running) {
    delayTimer.stop();
    }

    if (autoComplete.searchText.length > 2) {
    // if you remove below line then it kind of works
    // but it is more correct to remove all data
    // before repopulate. Really it is just holding
    // on to stale data
    colors.removeAll();
    delayTimer = new Timer(500,1);
    delayTimer.addEventListener(“timer”,
    showComboAll);
    delayTimer.start();
    }
    }

    public function showComboAll(event:TimerEvent):void {

    1. Guy,

      Thanks for putting this together. It looks like the end of it was cut off though, what’s in the showComoAll function?

  21. Ah, it is not cut off, literally replace the init() line with what I have pasted above. I provide a replacement init() in the snippet above.

    Actually the only way I could get dynamic data to work was to extend your Combo.mxml with my own and modify AutoComplete.mxml to use it instead, see code below. Essentially I add an extra call to commitProperties(). Side affect is that I get an extra change event when an item is selected so I need to be aware of this in my app.

    Thanks,
    Guy.

    1. Guy,

      Thanks for the example, that was really helpful. I think I’ve worked out a solution for you. I’ve added a “search” function which you can call after the data is added to the dataProvider. I’ve just checked in the changes to the google code site.

  22. Hillel,

    you’re a star, works a treat. However you still seem to need to defend against an extra event when an item is selected. My code additions to ColorDemo.mxml now look like below:

    // Replacement init method
    private function init():void {
    colors = new ArrayCollection();
    }
    private var delayTimer:Timer;

    private function handleTextChange():void {
    if (delayTimer != null && delayTimer.running)
    delayTimer.stop();

    if (autoComplete.selectedItem)
    return;
    colors.removeAll();

    if (autoComplete.searchText.length > 2) {
    delayTimer = new Timer(500,1);
    delayTimer.addEventListener(“timer”, showComboAll);
    delayTimer.start();
    }
    }

    public function showComboAll(event:TimerEvent):void {
    // original init code here

  23. Whoops, forgot to add the following to the end of the showComboAll() function:

    autoComplete.search();

    1. Awesome, thanks for your help getting this working. I’ve gotten a lot of request to make the component easily support a dynamic dataProvider.

  24. Hillel,

    I think I found a new problem now, when I try to programatically set a complex object as the selectedItem it does not render. For example if I add a button with a click action as below, the color is set but not the text.

    private function addItem() : void {
    autoComplete.selectedItem = { “name”:”Turquoise Blue”, “hex”:0x6CDAE7
    };
    }

    If I just try and set a set a simple object, i.e. a String, this works fine.

    Any ideas?

    Cheers,
    Guy.

    1. Guy,

      That’s interesting, I hadn’t considered the case where someone would use the selectedItem property to select an item not in the list. I think a workaround could be to first add the item to the dataProvider then set in in the selectedItem property. This should work though, I’ll add it to my list for the next release.

      I’m not able to reproduce the focus/prompt issue. When I try it the prompt appears for a split second then disappears (it shouldn’t appear at all, I’ll fix this), I notice that you added these comments to the “bug fixes” post, are you using the latest 0.98.1 version?

      Thanks!!

  25. Hillel,

    I think I know where the issue lies. In Combo.addItem() we do not allow the addition of complex objects, we assume the item is a string and then trim. If not string but a complex object the isNew test will always fail and item will never be added to the combo.

    If we change the test from “if (isNew)” to “if (isNew && item is String)” this seems to work. Not sure if there might be any unexpected side effects though.

    Guy.

  26. Hillel,

    rather curiously when I programmatically set the selected item the focus remains on the PromptTextInput component, as such it keeps displaying the prompt text. As a workaround I can call a setFocus() on something else, for example the AutoComplete component, and all is well. Makes my code look a bit strange though.

    Guy.

  27. Hillel,

    actually the problem with the unwanted prompt is manifesting itself even when an item is not selected programmatically.

    To reproduce, type some random text and then shift focus by clicking on the ‘Style’ dropdown. Typed text is then shown as selected with part of the prompt still visible.

    Guy.

  28. A piece of advice – would be handy if you set up a persistent URL where one can download the latest version of this component, taken into the account that this component is updated every month

    1. JabbyPanda,

      Thanks for the advice, I’ll start storing the zip files under the downloads tab of the google code site.

    1. Sachin,

      I’ve used multiple AutoCompletes on a single page and haven’t had any issues. Can you post/email me a test application which demonstrates your problem?

      Thanks

  29. Hello Hillel,

    I found a small bug. When the dropdown is the last item of a form, the selection list does not open below the textinput but above. this is what I want. But when I continue to type and the number of available options are reduced, the remaining options should be aligned at the bottom of the dropdown. now they appear to be detached from the textinput

    Cheers,
    Ropo

      1. Hi Hillel,

        First of all, thanks for a great component! It has everything I´ve been looking for and the functionality is great!

        I did however run into the same issue as Ropo was describing above, did you manage to find a solution?

        Cheers,
        Michael

      2. Michael,

        This will be fixed in the next version. If you don’t want to wait for the next version to be packaged up and released (it’ll probably be a couple of weeks) you can download the latest code from the google code site.

  30. very simple but nice code snippet. i found it very useful.

    private function onMouseUp(event:Event):void{
    autoCompleteValues.showDropDown();
    }

      1. However, it looks like a call to positionDropDown(); at line 883 fixed it? If you have any better solution – or i just missed your previous one please do tell

  31. Hi Hillel, I’m Leon, I am May 27, 2010 at 11:46 for you to ask a question:
    “If the Allow Duplicates option is not selected, when I select the” Almond “and
    “Antique Brass”, and then I enter “A” and press the Enter key, after that I deleted the “Antique Brass”, find “Almond” can repeat ”
    Now that you have any better suggestions for the What, this is very important to me now

  32. In autocomplete field i received this error..

    ReferenceError: Error #1069: Property name not found on String and there is no default value.
    at view.components::HLabeledAutoFill/onClose()[C:\Users\Admin\Documents\Flex Builder 3\FlexProject\src\view\components\HLabeledAutoFill.mxml:210]
    at view.components::HLabeledAutoFill/__iACField_close()[C:\Users\Admin\Documents\Flex Builder 3\FlexProject\src\view\components\HLabeledAutoFill.mxml:309]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9298]
    at com.adobe.flex.extras.controls::ComboBox/http://www.adobe.com/2006/flex/mx/internal::onTweenEnd()[C:\Users\Admin\Documents\Flex Builder 3\FlexProject\src\com\adobe\flex\extras\controls\ComboBox.as:2053]
    at mx.effects::Tween/endTween()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\effects\Tween.as:524]
    at com.adobe.flex.extras.controls::ComboBox/destroyDropdown()[C:\Users\Admin\Documents\Flex Builder 3\FlexProject\src\com\adobe\flex\extras\controls\ComboBox.as:1653]
    at com.adobe.flex.extras.controls::ComboBox/set dataProvider()[C:\Users\Admin\Documents\Flex Builder 3\FlexProject\src\com\adobe\flex\extras\controls\ComboBox.as:719]
    at com.adobe.flex.extras.controls::AutoComplete/set dataProvider()[C:\Users\Admin\Documents\Flex Builder 3\FlexProject\src\com\adobe\flex\extras\controls\AutoComplete.as:179]
    at controller.commands::AutoCompleteCmd/execute()[C:\Users\Admin\Documents\Flex Builder 3\FlexProject\src\controller\commands\AutoCompleteCmd.as:48]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\UIComponent.as:9298]
    at view.components::HLabeledAutoFill/delayedCall()[C:\Users\Admin\Documents\Flex Builder 3\FlexProject\src\view\components\HLabeledAutoFill.mxml:168]
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()
    how to resolved?.. help me

      1. yes..
        When i clicked backspace this error occured.Not at all time but some time.The process is when i enter two letters it goes to a backend call and return list of values that are matched..

    1. I’m not sure, I just tried it in a simple test application and it seems to be working for me. Are you using the latest version (v1.2). If you could put together a sample application which demonstrates the issue I’d be happy to help you debug it.

  33. Hi, thanks for this great component.

    I have a question.

    When i type “sche” in the autocomplete textinput, i get two options. When i click the second, the first one is selected. Is this a bug?

    Thanks!

    1. Are you seeing this behavior in the demo? I’m having trouble replicating it, if you could send me a sample application which demonstrates the issue I’d be happy to help debug it.

Leave a Reply to sachin Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s