In order to make this work we need to have some data to make a results list from. In this example we are using two XML files to provide that data. Open up the pagDemo.fla and it's Document Class, PagDemo.as. You'll notice in the pageDemo.fla that I haven't lied to you, and there is nothing on the the stage and the only thing in the library is an instance of the Button component. Under the Document Class setting we have declared PagDemo - no .as, just the class name - as the Document Class. Let's switch over to that file.

Starting from the top, we import the necessary classes.
package{
  import flash.display.*;
  import flash.events.*;
  import flash.geom.*;
  import flash.net.*;
  import flash.text.*;
  import fl.controls.Button;
  import flash.external.ExternalInterface;
  import ca.xty.myUtils.NextPrev;
  import ca.xty.myUtils.CustomEvent;


The two custom classes we need are found in the ca.xty.myUtils folder and they are NextPrev.as and CustomEvent.as. We will discuss these, and the ExternalInterface class, in more detail as we go along. Next we set up our variables.
public class PagDemo extends MovieClip{
       
  //XML variables
  private var dataLoader:URLLoader = new URLLoader();
  private var xmlData:XML = new XML();
  private var musicInfoArray:Array;

  //On screen assets
  private var musicBut1:Button;
  private var musicBut2:Button;
  private var goBtn:Button;
  private var t1:TextField;
  private var ip1:TextField;
   
  //Data display variables
  private var barArray:Array;
  private var titleArray:Array;
  private var composerArray:Array;
  private var descArray:Array;
  private var songLengthArray:Array;
  private var cartArray:Array;
  private var titleHead:TextField;
  private var timeHead:TextField;
  private var composerHead:TextField;
  private var descHead:TextField;
  private var buyHead:TextField;
  private var buyArray:Array;
       
  //Pagination variables
  private var npT:NextPrev;
  private var npB:NextPrev;
  private var useNP:Boolean = false;
  private var maxNum:int = 5;
  private var numSongs:int;
  private var itemStart:int = 0;
  private var itemsToShow:int;
  private var showingItem:int = 1;
  private var numVisible:int;
  private var nBtn:Boolean;
  private var pBtn:Boolean;
  private var firstPage:Boolean = true;
  private var resultsTop:Sprite;
  private var resultsHolder:Sprite;

  // TextFormats
  private var titleFormat:TextFormat;
  private var titleFormatC:TextFormat;
       
  //X and Y positions
  private var xPos:int;
  private var yPos:int;


First up, we get our XML ducks in a row. We declare a URLLoader to get the XML files off the server. Then we have a an XML object, and finally an array called musicInfoArray which is an array that we will be dumping all the results from the XML files in.

Our On Screen assets include the buttons to grab the music and another button which allows us to set the number of results we want to show at one time. The TextFields are a label field and an input field to enter in the number of desired results.

The Data Display variables are the things we will be using to show the results. These consist of arrays and TextFields.

The Pagination variables are the things we will be using to keep track of where we are and what is happening within the pagination process. The first two, npT and npB are variables to represent instances of our class NextPrev and stand for NextPrev Top and NextPrev Bottom. The useNP is a Boolean that will tell us whether or not we need to use an instance of the NextPrev class by determining the number of results and balancing that against the next variable maxNum. So, if we have 5 results and our maxNum is 10 then we do not need to use the NextPrev instance. If the opposite is true, then we need it. We set the maxNum to have an initial value of 5, but this can be whatever number of results you want to show. The variable itemStart is set to 0, and showingItem is set to 1. These values are what we need to get started. Then we have a bunch of integer values to pass information back and forth to the NextPrev class, a few more Booleans to let us know where we stand, and finally a couple of Sprites that we will be using as containers to hold our results. Using containers like this will provide us an easy way to remove the results in a single step.

Next up is our constructor.
public function PagDemo(){
           
  //Set up the TextFormats
  titleFormat = new TextFormat();
  titleFormat.color = 0x000000;
  titleFormat.font = "verdana";
  titleFormat.size = 10;
  titleFormat.align = "left";
           
  titleFormatC = new TextFormat();
  titleFormatC.color = 0x000000;
  titleFormatC.font = "verdana";
  titleFormatC.size = 10;
  titleFormatC.align = "center";
           
  //Give our XML Loader a Complete event listener
  dataLoader.addEventListener(Event.COMPLETE, loadData);
           
  //Put our assets on stage
  musicBut1 = new Button();
  musicBut1.x = 20;
  musicBut1.y = 10;
  musicBut1.width = 120;
  musicBut1.height = 20;
  musicBut1.label = "Rock Music (13)";
  musicBut1.addEventListener(MouseEvent.CLICK, musicButHandler);
  addChild(musicBut1);
           
  musicBut2 = new Button();
  musicBut2.x = 150;
  musicBut2.y = 10;
  musicBut2.width = 120;
  musicBut2.height = 20;
  musicBut2.label = "Easy Listening (4)";
  musicBut2.addEventListener(MouseEvent.CLICK, musicButHandler);
  addChild(musicBut2);
           
  t1 = new TextField();
  t1.x = 280;
  t1.y = 10;
  t1.width = 90;
  t1.height = 20;
  t1.text = "Items to Show:";
  t1.setTextFormat(titleFormat);
  addChild(t1);
           
  ip1 = new TextField();
  ip1.x = 375;
  ip1.y = 10;
  ip1.width = 30;
  ip1.height = 20;
  ip1.type = "input";
  ip1.border = true;
  ip1.defaultTextFormat = titleFormatC;
  ip1.text = String(maxNum);
  addChild(ip1);
           
  goBtn = new Button();
  goBtn.x = 410;
  goBtn.y = 10;
  goBtn.width = 30;
  goBtn.height = 20;
  goBtn.label = "Go";
  goBtn.addEventListener(MouseEvent.CLICK, goHandler);
  addChild(goBtn);
           
}


First we give our TextFormats some properties. They are nearly identical, with the only difference being the text align property.

Next we add a COMPLETE Event Listener to our XML dataLoader and direct it at a function called loadData.

Now we stick our stage assets in place. These are the buttons that will allow you to choose between Rock Music and Easy Listening. The numbers in parentheses represent the number of songs available in each category. I have taken a short cut here. In a real application, you would be counting the number of incoming results and appending that number to the button label. The last three assets go to make up our
number-of-results-to-see-at-once feature. A title field with a label of Items to Show, an input field to gather the answer and the goBtn to make it happen. Our goBtn has an event listener for a CLICK event and takes you to a function called goHandler.
private function goHandler(e:MouseEvent):void{
  //As long as the input field is not empty, we change the variable maxNum to the contents of the ip1 TextField
  if(ip1.text != ""){
    maxNum = Number(ip1.text);
  }
  //If the boolean firstPage is not true we remove the data already displayed on stage and reset our variables to start over
  if(!firstPage){
    removeChild(resultsTop);
    removeChild(resultsHolder);
    if(useNP){
      removeChild(npB);
      useNP = false;
    }
    firstPage = true;
    showingItem = 1;
    itemStart = 0;
    }
    //Check to see if numSongs is greater than the new maxNum and then buildResults again using the the new maxNum
    if(numSongs > maxNum){
      useNP = true;
    }else if(numSongs <= maxNum){
      itemsToShow = numSongs;
    }
  // Now build the results
  buildResults();
}


The first thing we check is whether or not our input field, ip1, has anything in it. As long as it is not equal to nothing, we set the variable maxNum to whatever is in the ip1 field. To use this in a project you would want to issue some kind of an alert at this point for those who push buttons first and provide answers later. Next we need to determine if the boolean firstPage is true or not. If it is not true, then that means we already have something on stage that we need to get rid of before proceeding. So we remove our two Sprites, resultsTop and resultsHolder. Now we check the useNP variable to see whether we are using an instance of our NextPrev on the bottom. If it's true, then we remove that instance as well.

Once everything is off stage, we reset the first Page variable to true, the showingItem to 1 and our itemStart to 0. Finally we check to see if numSongs is greater than the new maxNum, and then buildResults() again using the the new maxNum.

Next we'll look at our music button handler.

private function musicButHandler(e:MouseEvent):void{
  switch(e.currentTarget.label){
    case "Rock Music (13)":
      dataLoader.load(new URLRequest("rockMusic.xml"));
      break;
    case "Easy Listening (4)":
      dataLoader.load(new URLRequest("easyMusic.xml"));
      break;
  }
}


We use a switch statement, with the label data as the criteria, and then load the appropriate XML file. You'll remember that we already set up our listener for the dataLoader and declared it's function to be loadData.
private function loadData(e:Event):void {
  try{
    xmlData = new XML(e.target.data);
    parseData(xmlData);
  } catch (e:TypeError){
    trace("Unable to load XML");
  }
}


Here we assign the incoming data property to our XML object called xmlData, and then send that data to a function called parseData.

private function parseData(dataInput:XML):void {
  musicInfoArray = new Array();
  var infoList:XMLList = dataInput.song.composer;
  numSongs = infoList.length();
  for(var i:int = 0; i < numSongs; i++){
    var comp:String = dataInput.song[i].composer;
    var track:String = dataInput.song[i].title;
    var tl:String = dataInput.song[i].track_length;
    var d:String = dataInput.song[i].description;
    var musicObj:Object = {Composer:comp, Track:track, TrackLength:tl, Desc:d};
    musicInfoArray.push(musicObj);
  }
  //If the boolean firstPage is not true, then we remove the current data displayed and reset our variables to start over
  if(!firstPage){
    removeChild(resultsTop);
    removeChild(resultsHolder);
    if(useNP){
      removeChild(npB);
      useNP = false;
    }
    firstPage = true;
    showingItem = 1;
    itemStart = 0;
  }
  //If numSongs is greater then the maxNum to be shown, then we will need our next/prev feature so set the boolean useNP to true
  //and then buildResults
  if(numSongs > maxNum){
    useNP = true;
  }else if(numSongs <= maxNum){
    itemsToShow = numSongs;
  }
  // Now we build the results
  buildResults();
}


We set our musicInfoArray to empty by declaring a new instance of it. This array is going to hold an array of objects, with each object in the array containing all the information we need about one song. Next we declare a temporary variable called infoList that will hold our XMLList data, and we set it to point to the composer block in our XML file. We determine our numSongs variable by giving it the length value of our infoList. Notice here that the length property is declared as a function - length() - not the length property we normally see when getting the length of an array - such as someArray.length.

Now we use a for loop to gather all the available data and package it into an object - musicObj -, which we then push into our musicInfoArray. Once we have all the data stored away, we run through our check to see if this is the firstPage or not, and whether the numSongs is greater than the maxNum we set. This is the same routine as in our goHandler function we discussed above. Once we are ready, we buildResults().