开发者

Working on a Global Search tool - Just like on MAC

开发者 https://www.devze.com 2022-12-17 21:14 出处:网络
Hi I am working on a search tool for my website in Flex. I want it to work exactly likethe \"Spotlight\" tool on MAC desktop. \"http://www.recipester.org/images/6/66/How_to_Use_Spotlight_to_Search_on_

Hi I am working on a search tool for my website in Flex. I want it to work exactly like the "Spotlight" tool on MAC desktop. "http://www.recipester.org/images/6/66/How_to_Use_Spotlight_to_Search_on_Mac_OS_X_42.png" The link is to an image of spotlight.

I want to create almost the same thing in FLEX. What I currently have is a "Autocomplete" box, and I get all the data I want in it. Code for the autocomplete is below:

<auto:AutoComplete borderStyle="none" id="txt_friends_search" 
        textAlign="left" prompt="Search Friends" dataProvider="{all_friends_list}" 
        allowEditingNewValues="true" allowMultipleSelection="true" allowNewValues="true" 
        backspaceAction="remove" labelField="label"
        autoSelectEnabled="false" matchType="anyPart" 
        height="23" right="400"  top="1" dropDownItemRenderer="{new ClassFactory(weather.index_cloud_global_search_item_renderer)}" />

And my ItemRenderer looks like :

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox 
    xmlns:mx="http://www.adobe.com/2006/mxml" 
    width="100%" height="100%" 
    verticalGap="0" horizontalGap="0"
    creationComplete="init()"
    verticalScrollPolicy="off" horizontalScrollPolicy="off" 
    verticalAlign="middle">
    <mx:Script>
        <![CDATA[
            import mx.controls.Alert;
            import mx.collections.ArrayCollection;
            import com.hillelcoren.utils.StringUtils;
            import mx.utils.StringUtil;
            import mx.events.FlexEvent;
            import mx.controls.List;

        public function init():void
        {

        }                                                           
    ]]>
</mx:Script>

<mx:HBox width="100%" verticalGap="0" horizontalGap="0">
    <mx:HBox borderThickness="1" width="75" borderStyle="solid" horizontalAlign="left" horizontalScrollPolicy="off">
        <mx:Label id="type"  text="{data.type}" fontSize="12"/> 
    </mx:HBox>
    <mx:HBox borderThickness="1" width="75" borderStyle="solid" horizontalAlign="left" horizontalScrollPolicy="off">
        <!--mx:Label id="nameLabel"  text="{data.label}" fontSize="12"/-->
        <mx:List id="names" dataProvider="{all}"    
    </mx:HBox>      
</mx:HBox>      

<!--mx:Box id="colorBox" borderStyle="solid" width="50" height="25"/-->
<mx:Spacer width="15"/>

This shows the type and label of everything, example:

  • Friends ABC
  • Friends开发者_高级运维 XYZ
  • Messages This is the message
  • Messages example for messages
  • Files filename1
  • Files filename123

I believe you get my point there.

But what I want to create is something like:

Friends ABC XYZ Messages This is the message example for messages Files filename1 filename123 MoreFiles

Can someone plz help me in this. I actually have no idea how to move forward in this.

Let me know if you want more clarification on anything.

Regards Zeeshan


Since you're offering a bounty, I'll submit a different answer (as the previous one is technically valid).

Step #1: Download the Adobe Autocomplete Component integrate the class into your project.

Step #2: Create a new component that is derived from AutoComplete (I called mine SpotlightField.mxml)

<?xml version="1.0" encoding="utf-8"?>
<AutoComplete 
    xmlns="com.adobe.flex.extras.controls.*" 
    xmlns:mx="http://www.adobe.com/2006/mxml"
    creationComplete="init()"
    labelField="value"  
    itemRenderer="SpotlightFieldRenderer">

    <mx:Script>
        <![CDATA[

            private function init() : void
            {
                this.filterFunction = substringFilterFunction;
            }                                                       

            private function substringFilterFunction(element:*, text:String):Boolean
            {
                var label:String = this.itemToLabel(element);
                return(label.toLowerCase().indexOf(text.toLowerCase())!=-1);
            }
        ]]>
    </mx:Script>        
</AutoComplete>

