getElementByName does not seem to work - actionscript-3

I'm using Flex 4.6 and have a AIR application
I have a Panel with many labels on it. I need to access these labels from another class.
I don't want to pass all the labels objects. so I thought about passing the panel container in then access the labels through the getElementByName() method.
Here is my mark up:
<s:VGroup includeIn="SLA_textView" width="100%" height="100%"
paddingBottom="10" paddingRight="10">
<s:Panel id="SlaTextViewPanel" width="100%" height="100%"
title="test View">
<s:Label id="lbTotalBooks" name="test" x="82" y="62" />
</s:Panel>
</s:VGroup>
the actionscript code look like this:
getLabels(Container:Panel){
var _Container:Panel = Container;
//var tempLabel:Label = _Container.getChildByName("test") as Label;
var n:int = _Container.numChildren;
for (var i:int = 0; i < n; i++) {
var c:DisplayObject = _Container.getChildAt(i);
trace(c.name);
}
var tempLabel:Label = _Container.getChildByName("test") as Label;
Why is tempLabel always null?
So I tried to loop through the name of the object on the Panel and the test label don't even show up? so I have something wrong somewhere.
Trace:
instance1333
PanelSkin1074

When and where do you call a getLabels method? It's possible that labels have been created but not initialized yet.

You can use something like this:
var element:Group = "searchId" in this ? this["searchId"] as Group : null;

Related

as3 print a page with text, image and data grid [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have an AIR application.
I want to print a set of text, image and datagrid my document is like a report.
As datagrid has different heights, I don't know how to do.
Could you help me ?
Best regards
Here's an example from the docs: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/printing/FlexPrintJob.html
FormPrintFooter.mxml
<s:VGroup name="FormPrintFooter"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="60%"
horizontalAlign="right" >
<!-- Declare and initialize the product total variable. -->
<fx:Script>
<![CDATA[
[Bindable]
public var pTotal:Number = 0;
]]>
</fx:Script>
<s:Label text="Product Total: {pTotal}"/>
</s:VGroup>
FormPrintView.mxml
<!-- Custom control to print the Halo DataGrid control on multiple pages. -->
<s:VGroup name="FormPrintView"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns="*">
<fx:Script>
<![CDATA[
import mx.core.*;
// Declare and initialize the variables used in the component.
// The application sets the actual prodTotal value.
[Bindable]
public var pageNumber:Number = 1;
[Bindable]
public var prodTotal:Number = 0;
// Control the page contents by selectively hiding the header and
// footer based on the page type.
public function showPage(pageType:String):void {
if (pageType == "first" || pageType == "middle") {
// Hide the footer.
footer.includeInLayout = false;
footer.visible = false;
}
if (pageType == "middle" || pageType == "last") {
// The header won't be used again; hide it.
header.includeInLayout = false;
header.visible = false;
}
if (pageType == "last") {
// Show the footer.
footer.includeInLayout = true;
footer.visible = true;
}
//Update the DataGrid layout to reflect the results.
validateNow();
}
]]>
</fx:Script>
<!-- The template for the printed page, with the contents for all pages. -->
<s:VGroup width="80%" horizontalAlign="left">
<s:Label text="Page {pageNumber}"/>
</s:VGroup>
<FormPrintHeader id="header" />
<!-- The data grid. The sizeToPage property is true by default, so the last
page has only as many grid rows as are needed for the data. -->
<mx:PrintDataGrid id="myDataGrid" width="60%" height="100%">
<!-- Specify the columns to ensure that their order is correct. -->
<mx:columns>
<mx:DataGridColumn dataField="Index" />
<mx:DataGridColumn dataField="Qty" />
</mx:columns>
</mx:PrintDataGrid>
<!-- Create a FormPrintFooter control and set its prodTotal variable. -->
<FormPrintFooter id="footer" pTotal="{prodTotal}" />
</s:VGroup>
PrintDataGridExample.mxml
<!-- Main application to print a Halo DataGrid control on multiple pages. -->
<s:Application name="PrintDataGridExample.mxml"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="initData();">
<fx:Script>
<![CDATA[
import mx.printing.*;
import mx.collections.ArrayCollection;
import FormPrintView;
import mx.core.FlexGlobals;
// Declare variables and initialize simple variables.
[Bindable]
public var dgProvider:ArrayCollection;
public var footerHeight:Number = 20;
public var prodIndex:Number;
public var prodTotal:Number = 0;
// Data initialization.
public function initData():void {
// Create the data provider for the DataGrid control.
dgProvider = new ArrayCollection;
}
// Fill the dgProvider ArrayCollection with the specified items.
public function setdgProvider(items:int):void {
prodIndex=1;
dgProvider.removeAll();
for (var z:int=0; z<items; z++) {
var prod1:Object = {};
prod1.Qty = prodIndex * 7;
prod1.Index = prodIndex++;
prodTotal += prod1.Qty;
dgProvider.addItem(prod1);
}
}
// The function to print the output.
public function doPrint():void {
var printJob:FlexPrintJob = new FlexPrintJob();
if (printJob.start()) {
// Create a FormPrintView control as a child of the current view.
var thePrintView:FormPrintView = new FormPrintView();
FlexGlobals.topLevelApplication.addElement(thePrintView);
//Set the print view properties.
thePrintView.width=printJob.pageWidth;
thePrintView.height=printJob.pageHeight;
thePrintView.prodTotal = prodTotal;
// Set the data provider of the FormPrintView component's data grid
// to be the data provider of the displayed data grid.
thePrintView.myDataGrid.dataProvider = myDataGrid.dataProvider;
// Create a single-page image.
thePrintView.showPage("single");
// If the print image's data grid can hold all the provider's rows,
// add the page to the print job.
if (!thePrintView.myDataGrid.validNextPage) {
printJob.addObject(thePrintView);
}
// Otherwise, the job requires multiple pages.
else {
// Create the first page and add it to the print job.
thePrintView.showPage("first");
printJob.addObject(thePrintView);
thePrintView.pageNumber++;
// Loop through the following code until all pages are queued.
while (true) {
// Move the next page of data to the top of the print grid.
thePrintView.myDataGrid.nextPage();
thePrintView.showPage("last");
// If the page holds the remaining data, or if the last page
// was completely filled by the last grid data, queue it for printing.
// Test if there is data for another PrintDataGrid page.
if (!thePrintView.myDataGrid.validNextPage) {
// This is the last page; queue it and exit the print loop.
printJob.addObject(thePrintView);
break;
} else {
// This is not the last page. Queue a middle page.
thePrintView.showPage("middle");
printJob.addObject(thePrintView);
thePrintView.pageNumber++;
}
}
}
// All pages are queued; remove the FormPrintView control to free memory.
FlexGlobals.topLevelApplication.removeElement(thePrintView);
}
// Send the job to the printer.
printJob.send();
}
]]>
</fx:Script>
<s:Panel title="DataGrid Printing Example"
width="75%" height="75%"
horizontalCenter="0" verticalCenter="0">
<s:VGroup left="10" right="10" top="10" bottom="10">
<mx:DataGrid id="myDataGrid" dataProvider="{dgProvider}">
<mx:columns>
<mx:DataGridColumn dataField="Index"/>
<mx:DataGridColumn dataField="Qty"/>
</mx:columns>
</mx:DataGrid>
<s:Label width="100%" color="blue"
text="Specify the number of lines and click Fill Grid first. Then you can click Print."/>
<s:TextInput id="dataItems" text="35"/>
<s:HGroup>
<s:Button id="setDP" label="Fill Grid" click="setdgProvider(int(dataItems.text));"/>
<s:Button id="printDG" label="Print" click="doPrint();"/>
</s:HGroup>
</s:VGroup>
</s:Panel>
</s:Application>

Spark.Components.List with variable content: Flex 4, AS3

I coded the following in Flex 4/AS3 and it doesn't worked as expected.
So, I would like to know if there is something wrong with my code... I'll explain it:
TileTest.mxml
<s:Application minWidth="955" minHeight="600" creationComplete="createButtons()"
<fx:Script>
<![CDATA[
import Object.TestButton;
import mx.collections.ArrayList;
private var _names:Array = ["one", "two", "three"];
public function createButtons():void
{
var buttons:ArrayList = new ArrayList();
for(var a:int = 0; a < _names.length; a++)
{
var testButton:TestButton = new TestButton();
testButton.customName = _names[a];
buttons.addItem(testButton);
}
myList.dataProvider = buttons;
}
]]>
</fx:Script>
<s:VGroup gap="12" width="100%">
<s:Label text="Options" fontSize="18" fontWeight="bold" color="#333333" />
<s:List width="100%" height="100%" id="myList" itemRenderer="Object.TestButton" borderVisible="false">
<s:layout>
<s:TileLayout orientation="rows" columnWidth="290" rowHeight="90" columnAlign="left" horizontalGap="0" verticalGap="0" />
</s:layout>
</s:List>
</s:VGroup>
</s:Application>
This is my Application. Here, I have a List called myList, where I load some TestButtons. I set a name for each button inside the loop.
TestButton
<s:Group width="300" height="90" click="{ Alert.show(_name); }"
<fx:Script>
<![CDATA[
import mx.controls.Alert;
private var _name:String = "just a test...";
public function set customName(newName:String):void
{
_name = newName;
Alert.show(_name);
this.addEventListener(MouseEvent.MOUSE_OVER, function():void{ Alert.show(_name); });
}
]]>
</fx:Script>
<s:BorderContainer accentColor="#000000" width="100%" height="100%" />
</s:Group>
As you can see, I have three Alerts in this component... I did so we can understand the problem.
The first Alert occurs when I set the customName, which occurs in the Application, as already shown.
The second one should occur on Mouse_Over, as the event listener been added to the Group element.
And the third Alert should occur on Click in the Group element.
Now, if I run the resulting swf, I see all the three buttons in the screen and three Alerts, one for each set customName by the Application and it alerts the right name.
If I put the mouse over any button, it doesn't alert any message.
If I click any button, it alerts the default message set to the _name property, which is "just a test..."
I can't understand what is the problem, as I was expecting it to always alert the name set by the Application to each button. Also, I don't want to change the components... what I'm saying is that I would like to have a List and TestButtons with a private String inside.
If the problem is in these specific implementation, so I'll have no other way than change it...
Thank you all!
The problem is that you have a list of TestButtons in your data provider, instead of just plain data. Those buttons get created, and that is why you see the correct Alert messages.
So, then Flex sees a list with three items and therefore it creates three additional TestButtons to render the data in your list. But those TestButtons are completely new ones, with default values for its properties.
To fix this, it would be better if you had data only in your data provider ArrayList, and you would access it through the data property of your item renderer.

Check Spark DataGrid cells' contents programmatically?

I'm using the Spark DataGrid for the first time and finding it generally very usable. There's something I'd like to do with the contents of my grid now that I've drawn it though and I'm a bit stuck as how to proceed.
I'd like to make a function that runs through each cell of a certain column in the DataGrid, that checks each value against an Array of predefined values; if it finds a match, it should then highlight the cell as conflicting, by changing its colour.
I know you can access a particular cell's item renderer, by using the getItemRendererAt() function, and passing the column and row indices. But I can't see how I would, for example, loop through the values in each column.
I may well be going about this all wrong, in which case feel free to push me onto the right path. Equally if it's possible to do what I'm trying to do, I'd love to hear how.
Thanks!
Actually, you should create your own <s:GridItemRenderer /> and use it as an itemRenderer of your dataGrid.
This way, you will be able to change the color of the cell depending on the data property of the <s:GridItemRenderer />.
Here is an example of how you could do it:
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:s = "library://ns.adobe.com/flex/spark"
xmlns:mx = "library://ns.adobe.com/flex/mx" >
<fx:Script>
<![CDATA[
private function isValid(value:uint):Boolean
{
//whatever;
return true;
}
]]>
</fx:Script>
<s:BorderContainer width="100%" height="100%">
<s:borderStroke>
<s:SolidColorStroke color="{isValid(data)?#00FF00:#FF0000}" />
</s:borderStroke>
<s:UITextField label="{data}" />
</s:BorderContainer>
</s:GridItemRenderer>
Using the example above, also Override the "set data" to change the color everytime you change the data, and not only on the grid creation
<?xml version="1.0" encoding="utf-8"?>
<s:GridItemRenderer xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:s = "library://ns.adobe.com/flex/spark"
xmlns:mx = "library://ns.adobe.com/flex/mx" >
<fx:Script>
<![CDATA[
import mx.controls.ColorPicker;
import mx.events.FlexEvent;
import mx.utils.ColorUtil;
override public function set data(value:Object):void{
super.data = value;
if(data.different == 1){
solidColor.color = 255;
}
}
]]>
</fx:Script>
<s:BorderContainer width="100%" height="100%">
<s:borderStroke>
<s:SolidColorStroke id="solidColor" />
</s:borderStroke>
<s:UITextFieldGridItemRenderer label="{data.name}" />
</s:BorderContainer>
</s:GridItemRenderer>
Then the next steps are easy, clone your dataProvider from the datagrid and then compare both, and if the item is changed, just set "1" to ,for example, the flag "different" in the example above and then the itemRenderer will call itself and change de color automatically

RadioButtonGroup with each RadioButton added in components?

Working in Flex 3, I have a series of components being rendered on a canvas, each of which should represent a single potential selection, ideally in a RadioButtonGroup. So in my parent canvas I am defining the RadioButtonGroup, and each component provides a single RadioButton. However, this doesn't seem to work.
Suppose there is a component called aComponent defined as such:
<mx:Canvas ...>
...
<mx:RadioButton id="someButton" groupName="myRadioButtonGroup" ... />
</mx:Canvas>
The outer canvas:
<mx:Canvas id="outerCanvas" ...>
...
<mx:Script>
public function doesSomething():void
{
var myComponent:aComponent = new aComponent();
outerCanvas.addChild(myComponent);
}
</mx:Script>
...
<mx:RadioButtonGroup id="myRadioButtonGroup" />
</mx:Canvas>
So my guess was that at this point if, say, four of these components were added, the radio buttons would behave in mutually exclusive fashion and I'd be able to access myRadioButtonGroup.selectedValue to get the current selection. However, it doesn't seem to work that way.
Is what I'm trying to do even possible, or have I maybe just missed something?
Thanks!
Edit - got to the bottom of it:
The radiobuttongroup isn't available to the component. It's parent has 'myRadioButtonGroup', but not the component.. Pass the 'myRadioButtonGroup' to the constructor and use it..
outerCanvas function:
var myComponent:aComponent = new aComponent(myRadioButtonGroup);
aComponent definition:
private var radioGroup:RadioButtonGroup;
function aComponent(radioGroup:RadioButtonGroup):void {
this.radioGroup = radioGroup;
}
</mx:Script>
<mx:RadioButton id="someButton" groupName="radioGroup" ... />
untested, but hopefully gives you the idea

getting mx:CheckBox values from inside mx:Repeater

I have an an array of objects that I use as the datasource for my repeater.
<mx:Repeater id="categoryRepeater" dataProvider="{this.allCategories}">
<mx:HBox>
<mx:Spacer width="20"/>
<mx:CheckBox id="categoryCheckBox" label="{categoryRepeater.currentItem.question}"/>
</mx:HBox>
</mx:Repeater>
I would like to be able to tell which of the checkboxes in the list have been checked, but I'm not sure how to do it. I know I can add a function when it's clicked, but I don't know how to tell which checkbox called the function.
Use the currentIndex property.
I realize that this is a very old post, but I had run into the same issue and the currentIndex was not a sufficient answer for me. What I found to work better was to create a function on click:
<mx:Repeater id="rp" dataProvider="{dp}">
<s:CheckBox height="100%" width="100%" label="{String(rp.currentItem)}"
click="showAlert(event);"/>
</mx:Repeater>
and the showAlert function looks something like this:
private function showAlert(evt:MouseEvent):void {
var curBox:CheckBox = evt.currentTarget as CheckBox;
var str:String = curBox.content.toString();
if(curBox.selected)
Alert.show(str + " clicked");
}
This way you can deal with the event as a CheckBox inside of your ActionScript code and find values such as whether or not it has been selected etc.