Flex Type Ahead DropDownList - apache-flex

I need to implement multi character type ahead functionality on a DropDownList. Im using spark components Flex 4.5.1.
I wish the long list to for example if I type bl
It will go to Blue not to the first B then the first L
Its a common requirement and all browsers now support it, hope its something that already exists or someone has customized a version.

Why wouldn't you use the Flex Spark ComboBox, which has the type ahead feature built right in?

You can probably customize one of the many autocompletes. I posted the following snippet in another question on how to do an autocomplete.
package autoCompleteExample
{
import mx.collections.ICollectionView;
import mx.collections.IList;
import spark.components.ComboBox;
import spark.events.TextOperationEvent;
public class AutoCompleteExample extends ComboBox
{
override protected function textInput_changeHandler(event:TextOperationEvent):void{
super.textInput_changeHandler(event);
ICollectionView(dataProvider).refresh();
}
override public function set dataProvider(value:IList):void{
ICollectionView(value).filterFunction = defaultFilterFunction;
super.dataProvider = value;
}
private function defaultFilterFunction(item:Object):Boolean{
return (textInput.text.toLowerCase() == String(item[labelField].toLowerCase()).substr( 0, textInput.text.length ));
}
}
}
You can probably just change the text operation handler to select the first item AFTER the refresh. Not sure how well it would work.

Related

Flex List Scroll Speed With Mouse Wheel

I have a custom class that extends List which I am using as a container. However, the scroll speed is too fast on the mouse wheel, as in it scrolls loads even if you only move the wheel a tiny bit. I tried adding an event listener to my list for MouseEvent.MOUSE_WHEEL and setting the value of event.delta but this has had no effect. Does anyone know how I can make it slower?
My custom class is nothing special, I just created it so I could have a different itemRenders for different item types. It looks like:
public class MultipleRenderersList extends List
{
override public function createItemRenderer(data:Object):IListItemRenderer
{
if (data is IRenderable)
{
return data.getDiaryRenderer();
}
else if (data is Array)
{
if (data.length > 0)
{
if (data[0] is IRenderable)
{
return data[0].getDiaryRenderer(data);
}
}
}
return null;
}
}
The List class has a mouseWheelHandler function that you can override. Just override the function, update the delta property of the mouseevent, and call super. This example will quarter the delta, reducing the speed substantially:
package
{
import flash.events.Event;
import flash.events.MouseEvent;
import mx.controls.Alert;
import mx.controls.List;
public class MyList extends List
{
override protected function mouseWheelHandler(event:MouseEvent):void {
event.delta = event.delta/4;
super.mouseWheelHandler(event);
}
}
}
However, in many cases the scroll speed / delta will be driven off of a system preference, so doing this may cause unexpected behavior for some users. The reason that adding the handler and updating the delta failed to work is that by that point mouseWheelHandler had already been called.
A very simple way to modify this is to change the verticalLineScrollSize property. This is a property of all containers and it defaults to 5. (for flex 3)
Actually, what HandOfCode said isn't relevant here. Because he made the same mistake as i did, which is to think that a List component or TileList component are containers. They aren't. So, they don't have verticalLineScrollSize property.
Sean solution is the only one that worked for my case. I would add that event.delta may have a positive or negative value depending of the direction of the wheel action. So you better do something like this if you plan to scroll, for example one line at a time :
override protected function mouseWheelHandler(event:MouseEvent):void
{
event.delta = (event.delta > 0) ? 1:-1;
super.mouseWheelHandler(event);
}

Handling error conditions on Flex

I have the following AS code.I have noticed that if an Application i s using the webcamera then it cannot be used by any secondary applications until unless the primary application is closed.
My question is that from the following code 1.can we capture that condition
2.If no camera is detected how to give the alert since it is an AS code
EDIT:
Filename is cldAS.as
Now how to call cldAS() from any.mxml file .Some example would be appreciated
package org.com
{
import flash.display.Sprite;
import flash.media.*;
import flash.net.*;
public class cldAS extends Sprite
{
public function cldAS()
{
var cam:Camera = Camera.getCamera();
if(cam != null)
{
cam.setMode(640, 480, 30);
var video:Video = new Video(300, 450);
video.attachCamera(cam);
addChild(video);
}
else
{
trace("No Camera Detected");
//How to give an alert here
}
}
}
}
Alert.show("You don't seem to have a webcam.");
instead of
trace(...) ?
Alert is available in Flex only , in AS3 you should really implement your own solution, on the other hand , since Alert is a Javascript function , you could also use ExternalInterface to call it.
As far as implementing your own solution is concerned, at the minimum you need a TextField to display your message, which text you could provide by sending a CustomEvent with a message property that will simply take a String. It wouldn't take too much work to create your own Alert class.It would sit on top of your App , you could toggle visibility when receiving a CustomEvent and have a Close button to hide it.
You should be able to call your AS3 class within script tags , other than that I'll leave a more detailed answer to Flex experts. I'm not sure if you can add a Sprite directly into Flex , for all I remember an object in Flex must inherit from UIComponent in order to be added to the stage but check with the other guys here, I haven't used Flex in quite some time...
<mx:Script>
import org.com.cldAS;
public cld:cldAS = new cldAS();
</mx:Script>

