ActionScript 3 Can't Add and Remove item from Array - arrays

I'm working on a shopping list app and i'm having issue's removing and adding an item within the array.
I have an output_txt.text and input_txt.text with three buttons add_btn, remove_btn, and clear_btn. Inside my list (output) I have items of "Bread, Dog Food, Eggs, Hamburger, Milk". I want to be able to add items to the list and sort them alphabetically.
When I add an item it sorts it alphabetically, however when I try to add another item it just replaces the last item I entered.
When I want to clear an item I want to be able to copy the item from the list and place it in the input textbox and click the remove btn to remove it, but when I do this it only removes the second item and then places it to the bottom of the list.
(The totalItems_txt.text is the total number of items I add and remove from the list.)
Here's my code:
clear_btn.addEventListener(MouseEvent.CLICK, ClearList);
function ClearList(e:MouseEvent):void {
output_txt.text = "";
totalItems_txt.text = "0";
}
addItem_btn.addEventListener(MouseEvent.CLICK, AddItem);
function AddItem(e:MouseEvent):void {
var newItems:Array = ["Bread", "Dog Food", "Eggs", "Hamburger", "Milk"];
newItems[0] = "Bread";
newItems[1] = "Dog Food";
newItems[2] = "Eggs";
newItems[3] = "Hamburger";
newItems[4] = "Milk";
newItems[5] = input_txt.text;
newItems.sort(Array.CASEINSENSITIVE);
input_txt.text = "";
output_txt.text = "";
for (var i:int = 0; i < newItems.length; i++){
output_txt.appendText(newItems[i] + "\n");
}
totalItems_txt.text = newItems.length.toString();
}
remove_btn.addEventListener(MouseEvent.CLICK, RemoveItems);
function RemoveItems(e:MouseEvent):void {
var items:Array = ["Bread", "Dog Food", "Eggs", "Hamburger", "Milk"];
items[0] = "Bread";
items[1] = "Dog Food";
items[2] = "Eggs";
items[3] = "Hamburger";
items[4] = "Milk";
items[5] = input_txt.text;
output_txt.text = "";
items.splice(1,1);
for (var i:int = 0; i < items.length; i++){
output_txt.appendText(items[i] + "\n");
}
totalItems_txt.text = items.length.toString();
}

It's easier to identify the cause of the problem if you provide a complete and verifiable example, however, at the heart of your issue is an understanding of the Array methods:
splice(startIndex:int, deleteCount:uint), for removing items.
push(... args), for adding items.
If you explicitly reference newItems[0] thru [5], then you'll only ever affect entries 0 - 5, however, push is useful since it simply adds it to the end of your array. Conversely, you could use either splice (to specifically target a certain index), or pop() (which removes the last element from an array) to delete items from your array.
The other problem is that your arrays are local. Because you're recreating them every time you call RemoveItems or AddItem, you'll never save your changes. So, move it outside of those functions, and it'll be saved between clicks.
I've reworked your code with changes, and added supplemental code for the missing UI code you didn't provide. You can run this in a new .fla file and it will work as intended.
import flash.text.TextField;
import flash.events.KeyboardEvent;
import flash.display.Sprite;
var items:Array = ["Bread", "Dog Food", "Eggs", "Hamburger", "Milk"];
function addItem(e:MouseEvent):void {
if (input_txt.text != "") { // Assuming we having something in the input_txt,
items.push(input_txt.text); // add it to the end of our items array
input_txt.text = "";
updateOutput();
}
}
function removeItems(e:MouseEvent):void {
items.splice(0,1);
updateOutput();
}
function clearList(e:MouseEvent):void {
items = []; // empty our list by replacing it with a new one.
output_txt.text = "";
totalItems_txt.text = "0";
}
function updateOutput():void {
items.sort(Array.CASEINSENSITIVE);
output_txt.text = "";
for (var i:int = 0; i < items.length; i++){
output_txt.appendText(items[i] + "\n");
}
totalItems_txt.text = "Total: " + items.length;
}
/* Supplemental UI Creation */
var addItem_btn:Sprite = new Sprite();
addItem_btn.graphics.beginFill(0xa1FFa1,1);
addItem_btn.graphics.drawRect(0,0,100,25)
addChild(addItem_btn);
addItem_btn.addEventListener(MouseEvent.CLICK, addItem);
var clear_btn:Sprite = new Sprite();
clear_btn.graphics.beginFill(0xa1a1a1,1);
clear_btn.graphics.drawRect(0,0,100,25)
addChild(clear_btn);
clear_btn.x = 101;
clear_btn.addEventListener(MouseEvent.CLICK, clearList);
var remove_btn:Sprite = new Sprite();
remove_btn.graphics.beginFill(0xFFa1a1,1);
remove_btn.graphics.drawRect(0,0,100,25)
addChild(remove_btn);
remove_btn.x = 202;
remove_btn.addEventListener(MouseEvent.CLICK, removeItems);
var input_txt:TextField = new TextField();
addChild(input_txt);
input_txt.type = "input";
input_txt.text = "input_txt";
input_txt.y = 50;
var output_txt:TextField = new TextField();
addChild(output_txt);
output_txt.text = "output_txt";
output_txt.y = 50;
output_txt.x = 101;
var totalItems_txt:TextField = new TextField();
addChild(totalItems_txt);
totalItems_txt.text = "totalItems_txt";
totalItems_txt.y = 50;
totalItems_txt.x = 202;

