Creating multiple TextInput fields in for loop - actionscript-3

I need to loop through an array and for each element create a textfield. My problem is how to create a new identifier for each new TextInput
this is my code;
var count:Number = 0;
for (var i:String in columnsData)
{
var myTI:TextInput = new TextInput();
myTI.width = 70;
myTI.height = 25;
myTI.text = columnsData[i];
myTI.name = "myTI" + count;
addChild(myTI);
count++;
}
all this does however is overwrite the previously created TextInput field, any ideas?

Try this:
var count:uint = 0,
textInputs:Array /* of TextInputs */ = [];
for(var i:String in columnsData){
textInputs[count] = new TextInput();
// Customize textInput[count] instead of myTI
addChild(textInputs[count]);
count++;
}
Outside of this loop, you should be able to look inside the textInputs array for references to each of your new TextInputs. Note that, inside the loop, you probably want to change the x/y coordinates for each TextInput so they don't overlap.

Related

How to get index of a Bitmap Image from bitmapdata(from an Array)?

I am wondering if i have an Array that push content that is Bitmap, how do i get index of a specific image when clicked. I tried to use indexOf but no luck, my codes are below.
Thanks for your time!
Code:
//First Part is where i add the URLRequest and add the image into contentHolder then onto Stage
function loadImage():void {
for(var i:int = 5; i < somedata.length; i++){
if(somedata[i]){
var loader:Loader = new Loader();
loader.load(new URLRequest("http://www.rentaid.info/rent/"+somedata[i]));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
}
}
}
function onImageLoaded(e:Event):void {
loadedArray.push(e.target.content as Bitmap);
for(var i:int = 0; i < loadedArray.length; i++){
var currentY1:int = 200;
e.currentTarget.loader.content.height =200;
e.currentTarget.loader.content.y += currentY1;
currentY1 += e.currentTarget.loader.content.height +300;
_contentHolder.mouseChildren = false; // ignore children mouseEvents
_contentHolder.mouseEnabled = true; // enable mouse on the object - normally set to true by default
_contentHolder.useHandCursor = true; // add hand cursor on mouse over
_contentHolder.buttonMode = true;
_contentHolder.addChild(loadedArray[i]);
addChild(_contentHolder);
_contentHolder.addEventListener(MouseEvent.CLICK, gotoscene);
}
}
// then the part where i try to get the index
function gotoscene(e:MouseEvent):void {
var index:Number;
index = loadedArray.indexOf(e.target);
trace(index);
}
Edit:
var viewport:Viewport = new Viewport();
viewport.y = 0;
viewport.addChild(_contentHolder);
Your first question has very simple answer:
var image:Bitmap = new Bitmap();
var images:Array = new Array(image);
for (var i:uint = 0; i < images.length; i++) {
// images[i].bitmapData is the original image in your array
// image.bitmapData is searched one
if (images[i].bitmapData == image.bitmapData) {
// found
}
}
But your problem is bigger than this. I see you keep wandering around..
You should add listener to each child, not the content holder as one. I usually don't use Loaders, but get their Bitmaps and wrap them in Sprites or something, that I add into the scene. You should store either this Sprite or your Loader into that array, not the Bitmap. Then add listener to each of them (Sprite or Loader, not Bitmap) and get the target. Depending on what you've stored in the array, you can easily get it as:
function gotoscene(e:MouseEvent):void {
var index:uint = loadedArray(indexOf(e.target));
}
But it's important to store one specific type that will actually be clickable. Don't think about the Bitmap - it's only a graphic representation, and doesn't do much in the code.
**EDIT:
Okay I'm adding the code you need but it's important to understand what you are doing and not just rely on someone else's answer :)
function onImageLoaded(e:Event):void {
var bitmap:Bitmap = e.target.content as Bitmap; // get the Bitmap
var image:Sprite = new Sprite();
image.addChild(bitmap); // wrap it inside new Sprite
// add listener to Sprite!
image.addEventListener(MouseEvent.CLICK, gotoscene);
// gets url of current image (http://website.com/images/image1.jpg)
var url:String = e.target.loaderURL;
// get only the number from that url by replacing or by some other way
// this removes the first part and results in "1.jpg"
var name:String = url.replace("http://website.com/images/image", "");
// this removes the extension and results in number only - 1, 2, 3
// it's important to change this depending on your naming convention
name = name.replace(".jpg", "");
image.name = "button" + name; // results in "button1", "button2", "button3"
// store object, name, or whatever (not really needed in your case, but commonly used)
loadedArray.push(image.name);
image.x = counter * 100; // position so you can see them, at 100, 200, 300, etc.
_contentHolder.addChild(image); // add newly created Sprite to content
}
function gotoscene(e:MouseEvent):void {
var name:String = e.target.name;
// strips down "button" from "button1", and only the number remains,
// which is 1, 2, 3, etc. the number of the scene :)
var scene:uint = name.replace("button", "");
// you're the man now :)
}

