flex setFocus on creation complete - actionscript-3

Normally, forms and pop Ups don't have the focus set when they are just displayed. The obvious solution was to set the focus to the first input in the creation complete event of the component, so the keyboard short Cuts like tab and space start working.
The problem is that, creation complete is not the panacea, sometimes the element is not focus-able at that point, and i am not sure why that happens.
The render event would ensure the focus, but it dispatches too much for a very simple purpose.
In which point a component is always ready to be focus-able?
Edit: The component giving me trouble to get start up focus, is a TitleWindow, which can be poped in 2 ways, a Mouse click event and a keyboard event.
When the tite window is displayed by a click, the first input gets focus in the creation complete event, but when displayed by a keyboard event, it doesnt...
By now i got it working with the following code:
private function titlewindow_creationCompleteHandler(e:FlexEvent):void{
callLater( setTextInputFocus);
}
private function setTextInputFocus():void{
txtPregunta.setFocus();
}
But doubt the way is shown has anything to do with this... because, some other TitleWindow are displayed this way too and they're fine.
So what could it be?

The render event would ensure the focus, but it dispatches too much for a very simple purpose.
If this is true then why not try this:
private function titlewindow_creationCompleteHandler(e:FlexEvent):void{
var callback : Function = function(re : Event) : void {
titlewindow.removeEventHandler(RenderEvent.orsomething, callback);
setTextInputFocus();
};
titlewindow.addEventHandler(RenderEvent.orsomething, callback);
}
Might be kind of a hack since it should be focusable on creationComplete but it would probably work.

Related

AngularJS: How to block execution until function returns?

I'm trying to display a google map on click with angular JS. But my function seems to be toggling the visibility based on a function call (via ng-show). This means that my trigger of the 'resize' event executes before the map div is actually visible so it doesn't work correctly.
$scope.mapVisible = false;
$scope.toggleMap = function() {
$scope.myMap.panTo($scope.myMarkers[0].getPosition());
$scope.mapVisible = !$scope.mapVisible;
// this executes too soon. How to block until the div is really visible?
google.maps.event.trigger($scope.myMap, 'resize');
}
<div ng-show="mapVisible">
<!-- map here -->
</div>
So how can I block triggering the 'resize' event on my map until the div is truly visible?
$scope.$watch("mapVisible", function (val) {
if (val) {
google.maps.event.trigger($scope.myMap, "resize");
}
});
This would make sure the map is visible before triggering the event.
Angularjs handles two-way binding by doing dirty-checking. It basically means that the value being watched is compared to the one in previous cycle. Each cycle ($digest) starts to run when something happens which could possibly change any value in the scope. If there is a change in the value, it would be reflected after the cycle has completed.
Back to your problem, when you toggle the mapVisible property, the view does not update immediately. It waits for the cycle to end before redrawing the view. But you fire the resize event so early, when the map is still invisible, therefore rendering invalid.
$watch does indeed watch the property and the changes will be reflected in the next cycle of the change, which means the view would be updated by the time watcher function has been invoked. Putting the resize function here would hence solve your issue.
I figured the easiest case is to use the $timeout service:
scope.$on "map:ui:shown", (event, args)->
$timeout ->
#use a delay because most of the time, the resizing should occur immediately after an angular cycle
#like when an ng-show has been set to the True condition
googleMaps.event.trigger(map, 'resize')
map.fitBounds scope.bounds if scope.bounds

Does ActionScript 3 have some sort of event delegation system?

I have a container with many images. Instead of adding a listener for click and other mouse events on each of the images, I would like to only listen for those events on the parent of the image.
Is that possible?
container.addEventListener(MouseEvent.CLICK, clickHandler);
private function clickHandler(e:MouseEvent):void {
trace(e.currentTarget); // references container
trace(e.target); //references container's child or container itself depending on what has been clicked
}
If i am understanding your question correctly, that is totally possible. So assuming you have something like:
parent.addChild(new Child());
parent.addChild(new Child());
parent.addChild(new Child());
parent.addChild(new Child());
Then you should be able to bind the event listener to the parent thusly:
parent.addEventListener(MouseEvent.CLICK, handleClick);
and then your handler should look something like
private function handleClick(e:MouseEvent) {
// cast the target of the event as the correct class
var clickedChild:Child = Child(e.target);
// Do whatever you want to do.
}
You can also combine this with the useCapture argument of addEventListener to attach the event on the capturing side of the event rather than the bubbling side. And also use the .stopPropagation() method on the Event to stop any other event handlers from firing as well...
But its difficult to say if you need to use those without knowing more about what you are trying to do. But hopefully that will give you a push in the right direction.

Is it possible to stop child click events propagating to parents when handled by .live()?