All you had to do is declare your array as public and then add just the values to the array by using push(). when you sort the actual index of the array still remains , but the displayed items index will be different ,

Related

add and remove item to qx.ui.list.List

How can I add item at the end of this array? I didn't find examples. Did I miss something. How can I remove an element?
var rawData = [];
for (var i = 0; i < 2; i++) {
rawData[i] = "Item " + i;
}
var model = qx.data.marshal.Json.createModel(rawData);
var list = new qx.ui.list.List(model);
//var list = new qx.ui.list.List(new qx.data.Array("item 0"));
//list.add( new qx.ui.list.List("itme 2"))
//list.createItem("item 2")
//list.insertAt(0, "item2")
this.getRoot().add(list);
There is MVC pattern implementation in qooxdoo. The elegant way is to work with model not view. You can wrap JS array by qooxdoo array qx.data.Array instead of qx.data.marshal.Json.createModel. The qooxdoo array has method append which add to the end of array and remove the last element is pop method.
const data = [];
for (let i = 0; i < 2; i++) {
data[i] = "Item " + i;
}
const model = new qx.data.Array(data);
const list = new qx.ui.list.List(model);
// removing element from list
model.pop();
// adding element to end of list
model.append("Item 3");
this.getRoot().add(list);
let doc = this.getRoot();
doc.add(list, {left: 100, top: 50});
I can use list.getModel().insertAt(2, "item 3")
list.getModel().removeAt(0)

Remove movieClips using array list?

