Sunday, September 29, 2013

My Good Friends, Sort() and e.target.parent! - PrepHelp

Hello everyone!

Just a quick little update on PrepHelp. Since my last post I've worked out quite a few bugs. Here's a few things I got working:

  • Expiration date checking
  • Edit an existing item
  • Sort items by name, type, quantity, or expiration date
To check to see if the item is close to expiring gave me quite a bit of trouble. My initial thought process was to convert the dates into a separate number. For instance let's use 12/24/14 as our example date. The day would be the base number, so 24. Then you would add 100 for every month, which would bring us to 1,224. Then you could add 10,000 for every year, then compare the two numbers to see if the current day is still before the expiration date. As I'm sitting there I'm thinking to myself that this is not the way to try and check something like this. It's just nuts to complicate it like that. What I ended up doing was something more logical, and I hope a good way to do it. Basically, when I check the date I work backwards, starting with checking if the current year is the same, before, or after the expiration year. If it is the same year I then do the same check for the month, then the day. If it is within one month of expiring it will change a movie clip as a warning, then if the expiration date has passed it changes that movie clip again stating it is expired.

Here's the code that I came up with:
/* Since the add item date only has the last two numbers of the year we have to add 2000 since the date chek in unrealscript has a 4 digit year */ //If it is the same year, check if it is the same month if(foodInvo[i].ExpY + 2000 == currentYear) { //If so, check if it is the same day if(foodInvo[i].ExpM == currentMonth) { //If so, say it is expired if(foodInvo[i].ExpD <= currentDay) { item.expMarker_mc.gotoAndStop(3); } //If not, flag it as about to expired else if(foodInvo[i].ExpD >= currentDay) { item.expMarker_mc.gotoAndStop(2); } } //If the expiration date is a month away, flag it as about to expired else if(foodInvo[i].ExpM == currentMonth + 1) { item.expMarker_mc.gotoAndStop(2); } //If it is past the expiration year, flag as expired else if(foodInvo[i].ExpM < currentMonth) { item.expMarker_mc.gotoAndStop(3); } } else if(foodInvo[i].ExpY + 2000 < currentYear) { item.expMarker_mc.gotoAndStop(3); }

This helped me get the sort by date feature figured out as well, since it is basically doing the same thing. With the sort feature I used a delegate for the first time. Very interesting stuff, though kind of confusing. Basically a delegate allows you to use a function as a variable, sort of. In the case of the Array.Sort(delegate) function the sort function calls the delegate and the delegate takes parameter A and parameter B, compares them, and returns either -1(If your statement is true) or 0(If your statement is false). If -1(If I read the inline if statement correctly) is returned then the two elements in the array that are being compared will be switched. 

For sorting by date I ended up doing a little bit of my crazy number adding, though just by 1 or 2 instead of thousands. Since it is comparing two values and returning the larger I ended up adding or subtracting from one or the other depending on if the year/month/day were before or after the other.

Here is what the final code looked like:
//Calling the correct delegate switch(SortType) { case "Qty": //If SortType is quantity //use the SFBQ delegate FInv.Sort(SFBQ); break; case "Date": //If it is date, //use SFDB instead FInv.Sort(SFBD); break; default: FInv.Sort(SFBQ); break; } //The delegates //Sort Food By Quantity delegate int SFBQ(Food A, Food B) { //If sort quantity ascending is true if(bQUp) { //If FoodA.Quantity is greater //than FoodB.Quantity return A.Q > B.Q ? -1 : 0; } else { return A.Q < B.Q ? -1 : 0; } } //Sort Food By Date delegate int SFBD(Food A, Food B) { local int TempA, TempB; //If Year A is greater than B add 1 to A; if(A.D.Y > B.D.Y) { TempA += 1; } //Else, add 1 to B else if(A.D.Y < B.D.Y) { TempB += 1; } //If both have the same year, repeat down //through month and day. else if(A.D.Y == B.D.Y) { if(A.D.M > B.D.M) { TempA += 1; } else if(A.D.M < B.D.M) { TempB += 1; } else if(A.D.M == B.D.M) { if(A.D.D > B.D.D) { TempA += 1; } else if(A.D.D < B.D.D) { TempB += 1; } } } //If sorting Date ascending is true if(bDUp) { return TempA > TempB ? -1 : 0; } else { return TempA < TempB ? -1 : 0; } }

The other sorts were pretty straight forward since it would automatically check if the strings/ints were equal or not.

When I got around to adding the edit item I took almost all of the code for it from my add item popup. One thing I did change, though, was when the edit item popup comes up it will already have the information of the item being edited in the textfields. This would allow the user to change only what was necessary instead of having to re-input all of the information again. To do this I made use of the e.target.parent variable in Flash. Since the items are being added dynamically through code I found using the e.target or e.currentTarget keywords to be really helpful since it stores what movieclip/button that was the target of the event(Like the editItem_btn on a MouseEvent.CLICK event). One thing I had an issue with was that my target was my editItem_btn and all the information I wanted to access, so I could fill the edit item textfields, was in the parent movieclip item_mc. I tried several variations of parent.e.target and MovieClip(parent).e.target until I got e.target.parent. Then I could access my other textfields and all was well.

Anyway, hope that helps someone. Back to working on the search functionality!

No comments:

Post a Comment