I have 'Back Board' on my images and content over here: http://syndex.me
So basically, you click on an image, it will overlay a info panel above the clicked content.
I want to do two things:
Click on the background of the site to fade out the currently opened info panel
Be able to click on a tag, link, or social icon within the info panel without triggering it's parent function, which is too fade out again.
I cannot use stopPropagation for the child click being superseded by the parent click as i need the click events to be handled by .live() (see documentation) This is due to the fact that posts are being dynamically loaded.
I cannot just say something like:
$("#Background").click(function(){//fade out the Info Board}
Because that is being covered by the entire post wrapper, and i can't put an event ont hat because then I'm even deeper in the dilemma of parents taking over children's events :-)
So far I'm at least able to have just one infoboard open (i.e I click on one image, then another, it will close the already opened one, and open the current one. So this part is all good:
$('.theContent:not(.clicked)').live("click", function () {
$(this).children('.postInfo').fadeIn(400);
$(".clicked").each(function() {
$(this).find('.postInfo').fadeOut(400);
$(this).removeClass('clicked');
});
$(this).addClass("clicked");
});
$('.clicked').live("click", function () {
$(".clicked").each(function() {
$(this).find('.postInfo').fadeOut(400);
$(this).removeClass('clicked');
});
});
Re .live(), .delegate() and .stopPropogation():
Since the .live() method handles events once they have propagated to the top of the document, it is not possible to stop propagation of live events. Similarly, events handled by .delegate() will propagate to the elements to which they are delegated; event handlers bound on any elements below it in the DOM tree will already have been executed by the time the delegated event handler is called. These handlers, therefore, may prevent the delegated handler from triggering by calling event.stopPropagation() or returning false.
How about simply checking whether the event actually took place on the specific element:
function activate(el) {
el.find('.postInfo').fadeIn(400);
el.addClass('clicked');
}
function deactivate(el) {
el.find('.postInfo').fadeOut(400);
el.removeClass('clicked');
}
$('.theContent:not(.clicked)').live('click', function(e) {
deactivate($('.clicked'));
activate($(this));
});
$('.clicked').live("click", function(e) {
if (! $(e.target).is('a')) {
// this should not trigger if a click occured on one of the links
deactivate($(this));
}
});
$('#ape').click(function(e) {
if ($(e.target).is('#ape')) {
deactivate($('.clicked'));
}
});
Have you thought about binding the click event when the post is dynamically loaded? This way you can use stopPropagation().
http://jsfiddle.net/rkw79/CzEj5/
If you bind the event to a parent element, it won't stop its propagation event to it's childrens.
You have two solutions, to bind an event to every children and put THERE the stop propagation call, or just test who ired the click event in the parent. I prsonaly find more elegant the second solution.
You can read something more about it here :
http://redfishmemories.blogspot.it/2014/08/jquery-prevent-event-propagation-and.html

Procedure to use the result from a textbox inside a popup - ActionScript

I am relatively new to ActionScript (have started with it 2 months ago), and have a little doubt of 'procedure' or 'technique' related to passing information between objects.
I have made a class that Pops-up a window that contains a panel with a textbox and two buttons, one for accepting, other for cancelling. It should work as a prompt in which you enter some text, and then if you like the changes, you accept, else, you cancel and the text you entered is discarded.
The thing I'm not sure how to handle is how to receive the text, once the user presses 'Accept', from the class I want to receive it from.
So, the approach I took is a bit cumbersome: firstly, when launching the popup, I associate with it a function (called onResult() in the code) from the 'class that launches', which will be called after the user presses the 'Accept' or 'Cancel' buttons; secondly, to get the text that the user inserted in the box, I keep a reference to it public from my class.
Please have a look at the code here:
http://pastebin.com/Kmud8rBe
I've also programmed in Android before, and the approach there would be much cleanier, just putting the text result from the popup inside a bundle inside an intent, and receiving it from the launched class. Here, I have to pass functions and such, which I don't like at all (although it works!).
So, my question is, for you ActionScript gurus out there, how would you approach this?
Thanks and regards!
pepillo
good that you created a class for your popup-functionality but why did you make all functions static? normal class with normal methods would be better ... and let the class extend from Sprite so that you can add the instance right to the stage.
package
{
import flash.display.Sprite;
public class Popup extends Sprite
{
public function Popup (label:String)
{
// add text and buttons ...
}
}
}
then you can just say:
var pop:Popup = new Popup("message");
addChild(pop);
and to get the data back after the popup is closed you would do sth like this:
private function onPressedAccept(event:MouseEvent):void
{
var text:String = _label.text;
// dispatch a custom event which saves the text as its data
dispatchEvent(new MyEvent(MyEvent.ACCEPT, text));
// close popup ...
parent.removeChild(this);
// or you would remove the popup in the ACCEPT eventlistener ...
}
listening for accept/cancel:
var pop:Popup = new Popup("message");
addChild(pop);
// add eventlistener
popup.addEventListener(MyEvent.ACCEPT, onAccept);
popup.addEventListener(MyEvent.CANCEL, onCancel);
private function onAccept(event:MyEvent):void
{
trace(event.data);
}
link about creating custom events:
http://www.8bitrocket.com/2007/7/31/Creating-Custom-Events-In-Flash-AS3-ActionScript-3/

Action Script 3 On Click

Before i start i want to let you know today is my first day with AS3.
I wanted to know how to do an onclick function in AS3.
For example i have button 1 ( as Instance name)
and when clicked i want it to hide and show another box. this is what i found online but how can i make it on click.
this.button1.alpha = 100;
Thanks so much.
You want
button1.addEventListener(EventType, callback);
You replace EventType with a mouse event (such as MouseEvent.MOUSE_DOWN) and callback is a function that you define, which is called whenever the event occurs.
See the following example, taken from this page on the FlashEnabled Blog:
// attach the event listener to this object, if you want a global event outside
// the current class attach to stage.addEventListener([event],[callback])
this.addEventListener(MouseEvent.CLICK, onMouseClickEvent);
// then make the callback
public function onMouseClickEvent(event:Event) {
trace(event);
if(event.buttonDown)
// if primary button down, left mouse button
trace(”left button was down”);
else
trace(”left button was not down”);
}
}
The above code sample attaches a click event handler to this (whatever context this code is executed in - it could be global, or inside a class). Inside your event handler, you'd want to use the Tween class (as explained on Kirupa.com) to animate the box out and the other box in.
Since you mentioned that it's your first day, note that trace() writes to the console.