I've a array of list and created image place holder with the array objects name (Example: myArray[a,b]) and loaded images from there, having array list as folder name.
And finally created a movieClip to load on them and display in stage.
Now I want to remove them calling the same array list.
Need help here...
My code below:
for (var l: int = 0; l < ListArray.length; l++) {
var BookName: MovieClip = new bookThumb();
trace("\n[" + l + "]: " + ListArray[l]);
ImageFoldername = ListArray[l];
var bookImagePath: String = "file://" + File.userDirectory.nativePath.toString() + "/Books/" + ImageFoldername + "/Images/Icon.png";
trace(bookImagePath);
var ImagePlacer: Loader = new Loader;
var ImageURL: URLRequest = new URLRequest(bookImagePath);
ImagePlacer.load(ImageURL);
BookName.addChild(ImagePlacer);
BookName.name = ImageFoldername
addChild(BookName)
BookName.x = FirstBook_x;
BookName.y = FirstBook_y;
BookName.buttonMode = true;
BookName.mouseChildren = false;
BookName.addEventListener(MouseEvent.CLICK, IconSelected);
BookName.alpha = .8
BookName.addEventListener(MouseEvent.MOUSE_OVER, IconMouseOver);
BookName.addEventListener(MouseEvent.MOUSE_OUT, IconMouseOut);
FirstBook_x = FirstBook_x + 250;
}
Because you assign the ImageFoldername to each MovieClip's name property, you can use getChildByName to find them and remove them:
(Note: convention in AS3 is to use UpperCamelCase for classes, and lowerCamelCase for variables and functions. I've written the code below following this convention. )
for (var i:int = 0; i < listArray.length; i++) {
var imageFolderName:String = listArray[i];
var bookThumb:BookThumb = getChildByName(imageFolderName) as BookThumb;
if (bookThumb) {
removeChild(bookThumb);
}
}
Another way you can handle it is to add each book thumb into a list:
var bookThumbs:Array = [];
for (var i:int = 0; i < listArray.length; i++) {
var bookThumb:Bookthumb = new BookThumb();
bookThumbs.push(bookThumb);
// ...
}
Then to remove them all:
for each (var bookThumb:BookThumb in bookThumbs) {
removeChild(bookThumb);
}
bookThumbs.length = 0;
But probably the easiest way to remove them all would be to simply put them all in a single container and later use removeChildren() to remove them all:
var container:Sprite = new Sprite();
addChild(container);
for (var i:int = 0; i < listArray.length; i++) {
var bookThumb:Bookthumb = new BookThumb();
container.push(bookThumb);
// ...
}
// when you want to remove them all:
container.removeChildren();

how to search for a specific word in a huge array?

In AS3 :
I've got a long text in an array.
var myHugeArray:Array = ["I love Apple
I have an Iphone
I eat a Banana
I'm John
I sell a computer
I sell an Apple
I love rock
I sell a car"];
How can I do to search a specifics words ? (like : show me sentences with the word "apple") --> output : "I love Apple" and "I sell an Apple"
Thanks,
EDIT
Here's what I did so far :
loader5.load(urlReq);
loader5.addEventListener(Event.COMPLETE,completeHandler2);
function completeHandler2(event:Event):void{
loader5.removeEventListener(Event.COMPLETE,completeHandler2);
trace("Données envoyées");
feedbackText.text = "Données envoyées";
loader5.load(urlReq);
loader5.addEventListener(Event.COMPLETE, complete);
}
function complete(e:Event):void {
addChild(list);
products = JSON.parse(loader5.data) as Array;
feedbackText.text = "complete";
for(var i:int = 0; i < products.length; i++){
createListItem(i, products[i]);
}
showList();
}
function createListItem(index:int, item:Object):void {
var listItem:TextField = new TextField();
listItem.text = item.title;
listItem.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
showDetails(item);
});
list.addChild(listItem);
str = item.title;
bar();
}
function bar(){
var arr: Array ;
searchBar.type = TextFieldType.INPUT;
var suggested:Array = new Array();
var textfields:Array = new Array();
searchBar.addEventListener(Event.CHANGE, suggest);
arr = str.split(",");
trace(arr);
function suggest(e:Event):void
{
suggested = [];
for (var i:int = 0; i < textfields.length; i++)
{
removeChild(textfields[i]);
}
textfields = [];
for (var j:int = 0; j < arr.length; j++)
{
if (arr[j].indexOf(searchBar.text.toLowerCase()) != -1)
{
var term:TextField = new TextField();
term.width = 360;
term.height = 24;
term.x = 18;
term.y = (24 * suggested.length) + 135;
term.border = true;
term.borderColor = 0x353535;
term.background = true;
term.backgroundColor = 0xFF9900;
term.textColor = 0x4C311D;
term.defaultTextFormat = format;
addChild(term);
suggested.push(arr[j]);
term.text = arr[j];
}
}
function showList():void {
list.visible = true;
}
function showDetails(item:Object):void {
titleTxt.htmlText = item.title;
detailsTxt.htmlText = "<U>prix:</U> " + item.prix + " xpf"+ "\n\n<U>Description:</U> " + "\n"+item.theDescription + "\n"+"\n\n<U>Contact:</U> " + item.mail+ "\n"+item.phone;
}
So, my AS3 code go search for PHP variable with loader5.
All the items found by the php are put in an Array (products).
And a list of all the products is created. (createListItem).
If I click on an item, it show me some details (price, description..etc). It's the function showDetails();
Know I've created a searchBar (autocomplete).
An array is created (arr) that split the string (str).
Then it does what it does to search through the array.
Problems :
1/ Weirdly, not all the words are displayed in my searchBar. Some words are working, other not.
2/ How can I do to call the function showDetails() when the user click on the suggest term ? (term.addEventListener(MouseEvent.CLICK, showDetails)); doesn't work as the terms is not item.title. ShowDetails is showing details of item.title. (so how can I say that term = item.title ?)
3/ Do you see a way simpler than that ?
Your myHugeArray is just string, so split() it with \n', you got the
ret array for example, then find the one contains the word you search, like "apple", using indexof() in each string
You need to split the string into an array then search each item
check this out
https://stackoverflow.com/a/34842518/3623547

as3: how to access a MovieClip as unique Object/MovieClip from Array which loaded from same MovieClip from the Library

I'm trying to add multiple copies of the same movieclip to the stage at once
I have the loop which fills the array and generate the movieclips to the stage
and the loop to add The click EventListener for each movieClip
but I miss the magical code to access every MovieClip separately
to have it removed from the stage by clicking on it
var numOfClips:Number = 5;
var mcArray:Array = new Array();
for(var i=0; i<numOfClips; i++)
{
var usd:mcUSD = new mcUSD();
//genrate random x , y position----------------------------
var randY:Number = Math.floor(Math.random()*460) + 120;
var randX:Number = Math.floor(Math.random()*350) + 60;
usd.x = randX;
usd.y = randY;
//---------------------------------------------------------
mcArray.push(usd);
addChild(usd);
}
for(var m:int = 0; m<mcArray.length; m++){
usd.addEventListener(MouseEvent.CLICK, colectmoney);
}
function colectmoney(e:MouseEvent): void {
removeChild(usd);
}
Try this:
import flash.events.MouseEvent;
var numOfClips:Number = 5;
var mcArray:Array = new Array();
for(var i=0; i<numOfClips; i++)
{
var usd:mcUSD = new mcUSD();
//genrate random x , y position----------------------------
var randY:Number = Math.floor(Math.random()*460) + 120;
var randX:Number = Math.floor(Math.random()*350) + 60;
usd.x = randX;
usd.y = randY;
//---------------------------------------------------------
mcArray.push(usd);
addChild(usd);
}
addEventListener(MouseEvent.CLICK, mouseClickHandler);
function mouseClickHandler(e:MouseEvent) : void {
removeChild(mcArray[mcArray.indexOf(e.target)]);
}
Important things to note: 1) you do not need to call a mouse.click event listener for each mcUSD object. It's more efficient to call it once. 2) removeChild(usd) won't work because you need to tell AS3 which mcUSD object to remove. 3) try to keep function nomenclature consistent - eg colectMoney instead of colectmoney. it will save you confusing times once your program gets bigger. hope this helps! :)