using DataGrid to addChild but I don't know how i can delete by choosing another item

please help me.
I am working in an offline map and I read data from XML. I put data in DataGrid and when i select item from datagrid I add child in the stage and create a movieclip for data (may be more than one child at a time ), but when i choose another item from the datagrid the new child added but the old one not removed.
this is my code:
familyGrid.addEventListener(Event.CHANGE, get_data2);
function get_data2(event:Event):void {
//get the selected item's name and search in another xml file
//for the points that have the same name
nameFamilyText.text= familyGrid.selectedItem.Latin;
var pattern_pID2:RegExp;
current_pID2 = [];
pattern_pID2 = new RegExp(nameFamilyText.text);
for (var n:int = 0; n<all_pID2.length; n++)
{
if ((pattern_pID2.test(all_pID2[n].fLatinName) || nameFamilyText.text=="") )
{
current_pID2.push(all_pID2[n]);
var fxnList:XMLList = pID_data2.marker.(#LatinName == nameFamilyText.text);
for each (var xnNode:XML in fxnList)
fButtonName.text= xnNode.#LatinName.toXMLString()
//create marker in the satge which have a n image of offline map
// i need to remove the old one before add a new one
var newString:String = ("id_"+all_pID2[n].id);
var markLoader:Loader = new Loader();
var myMark:String= ("T copy.png");
markLoader.load(new URLRequest (myMark));
markLoader.x=this[newString].x-8;
markLoader.y=this[newString].y-20;
addChild(markLoader);
markLoader.addEventListener(MouseEvent.CLICK, getToolTip);
function getToolTip(e:MouseEvent) {
var flabel:TextField = new TextField();
flabel.width=150;
flabel.height=20;
flabel.border=true;
flabel.background=true;
flabel.autoSize=TextFieldAutoSize.RIGHT;
flabel.text=xnNode.#Species_name.toXMLString();
flabel.x=markLoader.x-30;
flabel.y=markLoader.y-20;
addChild(flabel);
flabel.addEventListener(MouseEvent.CLICK, fShowData);
function fShowData(e:MouseEvent) {
///create movieclip for data
var fmc:MovieClip = new MovieClip();
fmc.graphics.beginFill(0x000000, .75);
fmc.graphics.drawRect(60, 90, 700, 500);
fmc.graphics.endFill();
fmc.x = 80;
fmc.y = 60;
addChild(fmc);
}}}
updateList2();
}}
Just put the Movieclips you want to add into a container movieclip.
Maybe something like this:
familyGrid.addEventListener(Event.CHANGE, get_data2);
var familyContainer = new MovieClip();
addChild(familyContainer);
In your get_data2 function you then do
function get_data2(event:Event):void {
...
removePreviousChildren();
familyContainer.addChild(markLoader);
...
}
function removePreviousChildren() {
while(familyContainer.numChildren > 0) {
familyContainer.removeChild(familyContainer.getChildAt(0))
}
}

Applying an event listener to all instances on the stage of an item, and deleting the specific item

I have a list of items in a scrolling list, I would like the user to click on a specific item to delete it - I need to apply an eventListener to all instances of that item, so that whatever item is clicked, it is deleted
This is the first function:
private function dataLoaded(event:Event):void {
// this holds the loaded xml data //
data = new XML(event.target.data);
//items properties call - add other calls to master properties later on//
items = data.item;
// parsing of each ingredient//
for (var i = 0; i < items.length(); i++) {
// instantiation of mcItem (the stage for each item)
_item = new Item();
// sets //over// layer to invisible / transparent //
_item.item_btn_over.alpha = 0;
// creates the var itemTextField //
_itemTextField = new TextField();
// _itemTextField visual attributes //
_itemTextField.x = _textFieldXPosition + _textFieldPaddingLeft;
_itemTextField.y = _textFieldYPosition;
_itemTextField.selectable = true;
_itemTextField.wordWrap = true;
_itemTextField.width = _textFieldWidth;
_itemTextField.height = _textFieldHeight;
_itemTextField.embedFonts = true;
_defaultFormat.color = 0x111112;
_defaultFormat.font = _arialRounded.fontName;
_defaultFormat.size = 18;
_itemTextField.defaultTextFormat = _defaultFormat;
_itemTextField.text = items[i].toString();
//adds textfield to displaylist//
_item.addChild(_itemTextField);
//vertical positioning//
_item.y = i * _itemPosition;
_item.buttonMode = true;
_item.mouseChildren = false;
//adds items to container displaylist//
_container.addChild(_item);
}
// Input Mask//
_mask = new Shape();
_mask.graphics.beginFill(0xFF0000);
_mask.graphics.drawRect(0, 0, _maskWidth, _maskHeight);
_mask.graphics.endFill();
// Positioning of input mask//
// horizontal centering of input mask//
_mask.x = stage.stageWidth / 2 - _container.width / 2;
_mask.y = _paddingTop;
// adds the mask onto the stage//
addChild(_mask);
// assigns the above mask to the container //
_container.mask = _mask;
// Positioning of container with the mask//
// horizontal centering of container //
_container.x = stage.stageWidth / 2 - _container.width / 2;
// vertical position of container //
_container.y = _paddingTop;
//Container background stylings//
_background = new Shape();
_background.graphics.beginFill(0xFFFFFF);
_background.graphics.drawRect(0, 0, _container.width, _container.height);
_background.graphics.endFill();
_container.addChildAt(_background, 0);
//End of container background stylings//
_item.parent.addEventListener( MouseEvent.CLICK, itemClicked );
_container.addEventListener(MouseEvent.MOUSE_OVER, movingOver);
_container.addEventListener(MouseEvent.MOUSE_OUT, movingOut);
}
And here is my itemClicked function:
function itemClicked(event:MouseEvent):void {
_item.parent.removeChild(_item);
}
Unfortunately, my previous efforts have only managed to delete the last item in the list. How do I apply a listener to all instances, but in the listener function only delete the item that has been clicked on?
Your problem is that you have what I am assuming is a class member variable called _item, and as you loop through, you are reusing that variable to create your new item. So, _item is only ever a reference to the last item you created.
So when you use it in your itemClickHandler -- it ALWAYS references the last item you created.
Here's an example of what you should be doing :
// this is just example code for your dataLoaded function showing the correct concept
for (var i = 0; i < items.length(); i++)
{
var newItem:Item = new Item;
// do whatever you need to newItem
newItem.addEventListener(MouseEvent.CLICKED, itemClicked);
}
function itemClicked(event:MouseEvent):void
{
var curItem:Item = event.currentTarget as Item;
curItem.parent.removeChild(curItem);
}
Although you could do this as well :
// this is just example code for your dataLoaded function showing the correct concept
for (var i = 0; i < items.length(); i++)
{
var newItem:Item = new Item;
// do whatever you need to newItem
}
_container.addEventListener(MouseEvent.CLICKED, itemClicked);
function itemClicked(event:MouseEvent):void
{
// you could also have a check here to see if it is indeed an Item
var curItem:Item = event.target as Item;
curItem.parent.removeChild(curItem);
}
This second approach has the advantage of only 1 listener, and therefore you'll only need to remove 1 when you are done with the list.
You can access the clicked item in the event listener as evt.target
Try:
function itemClicked(event:MouseEvent):void {
if(evt.target is Item) {
var item:Item = Item(evt.target);
item.parent.removeChild(item);
}
}

How to pass a variable into an Event.COMPLETE function?

I am running a loop to pull thumbs into a containing movieclip from an xml list. What I want to do is have the thumb's parent movieclip fade in after they are done loading, but I can't figure out how to reference the parent once it's loaded.
My code(which currently doesn't work the way I want it):
var vsThumb:articleBox;
var currentarticleX:Number = 0;
var articleLinkURL:String;
var articleImageURL:String;
var articleText:String;
var vsThumbLoader:Loader;
var next_x:Number;
next_x = 9;
var thumbAlphaTween:Tween;
var articlevsThumb:Array = new Array();
function loadarticleHeadlines():void
{
for (var i:int = 0; i < egarticleXml.articlelist.articleitem.length(); i++)
{
vsThumb = new articleBox();
vsThumb.alpha = 0;
vsThumbLoader = new Loader();
vsThumbLoader.load(new URLRequest(egarticleXml.articlelist.articleitem[i].articlethumbnail));
articleListContainter.addChild(vsThumb);
vsThumb.articleImage.addChild(vsThumbLoader);
vsThumb.articleTitle.text = egarticleXml.articlelist.articleitem[i].articletitle;
titleAutosize(vsThumb.articleTitle);
vsThumb.x = next_x;
next_x += 260;
articlevsThumb[i] = vsThumb;
vsThumbLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, showBox);
vsThumb.clickBtn.buttonMode = true;
}
function showBox(event:Event):void
{
thumbAlphaTween = new Tween(articlevsThumb[i],"alpha",None.easeNone,0,1,.25,true);
}
}
So how do I refer back to the loader's parent so I can fade in the whole movieclip? Can I pass a variable into the showBox function?
Don't use nested functions. They tend to make things more complicated.
i will always have the end value (articleitem.length()-1) in all of the event handlers you create, because its scope is the outer function, loadarticleHeadlines (it will increase by 1 on every iteration). That's probably why your code doesn't work.
The event will be fired on the loaderInfo of your loader, so you can find the loader's parent by using event.target.loader.parent:
function loadarticleHeadlines() : void
{
for (var i:int = 0; i < egarticleXml.articlelist.articleitem.length(); i++)
{
vsThumb = new articleBox();
vsThumb.alpha = 0;
vsThumbLoader = new Loader();
vsThumbLoader.load(new URLRequest(egarticleXml.articlelist.articleitem[i].articlethumbnail));
articleListContainter.addChild(vsThumb);
vsThumb.articleImage.addChild(vsThumbLoader);
vsThumb.articleTitle.text = egarticleXml.articlelist.articleitem[i].articletitle;
titleAutosize(vsThumb.articleTitle);
vsThumb.x = next_x;
next_x += 260;
articlevsThumb[i] = vsThumb;
vsThumbLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, showBox);
vsThumb.clickBtn.buttonMode = true;
}
}
function showBox(event:Event):void
{
thumbAlphaTween = new Tween(event.target.loader.parent,"alpha",None.easeNone,0,1,.25,true);
}
You don't need to pass a variable to your showBox, use the target property of the Event to retrieve the Loader:
function showBox(event:Event):void
{
var li:LoaderInfo=LoaderInfo(event.target);
// be nice remove your listener when your are done
li.removeEventListener(Event.COMPLETE, showBox);
var ldr:Loader=li.loader; // here is your loader
// do whatever you want with loader
thumbAlphaTween = new Tween(articlevsThumb[i],"alpha",None.easeNone,0,1,.25,true);
}

