How can be a ArrayCollection created? - actionscript-3

There is a nice example of Advanced Datagrid and use of ArrayCollection here. I like to have something like that;
private var dpFlat:ArrayCollection = new ArrayCollection([
{Region:"Southwest", Territory:"Arizona",
Territory_Rep:"Barbara Jennings", Actual:38865, Estimate:40000},
{Region:"Southwest", Territory:"Arizona",
Territory_Rep:"Dana Binn", Actual:29885, Estimate:30000},
{Region:"Southwest", Territory:"Central California",
Territory_Rep:"Joe Smith", Actual:29134, Estimate:30000},
{Region:"Southwest", Territory:"Nevada",
Territory_Rep:"Bethany Pittman", Actual:52888, Estimate:45000},
{Region:"Southwest", Territory:"Northern California",
Territory_Rep:"Lauren Ipsum", Actual:38805, Estimate:40000},
{Region:"Southwest", Territory:"Northern California",
Territory_Rep:"T.R. Smith", Actual:55498, Estimate:40000},
{Region:"Southwest", Territory:"Southern California",
Territory_Rep:"Alice Treu", Actual:44985, Estimate:45000},
{Region:"Southwest", Territory:"Southern California",
Territory_Rep:"Jane Grove", Actual:44913, Estimate:45000}
]);
I need to read an XML file and get some attributes from it. Then create a custom ArrayCollection with these attributes. Right now I am creating a custom XML but I no longer want to use XML and instead check Array Collection.
Here is the code I read and create another XML;
kitapKonuSayisi = _tempXMLOR.Body.Ogrenci.length();
for(var itra:int = 0; itra < kitapKonuSayisi; itra++)
{
uniteAdi = _tempXMLOR.Body.Ogrenci[itra].UniteAdi;
konuAdi = _tempXMLOR.Body.Ogrenci[itra].KonuAdi;
ogrenciAyrintiRaporArray.push([uniteAdi, konuAdi]);
}
for(var itrc:int = 0; itrc < kitapKonuSayisi; itrc++)
{
kitapUniteSayisi = _tempXMLOR.Body.Ogrenci[itrc].UniteAdi.length();
uniteAdi = _tempXMLOR.Body.Ogrenci[itrc].UniteAdi;
if(raporStringUnitCheck === true)
{
ogrenciAyrintiRaporStr += ('\t<Unite name="' + uniteAdi + '" yuzde="' + 100 + '">\n');
raporStringUnitCheck = false;
}
for(var itrd:int = 0; itrd < kitapUniteSayisi; itrd++)
{
if(ogrenciAyrintiRaporArray[itrd][0] == _tempXMLOR.Body.Ogrenci[itrc].UniteAdi)
{
konuAdi = _tempXMLOR.Body.Ogrenci[itrc].KonuAdi;
ogrenciAyrintiRaporStr += ('\t\t<Konu name="' + konuAdi + '" yuzde="' + 100 + '"/>\n');
}
}
}
if(raporStringUnitCheck === false && raporStringCompCheck === false)
{
ogrenciAyrintiRaporStr += ('\t</Unite>\n');
ogrenciAyrintiRaporStr += ('</Rapor>');
raporStringCompCheck = true;
raporString2XML = new XML(ogrenciAyrintiRaporStr);
}
So how can I create ArrayCollection and populate elements in that scheme?

So looks like you have an Array "ogrenciAyrintiRaporArray" already. You can create an ArrayCollection out of that:
var myArrayCollection:ArrayCollection = new ArrayCollection(ogrenciAyrintiRaporArray);
It's a bit strange that you have an Array consisting of arrays
ogrenciAyrintiRaporArray.push([uniteAdi, konuAdi]);
Usually there are objects in an ArrayCollection that you can easily use to display data in lists, datagrids etc. Also, it is easier to access properties in an object rather than indexes in an array. So you might want to change it to:
ogrenciAyrintiRaporArray.push({uniteAdi:uniteAdi, konuAdi:konuAdi});
Then you have an ArrayCollection of objects and can access data like
var uniteAdi:* = myArrayCollection.getItemAt(0).uniteAdi;
instead of
var uniteAdi:* = myArrayCollection.getItemAt(0)[0];
Which makes it unclear what is at the position 0, 1 or 2 in your data array

