get all the descendants Elements(controls) of VBox(container) in flex? - apache-flex

can we get all the elements and all the descendants of those elements in a
VBox
?
lets say i have Vobx, in which a grid is added.. and in grid there are many texinput controls.. i want to access all the descendants which are
Grid,GridRow,GridItem,TextInput
.. how to do that ?

You'll have to write a recursive function that traverses the hierarchy of components. There is no built-in method to access children below the first level of a container.
Something like:
function traceDisplayObject(object:DisplayObject):void {
trace("Object: " + object);
if (object is Container) {
var container:Container = Container(object);
var numChildren:uint = container.numChildren;
for (var i:uint = 0; i<numChildren; i++) {
traceDisplayObject(container.getChildAt(i));
}
}
}
traceDisplayObject(myVBox);

Related

Iterating over ArrayCollection while adding and removing items

I want to iterate over an ArrayCollection in Flex while there can be items added and removed.
Since i didn't find a way to use a "classic" Iterator like in Java, which would do the job. I tried the Cursor. But it doesn't really work the way i want it to be ;) So how do I do it nicely ?
var cursor:IViewCursor = workingStack.createCursor();
while (!cursor.afterLast)
{
// Search
deepFirstSearchModified(cursor.current.node,nodeB,cursor.current.way);
// Delete Node
cursor.remove();
// Next Node
cursor.moveNext();
}
I think better to use New Collection/Array for opertations as
private function parseSelectedItem(value:IListViewCollection):IListViewCollection{
var result:Array = new Array();
for each(var item:Object in value)
{
//result.push();
//result.pop();
}
return new ArrayCollection(result) ;
}
Hopes that helps
Try to use the following:
for (var i:int = myArrayCollection.length - 1; i >= 0; i--) {
myArrayCollection.removeItemAt(i);
}
There is a solution for your problem:
http://www.ericfeminella.com/blog/actionscript-3-apis/
Have a look at the CollectionIterator class.
Cheers
Take a look at ActionLinq. It implements the .Net Linq2Objects pattern, including IEnumerable. Of course, you need to be careful, because you are modifying the items you are iterating over...
var workingStack:ArrayCollection = getData();
var iterator:IEnumerable = Enumerable.from(workingStack);
for each(var item:String in iterator) {
doSomethingTo(workingStack);
}
In flex (or actionscript) any change that you do, is visible instantly. So you can do what you want in a for:
for (var i : Number = myArrayCollection.length; i > 0; i--) {
myArrayCollection.removeItemAt(i - 1);
}
I think that should work fine.

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.

How to assign custom CSS class to arbitrary arbitrary rows of h:dataTable?

I'm trying to assign a specific CSS class to specific rows of my <h:dataTable>. Is there some way to access and cutomize the resulting table rows?
Bind the rowClasses attribute to a bean property which returns the desired string of CSS classes.
<h:dataTable value="#{bean.list}" rowClasses="#{bean.rowClasses}">
with e.g.
public String getRowClasses() {
StringBuilder rowClasses = new StringBuilder();
for (Item item : list) {
if (rowClasses.length() > 0) rowClasses.append(",");
rowClasses.append(item.getRowClass());
}
return rowClasses.toString();
}
Update to clarify, this way you have full programmatic control over the rowClasses string. Note that the above is just a kickoff example, it doesn't necessarily need to be obtained by Item#getRowClass() or so. You can even do it in a simple for loop with a counter.
E.g.
public String getRowClasses() {
StringBuilder rowClasses = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
if (rowClasses.length() > 0) rowClasses.append(",");
rowClasses.append(selected.contains(i) ? "selected" : "none");
}
return rowClasses.toString();
}
where selected is a List<Integer>. If it contains 1, 2 and 5, then the returned string will look like as follows for a list of 10 items:
none,selected,selected,none,none,selected,none,none,none,none
I like #BalusC suggestion. If you want a second alternative, you can do this easily with javascript/JQuery.
With JQuery you can do it like this
(Note, this is just an example. I haven't tested it, and there is probably a better way of doing it)
$(document).ready(function(){
var counter = 0;
$('#myTable').each(function() {
counter = counter + 1;
if(counter==3) {
$(this).addClass('redRow');
return;
}
});
}

How to access children of children recursively?

I have a Canvas which has many components inside it and those again, have many components inside them.
getChildren() returns only the top level children. What is the best way to retrieve all the children (children of children of children and so on).
Well, I sorta know how to do this by iterating through the children, but the code is really messy. I'd prefer to use a nice recursive function. Has anyone written this before? Or is there a Util class to do this?
private function recuse(display : DisplayObjectContainer) : void {
if(display) {
for (var i : int = 0;i < _display.numChildren;i++) {
var child : DisplayObject = display.getChildAt(i);
trace(child.name);
if(child is DisplayObjectContainer) {
recuse(DisplayObjectContainer(child));
}
}
}
}
Try something likely (note you can return the lists recursively if you want to gather all the references to the top level iteration)
function inspect(object:DisplayObject):void
{
if(object is DisplayObjectContainer)
{
var casted:DisplayObjectContainer = object as DisplayObjectContainer
trace("DisplayObjectContainer ", casted.name)
for(var depth:int = 0; depth < casted.numChildren;depth++)
{
inspect(casted.getChildAt(depth))
}
}else{
trace("DisplayObject", object.name );
}
}
inspect(this)
function theCallbackFunction(obj:DisplayObject):void
{
trace(obj.name);
}
//Visit the children first.
//Deep most objects will be visited first and so on.
//stage is visited at the end.
//Uses recursion
function depthFirst(obj:DisplayObject, func:Function):void
{
if(!(obj instanceof DisplayObjectContainer))
{
func(obj);
return;
}
var p:DisplayObjectContainer = DisplayObjectContainer(obj);
var len:Number = p.numChildren;
for(var i:Number = 0; i < len; i++)
{
var child:DisplayObject = p.getChildAt(i);
depthFirst(child, func);
}
func(obj);
}
//Visit the siblings first.
//stage is visited first, then its children, then the grand children and so on
//No recursion.
function breadthFirst(obj:DisplayObject, func:Function):void
{
var q:Array = [];
q.push(obj);
var p:DisplayObjectContainer;
var i:Number, len:Number;
while(q.length != 0)
{
var child:DisplayObject = queue.shift();
func(child);
if(!(child instanceof DisplayObjectContainer))
continue;
p = DisplayObjectContainer(child);
len = p.numChildren;
for(i = 0; i < len; i++)
q.push(p.getChildAt(i));
}
}
depthFirst(this.stage, theCallbackFunction);
breadthFirst(this.stage, theCallbackFunction);

How to access mxml (Flex) DOM elements?

Is there a way to access the DOM-Elements of a mxml file in a way that you can in JS (e.g. using Prototype or jQuery)?
I need to know if a top-level element has a child (sub-sub-...-childs) with a certain id.
In JS (using prototype) it would be something like:
$('tabs').select('[id="something"]');
Any ideas?
Depending on what you're trying to do, Bifff might be the answer. Think of it as "JQuery for Flex": https://github.com/seanhess/bifff/wiki
You can recursively search through the structure. Something like this (Might not be the most efficient in your case):
private function hasChild(node:UIComponent, target:String):Boolean
{
if(node.id == target)
{
return true;
}
else
{
var hasTarget:Boolean = false;
for(var i:int = 0; i < node.numChildren; i++)
{
hasTarget = hasTarget || hasChild(node.getChildAt(i));
}
return hasTarget;
}
}

Resources