ActionScript 3 - retrieving text values from TexInput created in component

I have a tile layout containing a list of TextInputs and text fields , i have created these fields in a custom component using the following code;
var newTextInputs:Array = [];
var newTextLabels = [];
var space:Number = 30;
var count:Number = 0;
for (var i:String in columnsData)
{
//create text labels
var label:Text = new Text();
label.name = "label" + count;
label.text = i;
newTextLabels[count] = label;
addChild(newTextLabels[count]);
// create text fields
var field:TextInput = new TextInput();
field.name = "field" + count;
field.width = 100;
field.height = 25;
field.text = columnsData[i];
newTextInputs[count] = field;
addChild(newTextInputs[count]);
count++;
}
users are allowed edit the values in each TextInput field, now i need to retrieve the newly udpated values however how can i access these fields? Because the identifiers are created dynamically i cant simply go componentName.InputFieldName, any ideas?
I think what you're looking for is getChildByName
later edit: tested with Flash and TextField and it works:
trace(TextField(getChildByName('textfield')).text);
You can add an event handler for the TileList CHANGE event; when it fires, I think the event.target property will have the specific TextInput field. Alternatively you can look at the TileList.SelectedItem property.
You may also be able to have a DataProvider bound to the TileList instead of your code as shown, which will handle this automatically for you. Try just assigning your NewTextLabels array as the dataProvider.