ComboBox Bug in ActionScript - actionscript-3

I was trying to filter a combo box dataprovider based on the values in the text boxes . When the contents of the dataprovider changes Combo box automatically calls change event method . Please find the sample code below.
Filter Utility Function:
private function filterLocations(event:FocusEvent):void {
locationsList1.filterFunction = filterUtility;
locationsList1.refresh();
}
public function filterUtility(item:Object):Boolean {
// pass back whether the location square foot is with in the range specified
if((item.SQUARE_FOOTAGE >= rangeText1.text) && (item.SQUARE_FOOTAGE rangeText2.text))
return item.SQUARE_FOOTAGE;
}
// THIS WOULD BE CALLED WHEN COMBO BOX SELECTION IS DONE
private function selectLocationsReports(event:ListEvent):void {
selectedItem =(event.currentTarget as ComboBox).selectedItem.LOCATION_ID;
}
When the DataProvider gets refreshed its automatically calls change method and was throwing Null Pointer function because its prematurely calling the above selectLocationsReports method and its throwing error.
Can somebody let me know how to stop the CHANGE event from propogation when the dataprovider is refreshed.

You can't stop a CHANGE event, just don't add an event listener unless you are prepared to get the event. I don't see where your event listener for Event.CHANGE is in the code above.
Just be sure that you don't addEventListener(Event.CHANGE, selectLocationsReports) until your ComboBox is ready for it.