Related

Flare ItemVisualisation

Using the latest Flare build originally built by prefuse, I am trying to get an indent field like the one in Layouts seen here. I am working with a list of objects that I pull from Google Firebase. While I can put them on a graph just fine and compare one and other values I can't find instructions on the different layouts. I am about to study the docs but I wanted to know if there was anything else out there I could reference.
Edit:
http://flare.prefuse.org/api/flare/vis/operator/layout/Layout.html I have found the general layouts here. However I only am able to show 1 or two circles unless I do AxisLayout.
For reference, my data pulled from firebase is something like this.
An array of objects.
Each object has properties name, sales, date, active and such.
I want it to act like the example above and show the item name in each circle. Then when the user clicks the circle he is able to show the properties of the item.
Edit: I was able to find an article on it, but after hours of constructing my data around his set format, I am not able to mock it entirely.
http://simon.oconnorlamb.com/ria/2012/03/visualising-data-with-flare/
Edit: To go into detail:
When I pull from my json list from Google Firebase I parse it so that it puts the items in referencable categories. All of which go into an array to mock the tutorial I linked above. I am trying to mock the structure as close as possible.
private function handleDataRead(e:DatabaseEvent):void
{
var trueDataArray:Array = new Array();
//Extract manufacturers.
var manufacturers:Vector.<String> = new Vector.<String>();
for each (var item:Object in e.data)
{
if (manufacturers.indexOf(item.Manufacturer) == -1)
{
manufacturers.push(item.Manufacturer);
//Example: {type:'Manufacturer',id:'0',name:'Company A'}
trueDataArray.push( {type:'manufacturer',
id:manufacturers.indexOf(item.Manufacturer).toString(),
name:item.Manufacturer});
}
}
//Extract Item Name
var itemNames:Vector.<String> = new Vector.<String>();
for each (var item:Object in e.data)
{
if (itemNames.indexOf(item.ItemName) == -1)
{
itemNames.push(item.ItemName);
var idValue:String = new String(itemNames.indexOf(item.ItemName) + (manufacturers.length - 1) +1);
trueDataArray.push( {type:'item',
id:idValue,
name:item.ItemName,
manufacturer:manufacturers.indexOf(item.Manufacturer).toString()} );
}
}
//Extract property 1
var mlCount:Vector.<int> = new Vector.<int>();
for each (var item:Object in e.data)
{
if (item.hasOwnProperty("ML"))
{
if (mlCount.indexOf(item.ML) == -1)
{
mlCount.push(item.ML);
var idValue:String = new String(mlCount.indexOf(item.ML) + (itemNames.length - 1) + (manufacturers.length - 1) +1);
trueDataArray.push({type:'mL',
id:idValue,
name:(item.ML as int).toString(),
item:itemNames.indexOf(item.ItemName).toString()});
}
}
}
//Extract another property
var mgCount:Vector.<int> = new Vector.<int>();
for each (var item:Object in e.data)
{
if (item.hasOwnProperty("MG"))
{
if (mgCount.indexOf(item.MG) == -1)
{
mgCount.push(item.MG);
var idValue:String = new String(mgCount.indexOf(item.MG) + mlCount.indexOf(item.ML) + (itemNames.length - 1) + (manufacturers.length - 1) +1);
trueDataArray.push({type:'mG',
id:idValue,
name:(item.MG as int).toString(),
mL:mlCount.indexOf(item.ML).toString()});
}
}
}
The result looks like this.
[
{
"name":"Company A",
"type":"manufacturer",
"id":"0"
},
{
"name":"Company B",
"type":"manufacturer",
"id":"1"
},
{
"name":"Company C",
"type":"manufacturer",
"id":"2"
},
{
"name":"Company D",
"type":"manufacturer",
"id":"3"
},
{
"name":"Company E",
"type":"manufacturer",
"id":"4"
},
{
"type":"manufacturer",
"id":"5"
},
... //So on
{
"manufacturer":"0",
"name":"Item Name 1",
"type":"item",
"id":"18"
},
{
"manufacturer":"0",
"name":"Item Name 2",
"type":"item",
"id":"19"
},
{
"manufacturer":"0",
"name":"Item Name 3",
"type":"item",
"id":"20"
},
{
"manufacturer":"0",
"name":"Item Name 4",
"type":"item",
"id":"21"
...//So on
{
"name":"60",
"item":"0",
"type":"mL",
"id":"195"
},
{
"name":"100",
"item":"5",
"type":"mL",
"id":"196"
},
{
"name":"120",
"item":"36",
"type":"mL",
"id":"197"
},
{
"name":"30",
"item":"100",
"type":"mL",
"id":"198"
}
...//and so forth
]
When I pass this to my function to create the nodes and edges (that I again based off the blog in the link above)
public function buildTree(arr:Array):Data
{
var d:Data = new Data(true);
//Keyed lookup for easy edge addition in step 2
var nodeLookup:Object = {};
var row:Object;
var ns:NodeSprite;
//Step 1: Add all rows of data;
for each(row in arr){
ns = d.addNode(row);
nodeLookup[row.id] = ns;
}
//Step 2: Add edges
for each(ns in d.nodes){
if(ns.data.hasOwnProperty('manufacturer')){
d.addEdgeFor(nodeLookup[ns.data.manufacturer],ns);
}
else if(ns.data.hasOwnProperty('item')){
d.addEdgeFor(nodeLookup[ns.data.item],ns);
}
else if(ns.data.hasOwnProperty('mL')){
d.addEdgeFor(nodeLookup[ns.data.mL],ns);
}
}
return d;
}
and construct it
data = buildTree(trueDataArray);
sourceTree = new ItemVisualisation(data);
sourceTree.bounds = new Rectangle(10, 10, 550, 550);
sourceTree.x = 20;
sourceTree.y = 20;
addChild(sourceTree);
sourceTree.operators.add(new IndentedTreeLayout());
sourceTree.operators.add(new ShapeEncoder("data.type"));
sourceTree.operators.add(new ColorEncoder("data.type", Data.NODES, "lineColor", ScaleType.CATEGORIES));
sourceTree.data.nodes.setProperties({fillColor:0, lineWidth:2});
sourceTree.update();
I get the following..
I almost have this down but I don't know what I am doing wrong. Everything seems to be as it should in relation.
Edit: It seems that the nodes may be linking properly with each other however this is not the layout I desire. I cannot get any other layouts to work either.
trueDataArray.push({type:'root', id:0, name:'rootname'});
I was able to solve this problem by binding everything to 1 node. I was having some trouble listing anything beyond two steps but that is beyond the requirement of my project.

Passing a JSON AngularJS structure to a mongoDB database

I have just recentely used AngularJS to "convert" a data structure I had in pure SVG format into JSON format.
Now, I want to store such a structure in a MongoDB database to start finally connecting some components of the MEAN stack together and start seeing some things working! Basically, I have the following code inside a Webstorm AngularJS project:
JS:
var app = angular.module('app', []);
var RectangleDim=30;
app.controller('MainCtrl', function($scope) {
$scope.graph = {'width': 5000, 'height': 5000};
$scope.circles = [
/* JSON.parse("{\"x\": 85, \"y\": 20, \"r\":15}"),
{"x": 20, "y": 60, "r":20},
{"x": 18, "y": 10, "r":40} */
];
$scope.draw=function(val)
{
// val = document.getElementById("NumQuest").value;
return JSON.parse('{\"cx\":'+val+', "cy": 20, "r":30}');
// $scope.circles.push(JSON.parse('{\"x\":'+val+', "y": 220, "r":30}'));
};
$scope.rectangles = [
// {'x':220, 'y':220, 'width' : 300, 'height' : 100},
// {'x':520, 'y':220, 'width' : 10, 'height' : 10},
];
$scope.DrawRect=function(xpos,ypos) {
return JSON.parse('{\"x\":' + xpos + ', \"y\":' + ypos + ', \"width\":' + RectangleDim + ', \"height\":' + RectangleDim+ '}');
};
$scope.Debug=function(desiredNo){
desiredNo=document.getElementById("NumQuest").value;
for(var i = 0;i < RectangleDim*desiredNo+desiredNo;i++){
$scope.rectangles.push($scope.DrawRect(i+RectangleDim+1,40));
}
};
$scope.DrawLineOdd=function(desiredNo,lineNo,pozY){
var pozX = lineNo*RectangleDim;
var aux = 2*Math.floor(Math.sqrt(desiredNo))-1-2*lineNo;
for (var j = 0; j < aux; j++) {
$scope.rectangles.push($scope.DrawRect(pozX, pozY));//$scope.DrawRect(pozX, pozY);
pozX += RectangleDim;
}
//return aux;
};
$scope.DrawMatrixPerfectProgression=function(desiredNo) {
desiredNo=document.getElementById("NumQuest").value;
var line=0;
var pozy=0;
while(line<Math.floor(Math.sqrt(desiredNo))) {
$scope.DrawLineOdd(desiredNo, line, pozy);
//document.getElementById("val").innerHTML = teste;
line += 1;
pozy+=RectangleDim;
}
//document.getElementById('tablePrint').innerHTML = finalTable;
};
$scope.DrawLineEven=function(desiredNo, lineNo, pozY){
var pozX = lineNo*RectangleDim;
//var pozY = lineno*20;
var aux = 2*Math.floor(Math.sqrt(desiredNo))-2*lineNo;
for (var j = 0; j < aux; j++) {
$scope.rectangles.push($scope.DrawRect(pozX, pozY));
pozX += RectangleDim;
}
//return aux;
};
$scope.DrawMatrixEvenProgression=function(desiredNo) {
desiredNo=document.getElementById("NumQuest").value;
var line=0;
var pozy=0;
while(line<Math.floor((Math.sqrt(4*desiredNo+1)-1)/2)) {
$scope.DrawLineEven(desiredNo, line, pozy);
//document.getElementById("val").innerHTML = teste;
line += 1;
pozy+=RectangleDim;
}
//document.getElementById('tablePrint').innerHTML = finalTable;
};
$scope.AddExtraRectangles=function(desiredNo) {
desiredNo = document.getElementById("NumQuest").value;
var arg1 = desiredNo - ( Math.floor(Math.sqrt(desiredNo))*Math.floor(Math.sqrt(desiredNo)));
var arg2 = desiredNo-(Math.floor((Math.sqrt(4*desiredNo+1)-1)/2)*Math.floor((Math.sqrt(4*desiredNo+1)-1)/2))-Math.floor((Math.sqrt(4*desiredNo+1)-1)/2);
var OptimalLeftOver = Math.min( arg1 ,arg2 );
//We add two rectangles per row: one at the beginning one at the end
//we start with the row below the first one
var line;
var pozy;
var pozx1, pozx2;
var nRectLine_i;
if(OptimalLeftOver===arg1){
line=1;//1st line is skipped
pozy=RectangleDim;
pozx1 = 0;
while(OptimalLeftOver>0) {
nRectLine_i = 2* Math.floor(Math.sqrt(desiredNo))-1-2*line;
pozx2 = (line-1)*RectangleDim+RectangleDim*(nRectLine_i+1);//pozx1+nRectLine_i+2*RectangleDim;
$scope.rectangles.push($scope.DrawRect(pozx1,pozy));
OptimalLeftOver-=1;
if(OptimalLeftOver>0) {
$scope.rectangles.push($scope.DrawRect(pozx2, pozy));
OptimalLeftOver -= 1;
}
//document.getElementById("val").innerHTML = teste;
line += 1;
pozy+=RectangleDim;
pozx1=RectangleDim*line - RectangleDim;
}
//document.getElementById('tablePrint').innerHTML = finalTable;
}
else {
line=1;//1st line is skipped
pozy=RectangleDim;
pozx1 = 0;
while(OptimalLeftOver>0) {
nRectLine_i = 2* Math.floor(Math.sqrt(desiredNo))-2*line;
pozx2 = RectangleDim*(line-1)+RectangleDim*(nRectLine_i+1);//pozx1+nRectLine_i+2*RectangleDim;
$scope.rectangles.push($scope.DrawRect(pozx1,pozy));
OptimalLeftOver-=1;
if(OptimalLeftOver>0) {
$scope.rectangles.push($scope.DrawRect(pozx2, pozy));
OptimalLeftOver -= 1;
}
//document.getElementById("val").innerHTML = teste;
line += 1;
pozy+=RectangleDim;
pozx1=RectangleDim*line - RectangleDim;
}
//document.getElementById('tablePrint').innerHTML = finalTable;
}
};
/* $scope.DrawMatrix=function(desiredNo)
{
/* Chooses optimal leftover number based on the progression formulas.
Attempts to minimize the work of the designer of the response form without
making too much assumptions
desiredNo = document.getElementById("NumQuest").value;
var arg1 = desiredNo - ( Math.floor(Math.sqrt(desiredNo))*Math.floor(Math.sqrt(desiredNo)));
var arg2 = desiredNo - (Math.floor((Math.sqrt(4*desiredNo+1)-1)/2)*Math.floor((Math.sqrt(4*desiredNo+1)-1)/2))-Math.floor((Math.sqrt(4*desiredNo+1)-1)/2);
var OptimalLeftOver = Math.min( arg1 ,arg2 );
document.getElementById("val").innerHTML = 'There are '+OptimalLeftOver+' questions missing!'+ arg1+ '___'+arg2;
console.log(arg1);
if(OptimalLeftOver===arg1){
DrawMatrixPerfectProgression(desiredNo);
AddExtraRectangles(desiredNo);
}
else {
DrawMatrixEvenProgression(desiredNo);
AddExtraRectangles(desiredNo);
}
}; */
}
);
angular.bootstrap(document.getElementById('body'), ["app"]);
The relevant part of the code is the $scope.rectangles array which contains the JSON.parse of the strings representing my data structure on the html side and that structure in JSON (or JSON parsed or whatever) is what I want to save in the MongoDB database...How can I do that? The HTML relevant part is just like this:
HTML:
<p><button ng-click="DrawMatrixEvenProgression(NumQuest)">Draw</button></p>
<svg ng-attr-height="{{graph.height}}" ng-attr-width="{{graph.width}}">
<rect ng-repeat="rect in rectangles"
ng-attr-x="{{rect.x}}"
ng-attr-y="{{rect.y}}"
ng-attr-width="{{rect.width}}"
ng-attr-height="{{rect.height}}">
</rect>
</svg>
Any help will be appreciated... Can I start by adding more files to that project to handle the database and then things will be linked together?
Like adding stuff to handle the mongoose and the connections?
Thanks in advance!
Because Angular is a front-end framework. So to communicate with database (in this case MongoDB) you need to have application on the server-side to handle this and I suggest you to use Node.js and Mongoose as a MongoDB driver.
Node.js
Mongoose
Come back to Angular, you can create Angular service or factory and let the them talk to your server with service like $http or $resource.
Angular service documentation
Example for angular service
angular.module('app')
.factory('RectangleService', function($http){
return {
create: create
}
function create(rectangle){
// make http request to the server
return $http({
url: 'API_URL',
method: 'GET',
params: rectangle
});
}
});
After you create your service you have to inject it to your controller and
you may create some function to your $scope to talk with service like this
app.controller('MainCtrl', function($scope, RectangleService) { // <-- Inject service to controller
// your controller code
$scope.createRectangle = function(rectangle){
RectangleService.create(rectangle);
}
});
You can map createRectangle function to directive like ng-click and pass your json data as a parameter
Because I don't know what server-side language you can use, so I don't come with an example for Node.js & Mongoose
Hope this can help :)

Unnesting json object

My sample json is
"multiList": [
{
"my_key" : "this is my key"
},
{
"my_text_box": "This is my text box"
},
]
How do I convert this to
{"my_key" : "this is my key"},
{my_text_box": "This is my text box"},
dynamically?
using jquery
Your question doesn't make sense. Are you asking to convert to two separate objects? A string representation of those two objects? Something else? I can do the first two:
var objOne = json.multiList[0];
var objTwo = json.multiList[1];
var objStr = JSON.stringify(json.multiList[0]) + ', '
+ JSON.stringify(json.multiList[1]);
If you want to add all of the separate properties into one object, you can just extend another object in a loop.
var obj = {};
json.multiList.forEach(function (elem) {
for (k in elem) {
if (elem.hasOwnProperty(k)) {
obj[k] = elem[k];
}
}
});
http://jsfiddle.net/ExplosionPIlls/t2xyd/
This makes no consideration for the overriding of properties in obj.

nested html list to json

[
{
"tree_id": 6,
"fields" : ["id","lft", "rgt"], // tree_id is stripped if requested via fields because redundant
"values" :
[1,1,4,[
[2,2,3,[]]
]]
}
// more could follow ...
]
above is the json code that Bobab uses to export/import nested sets.
Baobab nested set json export/import format
How can i parse a nested html list to yield json like above?
I am trying to manipulate nested lists using drag and drop
Nestable list
It has 2 functions that kind of do what i want to achieve, but my head keeps twisting around it.
toHierarchy: function(options) {
var o = $.extend({}, this.options, options),
sDepth = o.startDepthCount || 0,
ret = [];
$(this.element).children(o.items).each(function () {
var level = _recursiveItems(this);
ret.push(level);
});
//console.log(JSON.stringify(ret));
return ret;
function _recursiveItems(item) {
var id = ($(item).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
if (id) {
var currentItem = {"id" : id[2]};
if ($(item).children(o.listType).children(o.items).length > 0) {
currentItem.children = [];
$(item).children(o.listType).children(o.items).each(function() {
var level = _recursiveItems(this);
currentItem.children.push(level);
});
}
return currentItem;
}
}
},
toArray: function(options) {
var o = $.extend({}, this.options, options),
sDepth = o.startDepthCount || 0,
ret = [],
left = 2;
ret.push({
"item_id": o.rootID,
"parent_id": 'none',
"depth": sDepth,
"left": '1',
"right": ($(o.items, this.element).length + 1) * 2
});
$(this.element).children(o.items).each(function () {
left = _recursiveArray(this, sDepth + 1, left);
});
ret = ret.sort(function(a,b){ return (a.left - b.left); });
//console.log(JSON.stringify(ret));
return ret;
function _recursiveArray(item, depth, left) {
var right = left + 1,
id,
pid;
if ($(item).children(o.listType).children(o.items).length > 0) {
depth ++;
$(item).children(o.listType).children(o.items).each(function () {
right = _recursiveArray($(this), depth, right);
});
depth --;
}
id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
if (depth === sDepth + 1) {
pid = o.rootID;
} else {
var parentItem = ($(item).parent(o.listType)
.parent(o.items)
.attr(o.attribute || 'id'))
.match(o.expression || (/(.+)[-=_](.+)/));
pid = parentItem[2];
}
if (id) {
ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right});
}
left = right + 1;
return left;
}
},
If your goal is to insert that data on the database using the Baobab library then you do not need to create the JSON code with the left/right indexes yourself, which can be fairly complicated to do.
Just send to the server tree structured data and on server side iterate over it adding the objects to the database.
You could create a generic tree structure with something like this (using jQuery to have a shorter example):
function genTree(domNode){
var parentObj = {
data : { /* filled with data found in domNode, e.g. the baobab node id */ },
children: []
};
$(domNode).find('> li, > ul > li').each(function(){
parentObj.children.push(genTree(this));
});
return parentObj;
}
Then when you'll travel the structure you will use the Baobab API to add the nodes to your database (at that point you can export it to JSON if you really need it)

Scroll to alphabet in a List (ArrayCollection dataProvider) (Alphabet Jump)

Hopefully this is easy but that sometimes means its impossible in flex and I have searched quite a bit to no avail.
Say I have a list (LIST#1) of artists:
2Pac
Adele
Amerie
Beyonce
Jason Aldean
Shakira
The Trews
I also have a list (LIST#2) that has the values #,A-Z - how would I create an alphabet jump?
So If a user clicked on "A" in LIST#2 that would automatically scroll to "Adele" at the top of LIST#1 - not filter so he/she could scroll up to view 2Pac or down to view The Tews if they were not in the view yet.
Its a standard Flex Spark List with an ArrayCollection as the dataProvider - the artist field is called: "title" along with a unique id field that is not visible to the user.
Thanks!
Please see comments on marker answer for discussion on Dictionary that may be faster in some cases. See below for code (HAVE NOT CONFIRMED ITS FASTER! PLEASE TEST):
private function alphabet_listChange(evt:IndexChangeEvent) : void {
var letter:String;
letter = evt.currentTarget.selectedItems[0].toString();
trace(currentDictionary[letter]);
ui_lstLibraryList.ensureIndexIsVisible(currentDictionary[letter]);
}
public function createAlphabetJumpDictionary() : Dictionary {
//alphabetArray is a class level array containing, A-Z;
//alphabetDictionary is a class level dictionary that indexes A-z so alphabetDictionary["A"] = 0 and ["X"] = 25
var currentIndexDict:Dictionary = new Dictionary; //Dictionary is like an array - just indexed for quick searches - limited to key & element
var searchArray:Array = new Array;
searchArray = currentArrayCollection.source; //currentArrayCollection is the main array of objects that contains the titles.
var currentIndex:Number; //Current index of interation
var currentAlphabetIndex:Number = 0; //Current index of alphabet
for (currentIndex = 0; currentIndex < searchArray.length; currentIndex++) {
var titleFirstLetter:String = searchArray[currentIndex].title.toString().toUpperCase().charAt(0);
if (titleFirstLetter == alphabetArray[currentAlphabetIndex]) {
currentIndexDict[titleFirstLetter] = currentIndex;
trace(titleFirstLetter + " - " + currentIndex);
currentAlphabetIndex++;
} else if (alphabetDictionary[titleFirstLetter] > alphabetDictionary[alphabetArray[currentAlphabetIndex]]) {
trace(titleFirstLetter + " - " + currentIndex);
currentIndexDict[titleFirstLetter] = currentIndex;
currentAlphabetIndex = Number(alphabetDictionary[titleFirstLetter] + 1);
}
}
return currentIndexDict;
}
private function build_alphabeticalArray() : Array {
var alphabetList:String;
alphabetList = "A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z";
alphabetArray = new Array;
alphabetArray = alphabetList.split(".");
return alphabetArray;
}
private function build_alphabetDictionary() : Dictionary {
var tmpAlphabetDictionary:Dictionary = new Dictionary;
for (var i:int=0; i < alphabetArray.length; i++) {
tmpAlphabetDictionary[alphabetArray[i]] = i;
trace(alphabetArray[i] + " - " + i);
}
return tmpAlphabetDictionary;
}
private function buildCurrentDictionary() : void {
trace("Collection Changed");
currentDictionary = new Dictionary;
currentDictionary = createAlphabetJumpDictionary();
}
The Flex Spark list has a very convenient method called ensureIndexIsVisible(index). Check the Flex reference documentation. All you have to do is to find the index of the first artist for the corresponding selected alphabet letter:
public function findAlphabetJumpIndex():Number
{
var jumpToIndex:Number;
var selectedLetter:String = alphabethList.selectedItem;
for (var i:int=0; i < artists.length; i++)
{
var artistName:String = artists.getItemAt(i);
var artistFirstLetter:String = artistName.toUpperCase().charAt(0);
if (artistFirstLetter == selectedLetter)
{
jumpToIndex = i;
break;
}
}
return jumpToIndex;
}
You can iterate your artist list data provider and check if artist name starts with selected alphabet from list two. When corresponding artist is found, set artist list selected index a value what you get from iterating data.