Step #3: Create the ItemRenderer you want to apply to this new component (I called mine SpotlightFieldRenderer.mxml). Note that the code is the same as the previous example, but I'll post it again for completeness.

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[

        ]]>
    </mx:Script>

    <mx:HBox width="100%">
        <mx:Label width="100" text="{data.type}" />
        <mx:Label text="{data.value}" />
    </mx:HBox>
</mx:Canvas>

Step #4: Update the AutoComplete.as class as follows:

/**
 *  @private
 *  Updates the dataProvider used for showing suggestions
 */
private function updateDataProvider():void
{
    dataProvider = tempCollection;
    collection.filterFunction = templateFilterFunction;
    collection.refresh();

    sort_and_filter(collection);

    //In case there are no suggestions, check there is something in the localHistory
      if(collection.length==0 && keepLocalHistory)
      {
        var so:SharedObject = SharedObject.getLocal("AutoCompleteData");
        usingLocalHistory = true;
        dataProvider = so.data.suggestions;
        usingLocalHistory = false;
        collection.filterFunction = templateFilterFunction;
        collection.refresh();
      }
  }

private function sort_and_filter(source:Object):Object
{
    if (source && source.length > 1) {   
        trace (source.length);  
        source.sortOn('type', Array.CASEINSENSITIVE);           
        var last:String = "";
        for each(var entry:Object in source) {      
            var current:String = entry.type;
            if (current != last)            
                last = current      
            else
                entry.type = "";
            last = entry.type;
        }
    }

    return source;
}  

You'll notice that the sort_and_filter function is defined, and called on the collection within updateDataProvider. The app now looks like this:

Working on a Global Search tool - Just like on MAC

That's it. The sample application now looks like this:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*">
    <mx:Script>
        <![CDATA[
            [Bindable]
            private var items:Array = [
                { type:'friends', value:'abc' },
                { type:'friends', value:'xyz' },
                { type:'messages', value:'this is the message' },
                { type:'messages', value:'example for messages' },
                { type:'files', value:'filename1' },
                { type:'files', value:'filename123' },
            ];
        ]]>
    </mx:Script>        
    <local:SpotlightField dataProvider="{items}" width="400" />
</mx:Application>

Let me know if you have any further questions. There is still a bit of work to do depending on how you want to display the results, but this should get you 95% of the way there ;)


You may want to try something like this. This is just a sample I whipped up, but the basics are there for you to apply to your solution. What this is doing is creating a custom item render (as you've already done), but the container that it's rendering, it adjusts the data set slightly within set dataProvider so that it sorts and filters.

Working on a Global Search tool - Just like on MAC

Obviously, you can expand upon this even further to add common icons, formatted text ... etc. The renderer has an explicit width set for the first "column" text. This is to better align results, but should probably be done while the list is being built (based on the string lengths of the values in the result set). Cheers ;)


Application.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:local="*">
 <mx:Script>
  <![CDATA[
   [Bindable]
   private var items:Array = [
    { type:'friends', value:'abc' },
    { type:'friends', value:'xyz' },
    { type:'messages', value:'this is the message' },
    { type:'messages', value:'example for messages' },
    { type:'files', value:'filename1' },
    { type:'files', value:'filename123' },
   ];
  ]]>
 </mx:Script>
 <local:SpotlightComboBox 
  dataProvider="{items}"   
  width="400" />
</mx:Application>

SpotlightComboBox.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:ComboBox 
 xmlns:mx="http://www.adobe.com/2006/mxml"
 itemRenderer="SpotlightComboBoxItemRenderer">

 <mx:Script>
  <![CDATA[   
   override public function set dataProvider(value:Object):void 
   {
    super.dataProvider = sort_and_filter(value as Array);
   } 

   private function sort_and_filter(source:Array):Array
   {
    if (source && source.length > 1) {     
     source.sortOn('type', Array.CASEINSENSITIVE);
     var last:String = "";
     for each(var entry:Object in source) {      
      var current:String = entry.type;
      if (current != last)            
       last = current      
      else
       entry.type = "";
      last = entry.type;
     }
    }

    return source;
   }     
  ]]>
 </mx:Script>

</mx:ComboBox>

SpotlightComboBoxItemRenderer.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:Script>
  <![CDATA[

  ]]>
 </mx:Script>

 <mx:HBox width="100%">
  <mx:Label width="100" text="{data.type}" />
  <mx:Label text="{data.value}" />
 </mx:HBox>
</mx:Canvas>
0

精彩评论

暂无评论...
验证码 换一张
取 消