Flex 3: Deselecting Toggle Button Through UIComponent Reference - apache-flex

I've got some buttons that have toggle set to true. I'm trying to re-set the button's state to unselected. But, I can't access the button directly like: button.selected=false.
I'm accessing the HBox's children which are the buttons. UIComonent doesn't have a selected property. So, how do I de-select the toggle in this bit of code below?
for (var j : int=0; j < theHBox.numChildren; j++){
var child : DisplayObject = theHBox.getChildAt(j);
var myButton:UIComponent = child as UIComponent;
myButton.setStyle("borderColor", "blue");
myButton.visible = true;
}

If possible, I would recommend casting the UIComponent to a button:
for (var j : int=0; j < theHBox.numChildren; j++){
var child : DisplayObject = theHBox.getChildAt(j);
if(child is Button){
var myButton:Button = child as Button;
myButton.setStyle("borderColor", "blue");
myButton.visible = true;
} else if(child is somethingElse){
// do something else
}
}
You could also do something like this:
for (var j : int=0; j < theHBox.numChildren; j++){
var child : DisplayObject = theHBox.getChildAt(j);
var myButton:UIComponent = child as UIComponent;
myButton.setStyle("borderColor", "blue");
myButton.visible = true;
myButton['toggle'] = false;
}
Which will work if all children are buttons, but if the 'myButton' does not have a toggle property, it will throw a run time error.

Related

creating a Placemarks that can be hidden

I have been trying to create a Placemark that I can hide and show (like turning visibility on and off) on demand (on click)... I am using this to make the placemark:
function placemark(lat, long, name, url, iconsrc){
var placemark = ge.createPlacemark(name);
ge.getFeatures().appendChild(placemark);
placemark.setName(name);
// Create style map for placemark
var icon = ge.createIcon('');
if(iconsrc == "0")
icon.setHref('http://maps.google.com/mapfiles/kml/paddle/red-circle.png');
else{
icon.setHref(iconsrc);
}
var style = ge.createStyle('');
style.getIconStyle().setIcon(icon);
if(iconsrc != "0")
style.getIconStyle().setScale(2.5);
placemark.setStyleSelector(style);
// Create point
var point = ge.createPoint('');
point.setLatitude(lat);
point.setLongitude(long);
//point.setAltitudeMode(1500);
placemark.setGeometry(point);
google.earth.addEventListener(placemark, 'click', function(event) {
// Prevent the default balloon from popping up.
event.preventDefault();
var balloon = ge.createHtmlStringBalloon('');
balloon.setFeature(placemark); // optional
balloon.setContentString(
'<iframe src="'+ url +'" frameborder="0"></iframe>');
ge.setBalloon(balloon);
});
}
I have tried everything... from this:
function hidePlacemark(name){
var children = ge.getFeatures().getChildNodes();
for(var i = 0; i < children.getLength(); i++) {
var child = children.item(i);
if(child.getType() == 'KmlPlacemark') {
if(child.getId()== name)
child.setVisibility(false);
}
}
}
to using this ge.getFeatures().removeChild(child);
can anyone point me to the right direction on creating a function that will allow me to turn the visibility on/off on demand please.
Your hidePlacemark function is missing some {} in your final IF statement
if(child.getId()== name)
you have
function hidePlacemark(name){
var children = ge.getFeatures().getChildNodes();
for(var i = 0; i < children.getLength(); i++) {
var child = children.item(i);
if(child.getType() == 'KmlPlacemark') {
if(child.getId()== name)
child.setVisibility(false);
}
}
}
make it
function hidePlacemark(name){
var children = ge.getFeatures().getChildNodes();
for(var i = 0; i < children.getLength(); i++) {
var child = children.item(i);
if(child.getType() == 'KmlPlacemark') {
if(child.getId()== name) {
child.setVisibility(false);
}
}
}
}
HOWEVER ------- you are better off doing this as it is much faster as you don't need to loop through ALL your placemarks
function hidePlacemark(name) {
var placemark = ge.getElementById(name);
placemark.setVisibility(false);
}
I think the plain ge.getFeatures().removeChild(placemark); works.
I played with this GooglePlayground, and just added the following code to line 8 (that is empty in this GooglePlayground Sample):
addSampleButton('Hide Placemark', function(){
ge.getFeatures().removeChild(placemark);
});
Clicking the button Hide Placemark hides the placemark like a charm here. Any chances your problem is somewhere else in your code?

