I want to know, how do I get the selected index, if I change the selection of a datagrid row. I´ve searched a lot and have found only the Adobe site
This is what I think is the right way:
myGrid.addEventListener(DataGridEvent.ITEM_FOCUS_IN, datagridchanged);
//DataGrid Changed Listener function
private function datagridchanged (e:DataGridEvent):void{
trace(e.selectedIndex); //Don`t know if .selectedIndex is correct
}
But nothing works, if someone could help me please?
Thanks in advance
If you simply want to know which item has been selected, you can listen to Event.CHANGE on your DataGrid.
Like this, for example:
mygrid.addEventListener(Event.CHANGE, onGridSelectedItem);
function onGridSelectedItem(e:Event):void{
var selected:int = mygrid.selectedIndex;
var item:Object = mygrid.selectedItem;
}
Related
I am new to the actionscript side of flash,
I am working on a map that has say 20 popups(movieclips) and the countries are the buttons, i have just been informed i need to add 60 more.
Below is an example of the code i have been using
english_movie.visible=french_movie.visible=turkish_movie.visible=false
english_btn.addEventListener(MouseEvent.CLICK, englishButtonClick);
french_btn.addEventListener(MouseEvent.CLICK, frenchButtonClick);
turkish_btn.addEventListener(MouseEvent.CLICK, turkishButtonClick)
function englishButtonClick(event:MouseEvent):void {
english_movie.visible=true;
english_movie.play();
french_movie.visible=turkish_movie.visible=false
}
function frenchButtonClick(event:MouseEvent):void {
french_movie.visible=true;
french_movie.play();
english_movie.visible=turkish_movie.visible=false
}
function turkishButtonClick(event:MouseEvent):void {
turkish_movie.visible=true;
turkish_movie.play();
english_movie.visible=french_movie.visible=false
}
Im thinking there must be an easier way to do this than replicating the code over and over.
Any help would be much appreciated.
Here's how to simplify the whole thing with code: Each btn object is
related to one movie object. This can be achieved with a Dictionary.
var btnToMovieAssociation:Dictionary = new Dictionary();
btnToMovieAssociation[english_btn] = english_movie; // repeat this line for every btn/movie pair
Now you have to generalise your click handler. The key difference
between each function (apart from making one certain movie visible)
is that they all make certain other movies invisible. But actually,
it's sufficient to only make the previously visible movie invisble.
To do this, create a variable that keeps track of the current visible
movie.
var currentMovie:MovieClip = english_movie;
Initialising the variable with english_movie has no effect on the
program. you can pick any other of the movies. It will make things
easier in the following code if this variable is initialised.
Now your function does effectively this:
make movie of clicked button visible
play this movie
make last movie invisible
Here's the cool part. You only add one listener. Look up if something
is in the dictionary for the clicked thing and consider that the
movie you want to show next.
addEventListener(MouseEvent.CLICK, buttonClick);
function buttonClick(event:MouseEvent):void
{
var movie:MovieClip = btnToMovieAssociation[event.target]
if (movie == null)
return; // nothing in the dictionary, it wasn't a button that was clicked.
movie.visible=true;
movie.play();
currentMovie.visible = false;
currentMovie = movie;
}
There are problems with this solution:
You still have to declare every pair, which is still tedious and prone to erro. (you have to type every name twice)
If your buttons are made up of several objects, event.target might point to them instead of the button as a whole. But with only
the btns in the dictionary and not all their individual parts,
nothing would be found in the dictionary. This can be circumvented by
setting mouseChildren = false; on every btn.
i posted this question else where and got this response
var tl:MovieClip=this;
var mc:MovieClip;
var i:int;
var buttonA:Array=[english_btn,french_btn,turkish_btn];
for(i=0;i<buttonA.length;i++){
buttonA[i].addEventListener(MouseEvent.CLICK,buttonF);
tl[buttonA[i].name.split("_")[0]+"_movie"].visible = false;
}
function buttonF(e:MouseEvent):void{
for(i=0;i<buttonA.length;i++){
tl[buttonA[i].name.split("_")[0]+"_movie"].visible = false;
}
tl[e.currentTarget.name.split("_")[0]+"_movie"].visible=true;
}
Which works great.
I have searched arond, but cant seem to find a proper answer to this. Lets say we have a super basic program which adds two numbers from 2 input text fields togehter and prints them out. Why cant i accses variables outside the event handler function? And what do i have to do in order to achieve this? The code is on a frame.
Why does this example not work? :
btn.addEventListener(MouseEvent.CLICK, cal);
var fnum:Number = Number(txt1.text);
var snum:Number = Number(txt2.text);
function cal(evt:MouseEvent){
txtOutput.text = String(fnum + snum);
}
And this example work?:
btn.addEventListener(MouseEvent.CLICK, cal);
function cal(evt:MouseEvent){
var fnum:Number = Number(txt1.text);
var snum:Number = Number(txt2.text);
txtOutput.text = String(fnum + snum);
}
I hate to be this guy, but I can't get it to replicate whats happening for you..
The only assumption that I can make is that the txt1.text & txt2.text aren't set yet when the button is clicked in example 1. Feel free to zip your project and dropbox it to me if you want me to investigate further :)
My situation is this:
I've got several (2+) MovieClips on the stage.
Each one contains an input-textbox in addition to the background.
When I click the first MovieClip, it gets selected and a light blue shadow is displayed to indicate it like so: http://puu.sh/aueAw/3575e83aca.png
If I click the second one, it looks like this: http://puu.sh/aueEj/826e1c9cb9.png
However, when the second MovieClip's textbox is clicked, the first MovieClip becomes selected! This doesn't make any sense to me.
What could be causing this? Everything works as it should as long as I don't take these nested textboxes into account.
Thanks in advance for your helpful answers!
Best regards,
Olin K.
EDIT: Here's the code that I use to add event listeners to the MovieClips.
public function updateVisualDocument()
{
if (!uniDocument.isEmpty())
{
//Update the Visual Document if the current Document contains any pages
visualDocument.uniPage.gotoAndStop(uniDocument.getCurrentPage().getLayout());
visualDocument.uniPage.pageNumber.text = uniDocument.getPageIndex();
//Update Thumbnails
for each (var someThumb in thumbnailArray)
{
someThumb.deselect();
}
thumbnailArray[uniDocument.getPageIndex() - 1].select();
for (var i:int = 0; i < visualDocument.uniPage.panelContainer.numChildren; i++)
{
var somePanelMC = visualDocument.uniPage.panelContainer.getChildAt(i);
if (!uniDocument.getCurrentPage().hasPanels())
{
uniDocument.getCurrentPage().addPanel(somePanelMC);
}
somePanelMC.addEventListener(MouseEvent.CLICK, panelClicked);
uniDocument.getCurrentPage().getPanel(i).setPanelMC(somePanelMC);
function panelClicked(e:Event)
{
//Panel gets selected
var panelIndex:int = int(e.target.name.substring(5));
uniDocument.getCurrentPage().deselectAllPanels();
uniDocument.getCurrentPage().getPanel(panelIndex).select();
}
}
uniDocument.getCurrentPage().panelsAreFull();
uniDocument.getCurrentPage().selectFirst();
}
}
EDIT: I tried changing the textbox to the dynamic text (from the input text) type and the problem is still exactly the same. I click the textbox, it selects the first MovieClip. I think it may have to do with using the same instance name, but since it's nested, why should it matter?
Looks like I figured it out on my own. Partially. I worked off what LDMS said in his comment "did you accidentally give them the same instance name?"
Well, no, I didn't. BUT- the textboxes all had the same instance name. This is irrelevant, but it got me focused on the textboxes names, and I realized that since I had mouseChildren set to false, the textboxes were the ones firing off the event listener.
So I changed up a bit of my code to look like this:
function panelClicked(e:Event)
{
//Panel gets selected
if (!e.target.name == "myText")
{
var panelIndex:int = int(e.target.name.substring(5));
uniDocument.getCurrentPage().deselectAllPanels();
uniDocument.getCurrentPage().getPanel(panelIndex).select();
}
}
And now it works! It's a simple workaround, since doing myText.mouseEnabled = false; was not an option because it needed to be clicked.
Hope this helps someone in the future! Cheers!
I was reading a tutorial on how you can make a turret follow the mouse, for a game, and I stumbled across something I've never seen before.
private function showGhostTurret(e:MouseEvent = null):void
{
var target_placeholder:Sprite = e.currentTarget as Sprite;
ghost_turret.x = target_placeholder.x;
ghost_turret.y = target_placeholder.y;
ghost_turret.visible = true;
}
I've never seen someone set the (e:Event) to null, like in the first line. Could someone please explain the purpose of doing this? Let me know if you need more information to answer.
Thanks.
That is a default parameter value. What it means is that the parameter e is optional so you can opt to not include it in a call to showGhostTurret() and e will be assigned the value null.
I'm not sure how that's useful in this particular case since, looking at the body of the function, e is most definitely required. You said this was part of a tutorial -- maybe it becomes useful later on?
I'm implementing some kind of combobox control (by extending spark.components.supportClasses.DropDownListBase)
Now, inside this control; I need to know:
if the dataprovider is changed/assigned. (which I can do... the first approach below works);
if any item in the dataprovider collection has changed.
I tried 2 methods that did not do the trick...
1ST APPROACH:
[Bindable("collectionChange")]
override public function set dataProvider(value:IList):void
{
if (value) value.addEventListener(CollectionEvent.COLLECTION_CHANGE, onDataChange);
super.dataProvider = value;
trace("DATA CHANGED"); //fires
}
protected function onDataChange(event:CollectionEvent):void
{
trace("COLLECTION ITEM(S) CHANGED"); //does not fire
}
2ND APPROACH:
Since this is based on DropDownListBase; it should dispatch the CollectionEvent.COLLECTION_CHANGE event already..?
public function myClass() //constructor
{
addEventListener(CollectionEvent.COLLECTION_CHANGE, onDataChange);
}
protected function onDataChange(event:CollectionEvent):void
{
trace("DATA CHANGED"); //does not fire
}
Any ideas?
UPDATE: Edited above.. The first approach lets me know if the dataprovider is changed but not if any item is updated in the dataprovider collection. The second approach does not work at all..
We'll be able to help significantly more if you show us a runnable sample to demonstrate the problem.
if the dataprovider is
changed/assigned.
Your first approach should work. Can you tell us what makes you think it didn't? ( No trace statement I assume? ). And tell us what you did to change the dataProvider.
The second approach won't work because myClass is not firing off the collectionChange event.
2 if any item in the dataprovider collection has changed.
There is not really a way to tell this. In most cases, a collection is just a list of pointers to other objects. If you change those pointers, then a collectionChange event is fired. IF you change the item that he pointer is pointed to, the collection has no way to know that something changed. Binding works very similarly if your an MXML fan.
If you have control over how items are changed, you can deal with it that way. Instead of:
(collection.getITemAt(x) as myObject).property = newValue;
Do something like this:
var myObject : MyObject = collection.getITemAt(x) as myObject
myObject.property = newValue;
collection.setItemAt(x, myObject);
I would expect that to fire a collectionChange event, but not the former.
That said, in the context of a dropDownListBase: As you scroll or open and close the drop down, the itemRenderers should be updated to reflect the most current dataProvider's data. But if you change something on the fly while the drop down is open, I would not expect it to update automatically [if you're not changing the dataProvider.