How can I prevent this arbitrary text truncation in AS3

Below is code that populates a menu. Everything seems to work great, with no errors thrown, except for one crucial part. My megaPages array has the values ["HOME","BABIES","BRIDALS","MISC","WEDDINGS","ABOUT"], but the actual text that displays on screen (which is produced by megaPages) is like this:
As you can see, some of the text is arbitrarily being truncated. I've traced the text strings as they get passed through the various functions at various stages of the menu-build, and they are always right, but somehow when each DisplayObject make it on screen, letters get ommitted (notice though that 'HOME' abd 'ABOUT' are fine). I don't even know where to start with this problem.
function buildMenu() {
var itemMCs = new Array();
for (var i = 0; i < megaPages.length; i++) {
megaPages[i] = megaPages[i].toUpperCase();
trace(megaPages[i]); // at each iteration, traces as follows "HOME","BABIES","BRIDALS","MISC","WEDDINGS","ABOUT"
var textMC = createText(megaPages[i]);
var itemMC = new MovieClip();
if (i!=0) {
var newLink = new PlateLink();
newLink.y = 0;
itemMC.addChild(newLink);
}
var newPlate = new Plate();
if (i==0) {
newPlate.y = 0;
} else {
newPlate.y = newLink.height - 2;
}
newPlate.x = 0;
newPlate.width = textMC.width + (plateMargin*2);
itemMC.addChild(newPlate);
if (i!=0) {
newLink.x = (newPlate.width/2) - (newLink.width/2);
}
textMC.x = plateMargin;
textMC.y = newPlate.y + .5;
itemMC.addChild(textMC);
itemMCs.push(itemMC);
itemMC.x = (homeplateref.x + (homeplateref.width/2)) - (itemMC.width/2);
if (i==0) {
itemMC.y = homeplateref.y;
} else {
itemMC.y = itemMCs[i-1].y + (itemMCs[i-1].height - 6);
}
menuRef.addChild(itemMC);
}
}
function createText(menuTitle) {
trace(menuTitle);
var textContainer : MovieClip = new MovieClip();
var myFont = new Font1();
var backText = instantText(menuTitle, 0x000000);
backText.x = 1;
backText.y = 1;
var frontText = instantText(menuTitle, 0xFFFFFF);
frontText.x = 0;
frontText.y = 0;
textContainer.addChild(backText);
textContainer.addChild(frontText);
return textContainer;
}
function instantText(textContent, color) {
trace(textContent); // again, traces the right text each time it is fired
var myFont = new Font1();
var myFormat:TextFormat = new TextFormat();
myFormat.size = 18;
myFormat.align = TextFormatAlign.CENTER;
myFormat.font = myFont.fontName;
var myText:TextField = new TextField();
myText.defaultTextFormat = myFormat;
myText.embedFonts = true;
myText.antiAliasType = AntiAliasType.ADVANCED;
myText.text = textContent;
myText.textColor = color;
myText.autoSize = TextFieldAutoSize.LEFT;
trace(myText.text);
return myText;
}
You need to embed all the necessary characters for the font you're using.
For textfields created in Flash:
Select the TextField, and hit the 'Embed' button in the properties panel.
For dynamically created textfields:
When you set the font to export (Font1 in your case) make sure to include all the characters you need.
You can choose to embed all uppercase characters, or just type in the ones you need for those specific menu items.

Resources