how to show vector features in OpenLayers after hiding it?

I did change some features style (through check-boxes) using style property :
var features = layer.features;
for( var i = 0; i < features.length; i++ ) {
//features[i].style = { visibility: 'hidden' };
features[i].style = 'none';
}
layer.redraw();
Now if I check the box again, it supposed to display again but nothing happens!
I tried:
features[i].style = 'block';
OR
features[i].style = 'delete';
then redraw the layer.. but this doesn't work
Any Idea ?
Try this:
// set style
features[i].style = null;
// or
features[i].style = {display:'none'};
// redraw feature
layer.drawFeature(features[i]);

How to tell when element is finally shown on screen?

I have a "Loading" dialog that displays while I'm adding a lot of custom elements to a container. I've set the dialog to disappear when the last added element's creationCompleteHandler is called, but the dialog disappears before all the elements display on screen (which results in a very large lag).
Here's an example of what I'm doing:
for (var i:int = 0; i < 100; i++) {
var elem:MyElement = new MyElement();
elem.name = "elem" + i;
container.addElement(elem);
if (i == 99) {
elem.creationComplete = function():void {
PopUpManager.removePopUp(loadingDialog);
};
}
}
So as I've said, the dialog disappears before all the elements appear on screen. Is there a way to tell when all the custom elements have been added AND are currently showing on screen?
Update: To clarify, elem.creationComplete is just a custom property function that gets called when the element's creationCompleteHandler is called.
The elements, even though they have been added in the right order, they are not created in that order:
private function doStuff():void {
PopUpManager.addPopUp(myPopup, this);
for (var i:int = 0; i < 10; i++) {
var elem:MyElement = new MyElement();
elem.name = "elem" + i;
container.addElement(elem);
elem.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:FlexEvent):void {
trace("i'm done " + e.target.name);
});
if (i == 9) {
elem.addEventListener(FlexEvent.CREATION_COMPLETE, function():void {
trace("i'll remove the popup " + elem.name);
PopUpManager.removePopUp(myPopup);
});
}
}
}
Gives:
i'm done elem5
i'm done elem7
i'm done elem0
i'm done elem8
i'm done elem6
i'm done elem3
i'm done elem9
i'll remove the popup elem9
i'm done elem1
i'm done elem4
i'm done elem2
You need to add a global variable to check that all the elements have actually been created:
public var created:int = 0;
private function doStuff():void {
PopUpManager.addPopUp(myPopup, this);
for (var i:int = 0; i < 10; i++) {
var elem:MyElement = new MyElement();
elem.name = "elem" + i;
container.addElement(elem);
created++; // <--- increment with each new element
elem.addEventListener(FlexEvent.CREATION_COMPLETE, function(e:FlexEvent):void {
created--; // <--- decrement when element is created
trace("i'm done ", e.target.name);
if (created == 0) {
trace("i'll remove it ", e.target.name);
PopUpManager.removePopUp(myPopup);
}
});
}
}
And the result is:
i'm done elem5
i'm done elem7
i'm done elem0
i'm done elem8
i'm done elem6
i'm done elem3
i'm done elem9
i'm done elem1
i'm done elem4
i'm done elem2
i'll remove it elem2
To solve this, I followed jidma's answer, except I listened for the PropertyChanged event and decremented when the contentHeight property changed on the container. This decremented only when the container's height was affected by the added element, which seemed to work.