The other thing to do (on top of Kekoa's response) is put an if statement in the event handler, and check to make sure the data is there before you begin working with it.

A handy syntax I use frequently for this is
if(dataprovidername) {
}

Related

Removing an EventListener from an object decided via an Array

I am making a simple calculator for an assignment in my IT-Class. It has 3 textboxes where the user can add his numbers, and the boxes start with a "0" inside of them, to show that the user is supposed to write numbers here. What I wanna do, is have this zero go away as the user puts focus on the box.
Since I have 3 boxes, I wanted to make the EventListener call up a function that removes the text and the Eventlistener, instead of writing the same code 3 times.
Using an array containing the different textboxes I managed to call them up, and change the text as I wanted, but the EventListener isn't being removed, so the text the user writes in is being removed when they focus on the textbox again
///////////////////////////////////////////////////////////////////////////////////
//The Array containing all the TextFields
var textFieldArr:Array = new Array(txtNumber1,txtNumber2,txtNumber2)
function onFocus(i:int){
return function (evt:FocusEvent){
textFieldArr[i].text = "";
textFieldArr[i].removeEventListener(FocusEvent.FOCUS_IN, onFocus(i))
}
}
//Calls up the onFocus function and declares variable i
txtNumber1.addEventListener(FocusEvent.FOCUS_IN, onFocus(0));
txtNumber2.addEventListener(FocusEvent.FOCUS_IN, onFocus(1));
txtNumber3.addEventListener(FocusEvent.FOCUS_IN, onFocus(2));
///////////////////////////////////////////////////////////////////////////////
Your event listener isn't being removed, because when you call onFocus(i) within the removeEventListener param, you are being returned a new function, and not the function that was originally being triggered by the event. The other problem with your code is that 'i' does not exist in the listener function you have declared -- you need to use only the properties of evt to figure out which text field to target, and the correct event listener to remove.
The common/correct way to do this is to use a event-accepting function, and listen to each text field with it. You don't even need the array anymore unless you have some other use for it.
function onFocusIn(evt:FocusEvent):void{
trace("onFocusIn("+evt.target+")");
var focusedField:TextField = TextField(evt.target);
if(focusedField){
focusedField.text = "";
focusedField.removeEventListener(FocusEvent.FOCUS_IN, onFocusIn);
}
}
txtNumber1.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
txtNumber2.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
txtNumber3.addEventListener(FocusEvent.FOCUS_IN, onFocusIn);
Listener is not removed, because onFocus returns on each invocation new Function instance.
You might try use target property of FocusEvent class:
var textFieldArr:Array = new Array(txtNumber1,txtNumber2,txtNumber2)
function onFocus(evt:FocusEvent){
TextField(evt.target).text = "";
TextField(evt.target).removeEventListener(FocusEvent.FOCUS_IN, onFocus)
}
//Calls up the onFocus function and declares variable i
txtNumber1.addEventListener(FocusEvent.FOCUS_IN, onFocus);
txtNumber2.addEventListener(FocusEvent.FOCUS_IN, onFocus);
txtNumber3.addEventListener(FocusEvent.FOCUS_IN, onFocus);

Validation in flex input text field

i have a program in flex wherein i check if a particular field is validated then the submit button is enabled. I am trying something like this:
public function init():void
{
submit.addEventListener(Event.CHANGE,enableSubmit);
}
public function enableSubmit(event:TextInput):void
{
//some code to enable the button
}
I can call init in creation complete to add event listener to submit! is this the correct way to do it ? Please help!
Yes, you can call the init in the creationComplete.
The only thing you need to change in your code is the parameter of the enableSubmit from TextInput to Event because the event is passed by parameter, like the code below:
public function enableSubmit(event:Event):void
{
//some code to enable the button
}
Also the event listener need to be added to the TextInput, so I am assuming that submit control is the TextInput submit.addEventListener(Event.CHANGE,enableSubmit);

Calling certain functions whitout having the right arguments

I have two function on my AS3 program, one fires when the width and height changes:
stage.addEventListener(Event.RESIZE, resizeListener);
function resizeListener (e:Event):void {
//some commands
}
And the second one fires one a number of milliseconds pass:
var myTimer:Timer = new Timer(clockUpdate, 0);
myTimer.addEventListener(TimerEvent.TIMER, updateData);
myTimer.start();
function updateData(e:TimerEvent):void {
trace("AUTOUPDATE");
trace(e);
}
I need to fires those function also manually, lets say when the user press a button, but i don't know what parameters i have to send them when they are called manually.
I tried just resizeListener() and updateData() but of course it fails asking me for the parameter.
You can make parameters in a function optional by providing a default value. This is an example by taking your two functions above and making the event parameters optional:
function resizeListener(e:Event = null):void {
//some commands
}
and
function updateData(e:TimerEvent = null):void {
trace("AUTOUPDATE");
trace(e);
}
Calling, for example, resizeListener() will now execute the function and the value of e will default to null.
Making the Event parameter optional, resizeListener(e:Event=null), as in walkietokyo's answer, is a perfectly valid and often convenient solution. Another alternative is to put the stuff you want to be able to do without the event being triggered in a separate function, that can be called by the event handler and from anywhere else.
So assuming for example that what you want to do on resize is to rearrange the layout, and you also want to do that same layout setup at initialization, or at the click of a button, or anytime really, you could do something like this:
stage.addEventListener(Event.RESIZE, resizeListener);
function resizeListener(e:Event):void {
rearrangeLayout();
}
function rearrangeLayout():void {
// The actual rearrangement goes here, instead of in resizeListener. This can be called from anywhere.
}
Which way to do it is probably a matter of taste or can vary from case to case, really, both works fine.
A benefit of separating things in an event handler and another function is that there will not arise a situation where you would have to check if the e:Event parameter is null or not. In other words, you would have code that is dependent on the Event, if any, in the event handler, and code that is independent of the Event in a more general function (not an event handler).
So in a more general and schematic case, the structure would be something like this:
addEventListener(Event.SOME_EVENT, eventListener);
function eventListener(e:Event):void {
// Code that needs the Event parameter goes here (if any).
// Call other function(s), for the stuff that needs to be done when the event happens.
otherFunction();
}
function otherFunction():void {
// Stuff that is not dependent on the Event object goes here, an can be called from anywhere.
}

actionscript 3.0 function mouseevent event handler

I have a function that uses a mouse event and it removes and adds things onto the stage:
beginBut.addEventListener(MouseEvent.CLICK, bgnListener);
function bgnListener (event:MouseEvent) {
removeEventListener(Event.ENTER_FRAME, setScreen);
removeChild(beginBut);
removeChild(myWord);
healthBar.addEventListener(Event.ENTER_FRAME, healthLose);
ball.addEventListener(Event.ENTER_FRAME, moveBall);
myGem.addEventListener(Event.ENTER_FRAME, addGem);
myScore.addEventListener(Event.ENTER_FRAME, scoreCount);
healthBar.width+=1000;
}
However after some other things happen, I need this event to occur again. I have already
added beginBut but when I use
beginBut.addEventListener(MouseEvent.CLICK, bgnListener);
the event adds and removes the things automatically when the function that adds beginBut back occurs and not when I actually click on beginBut. I have also tried
bgnListener();
but it says that there is the wrong number of arguments. I already searched all over and I can't seem to fix this. Any help would be greatly appreciated.
If you call bgnListener() like you are now, you'll get an argument mismatch error because the function is expecting to receive a MouseEvent.
If you want to be able to call bgnListener() on its own like that, you can define a default value for your argument event, which can be null:
function bgnListener(event:MouseEvent = null)
{
// ...
}

Can I specify a delay before the browser raises "rollover" event?

I am working on an ASP.NET web application that is required to bring up a popup on a roolover. I am using the "OnMouseOver" event and it works as expected. The problem is that the event is on a "hair trigger"; even a casual passage of the mouse over the control brings up the popup (which then must be manually dismissed). I want to add a delay so that a rapid pass over the control in question does not trigger the event. Is there a way to set such a delay or is there a different event that I could use to get the same "trigger event on a slow rollover"?
One solution that comes to mind, there may be better ways though:
Make the onmouseover call the function via a setTimeout delay
Inside the function, check the mouse is actually over that element.
You could also use an onmouseout to clear the setTimeout, but then you'd have to store a reference to the timer in a global variable to get at it again.
What I ended up doing is as follows (oRow is a table row but it could be any control):
function ItemMouseOver(oRow, "parameters for the popup")
{
oRow.showTimer = window.setTimeout(function()
{
alert('popup');
}, 1000);
}
function ItemMouseOut(oRow)
{
if (oRow.showTimer)
window.clearTimeout(oRow.showTimer);
In the ASP.NET grid view RowDataBound event: I added the following code:
protected void ReportGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && (
e.Row.RowState == DataControlRowState.Normal
|| e.Row.RowState == DataControlRowState.Alternate))
{
// get the input values for the popup for the row (stuff deleted)
e.Row.Attributes["onmouseover"] = "javascript:ItemMouseOver(this,
"parameters for the popup");";
e.Row.Attributes["onmouseout"] = "javascript:ItemMouseOut(this);";
}
}
It works just fine. Thanks.