views:

1696

answers:

3

I have a simple slider, with only 3 options. It seems strange to force the user to drag the small thumbnail on the slider, when it would be a lot easier to click one of the 3 actual labels by the side of the slider. Does anyone know how to accomplish this?

A: 

Are you sure a slider is the best component to use in this case? Generally speaking, sliders are to be used when the user has a large range of contiguous options to choose from, where the precision of a user's choice doesn't really matter (e.g. a volume slider - having volume at 51% as opposed to 50% really won't make much of a difference).

If you only have three options, and the user is only allowed to select one of those three options, I would suggest using either a combo box or a radio button group.

Dan
Hi, the slider represents size, going from small -> medium -> large. The slider makes sense in this case because you are showing the increasing size with the slider. At the moment there are 3 fixed sizes, but in the future the restriction might be removed and it could be any size between x and y.
Mark Ingram
Ahh OK, I can see why you'd want to take this approach then.That being said, I did look at the Flex docs, and I don't think there is an easy way to get clickable labels. The slider class just contains an array of Labels which correspond to the ticks. You might have some luck subclassing Label and adding click listeners, but I haven't tried it myself.
Dan
+1  A: 

This is a cool problem.

The Label object used by Slider turns out to be a subclass of Label (called SliderLabel). So, probably the best approach would be to subclass Slider and add event listeners to the labels.

I think you could successfully add event listeners in either the commitProperties method or the updateDisplayList method. I'm not sure if one would be preferable to the other, but commitProperties seems like the more correct choice.

So, in your subclass of Slider:

override protected function commitProperties():void
{
    super.commitProperties();

    for(var i:int = 0; i < labelObjects.numChildren; i++)
    {
        if(!SliderLabel(labelObjects.getChildAt(i)).hasEventListener(MouseEvent.CLICK))
        {
            SliderLabel(labelObjects.getChildAt(i)).addEventListener(MouseEvent.CLICK,sliderLabelClickListener);
        }
    }
}

and then maybe something like this for sliderLabelClickListener:

private function sliderLabelClickListener(e:MouseEvent):void
{
    dispatchEvent( new SliderLabelClickEvent(e.target) );
}

I think you'd want a custom event there, rather than dispatching a regular Event, so you could include the name/id/value of the label.

Also, you may want to put in a 'dispose' method to remove the CLICK event listener from the labels when the Slider is removed from the stage. It's not an issue if you aren't going to be removing the Slider, but if you are, what I normally do is create a method called dispose and put all my manual removal logic there (removing event listeners, unwatching/removing ChangeWatchers). Then I assign a listener to the component's REMOVED_FROM_STAGE event and call the dispose method from that listener.

Ross Henderson
That sounds interesting. I'll try and get this working - thanks!
Mark Ingram
A: 

Hi rhtx,

The solution that you have given is not clear to me... can you please send one sample.....