how could I traverse through children of a UIComponent Class in flex

I am dynamically creating a UI component based on XML templates stored in database. Now I want to access one of the child component of this UIComponent Class. I dont see any children property in this class? How could I possibly traverse through each child comppnent of this class and set its properties according to some logic in code(which I could not do in templates itself).
Basically what I want to do is something like this:
var cover:UICoomponent = generateScreen()
for each(var obj:UIComponent in cover.children){
if (obj.id =="myComponent"){
obj.SomProperty = "SomeValue";
}
}
Any help will be greatly appreciated. Thanks.
Use numChildren:
var cover:UICoomponent = generateScreen()
for (var i:int = 0; i < cover.numChildren; i++)
{
var obj:UIComposer = cover.getChildAt(i) as UIComponent;
if (obj.id =="myComponent") {
obj.SomProperty = "SomeValue";
}
}
Update: Traverse recursively
function findChild(childId:String,container:DisplayObjectContainer=null):UIComponent
{
container ||= this;
for (var i:int = 0; i < container.numChildren; i++)
{
var obj:UIComponent = container.getChildAt(i) as UIComponent;
if (obj.id == childId)
return obj;
if (obj is DisplayObjectContainer)
{
// search for children
child = findChild(childId,obj as DispalyObjectContainer);
if (child)
return child;
}
}
}
Usage:
var child:UIComponent = findChild("myComponent");
child.someProperty="SomeValue";
I haven't compiled this - but you get the general idea.

AIR: component behaves wrong after switching window

Ok so I have a component, that has a function to remove itself as a popUp in its current Window, and add itself to a newly created Window.
It works, however, if the component has a child like a ComboBox, the drop down still pops up in the old window where it used to be, also scrollbars, and focus seems to behave incorrectly in the new window also.
It seems to me like Flex still thinks the component is a child of the original window, not the new window. I have no idea how to resolve this though.
Here is my code:
private var ownWindow:Window;
private var _inOwnWindow:Boolean;
private var _removedEffect:Move;
private var _openX:Number;
private var _openY:Number;
public function launchInNewWindow(e:Event):void
{
_openX = Application.application.nativeWindow.x + this.x + 5; //keep in same spot add 5 for systemChrom border
_openY = Application.application.nativeWindow.y + this.y + 30;//keep in same spot add 30 for systemChrom title
this.parent.removeChild(this);
ownWindow = new Window();
ownWindow.systemChrome = 'none';
ownWindow.type = NativeWindowType.LIGHTWEIGHT;
ownWindow.transparent = true;
ownWindow.setStyle('showFlexChrome', false);
ownWindow.width = this.width > 750 ? 750 : this.width;
ownWindow.height = this.height > 550 ? 550 : this.height;
edit.enabled = false;
_removedEffect = this.getStyle('removedEffect') as Move;
if(_removedEffect == null)
{
openNewWindow();
}
else
{
// Wait for removed effect to play before adding to new window
_removedEffect.addEventListener(EffectEvent.EFFECT_END,delayOpenInNewWindow);
}
}
private function delayOpenInNewWindow(e:Event = null):void
{
var t:Timer = new Timer(100,1);
t.addEventListener(TimerEvent.TIMER,openNewWindow);
t.start();
}
private function openNewWindow(e:Event = null):void
{
ownWindow.addChild(this);
ownWindow.width += 5; //add to show dropshadow
ownWindow.height += 10; //add to show dropshadow
ownWindow.open();
_inOwnWindow = true;
ownWindow.nativeWindow.x = _openX;
ownWindow.nativeWindow.y = _openY;
}
Any ideas?
Thanks!!
Before I give this a run, have you tried a callLater on the openNewWindow() line?
[ lame fix attempt, i know -- but given that there doesn't seem to be an event that you can listen for in the case that the removedEffect isn't null and it seems like a timer is your only option there, I think it's o.k. to give lame fix attempts :-) ]

Resources