Can't apply filter to Sprite

I have this simple class:
import spark.effects.GlowFilter;
public class Letter extends Sprite {
private var glowFilter:GlowFilter = new GlowFilter();
public function Letter() {
filters = [glowFilter];
}
}
And in gaves "Error #2005: Parameter 0 - incorrect type. Should be type Filter" in runtime. If I change parent class to UIComponent everything works great. But I do not need all UIComponent functionality, I need just that damn filter works. =)
So, the question is what is the problem? Why it is not working with "Sprite" as parent class?
Using Flex 4.1.
You are trying to apply a flex specific filter to a non flex based object.
Try changing the import to
import flash.filters.GlowFilter;
This will use the standard flash filter instead.

Select multiple items in Flex Tree control without pressing the Ctrl key?

I'm trying to modifty the Flex Tree control to allow a user to select multiple items by just clicking each of the desired elements (ie I don't want them to have to press Ctrl or Shift). If the user clicks a selected item a 2nd time, it will deselect it. Can anyone help me out?
Thanks!
I just had to do this with a datagrid, since they are both based on list it will work for you too
How can I get a datagrid to behave like the ctrl key is active?
You can create a simple custom component of ur own. Here is the code:
package com
{
import flash.events.MouseEvent;
import mx.controls.Tree;
public class ForceCtrlTree extends Tree
{
override protected function mouseClickHandler(event:MouseEvent):void
{
event.ctrlKey = true;
super.mouseClickHandler(event);
}
override protected function mouseDownHandler(event:MouseEvent):void
{
event.ctrlKey = true;
super.mouseDownHandler(event);
}
}
}
Import this package into your project.
Then declare the tree component as follows:
Now you need not click ctrl to select multiple objects.

How can I get a datagrid to behave like the ctrl key is active?

I want my data grid to behave by default as if the user is holding the control key down. So when an item is clicked, then another item they are both part of the selection, clicking them again removes them from the selection.
I already have allowMultipleSelection = true but I can't seem to find any setting that does this. I'm working on the itemclick event in the meantime, but it seems like there might be an easy to use setting I'm missing.
Any thoughts?
You could also extend DataGrid and override the selectItem method like so:
override protected function selectItem(item:IListItemRenderer, shiftKey:Boolean, ctrlKey:Boolean, transition:Boolean = true):Boolean
{
return super.selectItem(item, shiftKey, true, transition )
}
Less code and less likely to have impact on other elements that might be listening for that MouseEvent.
You could try adding event listeners to the grid for MouseEvents (UP and/or DOWN) with the highest priority, stopping propagation, and redispatching a new MouseEvent with the same properties on the original event.target but this time with ctrlKey=true.
I'm not sure if it'll cause 10,000 other things to break.
I tried Nalandial's idea but had no luck...can't really intercept those events, but it got me going in the right direction. Worked a lot on this then found that the solution was a lot simpler than I was making it. I just needed to extend the dataGrid class and override two functions (mouseDownHandler and mouseClickHandler) adding the ctrlKey = true there then calling the rest of the function workes perfectly. In case you want to implement it, here's the code:
package com{
import flash.events.MouseEvent;
import mx.controls.DataGrid;
public class ForceCtrlDataGrid extends DataGrid{
public function ForceCtrlDataGrid(){
super();
}
override protected function mouseClickHandler(event:MouseEvent):void{
event.ctrlKey = true;
super.mouseClickHandler(event);
}
override protected function mouseDownHandler(event:MouseEvent):void{
event.ctrlKey = true;
super.mouseDownHandler(event);
}
}
}

Resources