Get Adobe Flash player

The Work Horse - NextPrevPN.as

This is where all the magic happens. First off we import all the classes we need.

package ca.xty.myUtils {
    import flash.display.*;
    import flash.text.*;
    import flash.events.*;
    import flash.utils.*;
    import flash.net.*;
    import fl.controls.Button;
    import ca.xty.myUtils.*;

Now we set up our variables.

public class NextPrevPN extends MovieClip {
		
    private var nextBtn:Button;
    private var prevBtn:Button;
    private var firstBtn:Button;
    private var lastBtn:Button;
		
    private var _numItems:int;// This is our total number of items
    private var _maxItems:int;// This is the number of items we want to show at one time
    private var itemStart:int;// This is the we use in our for loop to tell us which point in the array to start counting at
    private var _itemsToShow:int;// This is the number of items we are currently showing
    private var _txtColor:Number;// Text color
    private var _btnColor:Number;// Text color for the button
    private var _nBtn:Boolean;// This variable lets us know whether the Next button is currently enabled 
    private var _pBtn:Boolean;// This variable lets us know whether the Prev button is currently enabled
		
    private var buttonArray:Array;
    private var numPages:uint;
    private var _numButtons:uint;
    private var curPageBut:int = -1;
    private var newPageBut:int = 0;
    private var curPage:int = -1;
    private var newPage:int;
    private var firstPage:int;
    private var lastPage:int;
    private var pageStart:int;
    private var buttonCalc:int;
		
    private var statsArray:Array;// This is the array we will be passing back to the main class via our Custom Event
		
    //Display text fields
    private var st1:TextField;
    private var st2:TextField;
    private var st3:TextField;
    private var st4:TextField;
    //Our text formats
    private var showingFormat:TextFormat;
    private var showingFormatC:TextFormat;
    private var butFormat:TextFormat;
    private var butDownFormat:TextFormat;
    //Our x and y position variables
    private var xPos:int;
    private var yPos:int;

The comments tell the story pretty well. From the main class we are receiving the Total Number of Items, the Numbers of Items to Show at Once, the visual Number of Items to be Shown, the Text Color, the Button text color and the number of buttons to show at once.

public function NextPrevPN(numItems:int, maxItems:int, itemsToShow:int, txtColor:Number, btnColor:Number, numButs:uint){
    // Add our passed parameters to our class variables
    _numItems = numItems; 
    _maxItems = maxItems; 
    _itemsToShow = itemsToShow; 
    _txtColor = txtColor; 
    _btnColor = btnColor; 
    _numButtons = numButs;
			
    numPages = Math.ceil(_numItems/_maxItems);
    if(numPages < _numButtons){
        _numButtons = numPages;
    }
    buttonCalc = Math.floor(_numButtons/2);

First we transfer the incoming parameters in the constructor to the declared class variables. Then we figure out our total number pages by dividing our total items (_numItems) by the items to show per page (_maxItems) and use Math.ceil to round up. We want to round up because if you have 24 items and you are showing a maximum of 10 items per page you will have 2 full pages and a third page with 4 items on it. If we rounded down we would loose those last 4 items. Once we establish the number of pages we check that against the number of buttons we have decided to show (_numButtons). If numPages is less than _numButtons then we set _numButtons to equal numPages. The variable buttonCalc takes our _numButtons and divides it by 2 and then uses Math.floor to round it down. What the buttonCalc variable is going to do for us is set the number of pages we will move the page menu by when we reach the visible end of the buttons. It is best if your _numButtons (number of buttons showing on the screen) is an even number, but if it's not then the Math.floor will make sure we don't call for, say, 4 1/2 buttons. To see what I am talking about go to the demo movie and click on the last visible page button, number 8. Notice how the number 8 button moves back to approximately the middle, removing buttons 1- 4 from the beginning of the button menu, and making visible buttons 9 - 12. Our _numButtons variable is set to 8, so our buttonCalc is 4 and that is what causes the first 4 buttons to disappear and the next 4 buttons in the series to appear.

    // Set up our text formats
    showingFormat = new TextFormat();
    showingFormat.color = _txtColor;
    showingFormat.align = "left";
    showingFormat.size = 10;
    showingFormat.font = "verdana";
			
    showingFormatC = new TextFormat();
    showingFormatC.color = _txtColor;
    showingFormatC.align = "center";
    showingFormatC.size = 10;
    showingFormatC.font = "verdana";
			
    butFormat = new TextFormat();
    butFormat.color = _btnColor;
    butFormat.size = 10;
    butFormat.font = "verdana";
			
    butDownFormat = new TextFormat();
    butDownFormat.color = 0xff0000;
    butDownFormat.size = 10;
    butDownFormat.font = "verdana";
    // Set our initial x and y positions
    xPos = 0;
    yPos = 20;
			
    // Set up our first page button
    firstBtn = new Button();
    firstBtn.x = xPos;
    firstBtn.y = yPos;
    firstBtn.width = 40;
    firstBtn.height = 24;
    firstBtn.useHandCursor = true;
    firstBtn.label = "First";
    firstBtn.setStyle("upSkin", Button_upSkinPN);
    firstBtn.setStyle("overSkin", Button_overSkinPN);
    firstBtn.setStyle("downSkin", Button_downSkinPN);
    firstBtn.setStyle("disabledSkin", Button_disabledSkinPN);
    firstBtn.setStyle("textFormat", butFormat);
    firstBtn.addEventListener(MouseEvent.CLICK, npHandler);
    firstBtn.enabled = false;
    addChild(firstBtn);
			
    xPos += 45;
		
    // Set up our previous button
    prevBtn = new Button();
    prevBtn.x = xPos;
    prevBtn.y = yPos;
    prevBtn.width = 60;
    prevBtn.height = 24;
    prevBtn.useHandCursor = true;
    prevBtn.label = "<< Prev";
    prevBtn.setStyle("upSkin", Button_upSkinPN);
    prevBtn.setStyle("overSkin", Button_overSkinPN);
    prevBtn.setStyle("downSkin", Button_downSkinPN);
    prevBtn.setStyle("disabledSkin", Button_disabledSkinPN);
    prevBtn.setStyle("textFormat", butFormat);
    prevBtn.addEventListener(MouseEvent.CLICK, npHandler);
    prevBtn.enabled = false;
    addChild(prevBtn);
			
    xPos += 65;
			
    var x1:int = xPos;

After we add some properties to our TextFormats, we set the initial value of xPos and yPos to 0 and then we begin to build our NextPrevPN menu. We have a First Page button, and next to it a Previous button. Notice that we are using our custom button skins here. At the very beginning we won't have any pages that come before this, and we are already on the first page, so we initially set both of these buttons to enabled = false. We are going to need a reference point to tell us where the page buttons start on the X axis, so we set up the x1 variable and set it equal to the current xPos position.

    // Our variable itemStart will always be 0 at the beginning
    itemStart = 0;
    pageStart = 0;
    buttonArray = new Array();
    var j:uint = pageStart + 1;
    for(var i:int = 0; i < _numButtons; i++){
        buttonArray[i] = new Button();
        buttonArray[i].x = xPos;
        buttonArray[i].y = yPos;
        buttonArray[i].width = 28;
        buttonArray[i].height = 24;
        buttonArray[i].toggle = true;
        buttonArray[i].label = j;
        buttonArray[i].name = i;
        buttonArray[i].useHandCursor = true;
        buttonArray[i].setStyle("upSkin", Button_upSkinPN);
        buttonArray[i].setStyle("overSkin", Button_overSkinPN);
        buttonArray[i].setStyle("downSkin", Button_downSkinPN);
        buttonArray[i].setStyle("selectedUpSkin", Button_selectedUpSkinPN);
        buttonArray[i].setStyle("selectedOverSkin", Button_selectedOverSkinPN);
        buttonArray[i].setStyle("selectedDownSkin", Button_selectedDownSkinPN);
        buttonArray[i].setStyle("textFormat", butFormat);
        buttonArray[i].addEventListener(MouseEvent.CLICK, pageListener);
        addChild(buttonArray[i]);
        xPos += 28;
        j++;
    }
    firstPage = parseInt(buttonArray[0].label);
    lastPage = parseInt(buttonArray[_numButtons - 1].label);
    newPageBut = 0;
    newPage = 1;
    butState();
			
    var x2:int = xPos;

Now we build the page buttons. On the first time through our variables itemStart and pageStart will be zero. Then we initialize our buttonArray and set up a variable j to equal pageStart + 1. We will use j to set the label on our buttons. Even though we as programmers need to start things at 0, our visitors expect the first page to be 1.

Using a for loop we create enough page buttons to satisfy our _numButtons variable. Note that we are setting the toggle property to true and that we are making use of our custom button skins once again. Because toggle is true, we need to use our selected states skins as well.

Once we have the buttons in place, we initialize of firstPage and lastpage variables using parseInt to take our button labels and turn them back into integers. The newPageBut and newPage variables are initialized as well. We will be using these in our function butState(). This function will act as our toggle button handler. Normally a toggle button is used by clicking it once and then clicking it again to release the state, but we don't want people to have to unclick our page buttons, we only want the toggle feature to show them visually which page button is clicked. Lastly, we create a variable called x2 as a reference to the ending position of our button menu.

    xPos += 5;
			
    // Set up our Next button
    nextBtn = new Button();
    nextBtn.x = xPos;
    nextBtn.y = yPos;
    nextBtn.width = 60;
    nextBtn.height = 24;
    nextBtn.useHandCursor = true;
    nextBtn.label = "Next >>";
    nextBtn.setStyle("upSkin", Button_upSkinPN);
    nextBtn.setStyle("overSkin", Button_overSkinPN);
    nextBtn.setStyle("downSkin", Button_downSkinPN);
    nextBtn.setStyle("disabledSkin", Button_disabledSkinPN);
    nextBtn.setStyle("textFormat", butFormat);
    nextBtn.addEventListener(MouseEvent.CLICK, npHandler);
    addChild(nextBtn);
			
    xPos += 65;
			
    // Set up our Last button
    lastBtn = new Button();
    lastBtn.x = xPos;
    lastBtn.y = yPos;
    lastBtn.width = 40;
    lastBtn.height = 24;
    lastBtn.useHandCursor = true;
    lastBtn.label = "Last";
    lastBtn.setStyle("upSkin", Button_upSkinPN);
    lastBtn.setStyle("overSkin", Button_overSkinPN);
    lastBtn.setStyle("downSkin", Button_downSkinPN);
    lastBtn.setStyle("disabledSkin", Button_disabledSkinPN);
    lastBtn.setStyle("textFormat", butFormat);
    lastBtn.addEventListener(MouseEvent.CLICK, npHandler);
    addChild(lastBtn);

To give us a bit of room we add 5 to our xPos and then put our Next and Last buttons in place.

    xPos = x1 + (((x2 - x1) - 220)/2);
    yPos -= 20;
	
    // Set up our text fields to show the results
    st1 = new TextField();
    st1.x = xPos;
    st1.y = yPos;
    st1.width = 80;
    st1.height = 20;
    st1.text = "Total Items:";
    st1.setTextFormat(showingFormatC);
    addChild(st1);
			
    xPos += 80;
		
    st2 = new TextField();
    st2.x = xPos;
    st2.y = yPos;
    st2.width = 30;
    st2.height = 20;
    st2.text = String(_numItems);
    st2.setTextFormat(showingFormatC);
    addChild(st2);
				
    xPos += 30;
			
    st3 = new TextField();
    st3.x = xPos;
    st3.y = yPos;
    st3.width = 80;
    st3.height = 20;
    st3.text = "Total Pages:";
    st3.setTextFormat(showingFormatC);
    addChild(st3);
				
    xPos += 80;
				
    st4 = new TextField();
    st4.x = xPos;
    st4.y = yPos;
    st4.width = 30;
    st4.height = 20;
    st4.text = String(numPages);
    st4.setTextFormat(showingFormatC);
    addChild(st4);
				
}

To set up the text fields to show us our total items and total pages information we need to first calculate our xPos. It will equal x1 (starting reference) plus x2 (ending reference) minus x1 minus 220 ( the total width of the 4 text fields, st1, st2, st3 and st4) divided by 2. This will center it within the button menu. Because I want to place it on top of the button menu we subtract 20 from our current yPos. That done, we set up our text fields and we are good to go.

private function pageListener(e:MouseEvent = null):void{
    if(e != null){
        newPage = parseInt(e.target.label);
        newPageBut = e.target.name;
    }
    if(newPage > 1){
        prevBtn.enabled = true;
        firstBtn.enabled = true;
    }else if(newPage <= 1){
        prevBtn.enabled = false;
        firstBtn.enabled = false;
    }
		
    if(newPage >= numPages){
        nextBtn.enabled = false;
        lastBtn.enabled = false;
    }else if(newPage < numPages){
        nextBtn.enabled = true;
        lastBtn.enabled = true;
    }
			
    if(newPage == firstPage && newPage > 1){
        if(newPage - buttonCalc > 0){
            var extraPage:int = pageStart % buttonCalc;
            if(extraPage > 0){
                pageStart -= extraPage;
                newPageBut += ((pageStart - buttonCalc) + extraPage);
            }else{
                pageStart -= buttonCalc;
                newPageBut += (pageStart + buttonCalc);
            }
        }else if(newPage - buttonCalc == 0){
            if(pageStart - buttonCalc >= 0){
                pageStart -= buttonCalc;
                newPageBut += (pageStart + buttonCalc);
            }else{
                pageStart = 0;
                newPageBut = newPage - 1;
            }
        }else if(newPage - buttonCalc < 0){
            newPageBut = pageStart;
            pageStart = 0;
        }
        buttonArray[0].selected = false;
        buildPageButtons();
    }else if(newPage == firstPage && newPageBut == 0){
        pageStart = 0;
        buildPageButtons();
    }
			
    if(newPage == lastPage && (newPage + buttonCalc) <= numPages){
        pageStart += buttonCalc;
        newPageBut -= buttonCalc;
        buttonArray[_numButtons-1].selected = false;
        buildPageButtons();
    }else if(newPage == lastPage && numPages - newPage > 0){
        pageStart += (numPages - newPage);
        if((pageStart - buttonCalc) < 0){
            newPageBut -= pageStart;
        }else{
            newPageBut -= (pageStart - buttonCalc);
        }
        buttonArray[_numButtons-1].selected = false;
        buildPageButtons();
    }else if(newPage == lastPage && (numPages - newPage) == 0){
        pageStart = (numPages - _numButtons);
        buildPageButtons();
    }
    butState();
    itemStart = (_maxItems * newPage) - _maxItems;
    _itemsToShow = _maxItems * newPage;
		
    if(newPage > curPage){
        if(_itemsToShow >= _numItems){
            _itemsToShow = _numItems;
        }
    }
			
    if(newPage < curPage){
        if(_itemsToShow > _maxItems){
            var mod = _itemsToShow % _maxItems;
            if(mod > 0){
                _itemsToShow -= mod;
                _itemsToShow += _maxItems;
            }
        }
			
        if(_itemsToShow <= _maxItems && _numItems >= _maxItems){
            _itemsToShow = _maxItems;
        }
    }
			
    statsArray = new Array();
    statsArray.push(pageStart);
    statsArray.push(newPage);
    statsArray.push(newPageBut);
    statsArray.push(itemStart);
    statsArray.push(_itemsToShow);
    statsArray.push(nextBtn.enabled);
    statsArray.push(prevBtn.enabled);
    statsArray.push(firstBtn.enabled);
    statsArray.push(lastBtn.enabled);
    dispatchEvent(new CustomEvent(CustomEvent.CUSTOM, statsArray));
			
    curPage = newPage;
}

The function pageListener is the event handler for the page buttons we just set up. It has a lot to keep its eye on. Notice that the MouseEvent is set to equal null. The reason we do this is so that we can call it from a MouseEvent, someone clicks a page button, or we can call it without the use of a button click. We'll be doing that in the function npHandler which is the event listener for the First Page, Previous, Next and Last Page buttons.

The first thing we check is whether or not e is equal to null. If it is not equal to null, meaning that a page button was clicked, then we set the newPage variable to equal the label of the page button that was clicked. We turn it from a String into an Integer using the parseInt function. Then we set the newPageBut to equal the button name property.

If newPage is greater than 1 then we enable the prevBtn and the firstBtn, otherwise if it is less than or equal to 1 we disable the prevBtn and the firstBtn.

If the newPage is greater than or equal to numPages, meaning that we are at the end of the series of page buttons, we set the nextBtn and the lastBtn to be disabled, otherwise we enable both of them.

Now, if newPage is equal to firstPage ( this is the first page button showing, not necessarily page number 1) and newPage is greater than 1, we then check to see if newPage minus buttonCalc is greater than 0. If it is, then we create the variable extraPage as an integer and set it to be equal to the modulo of pageStart and buttonCalc, which is the remainder of pageStart divided by buttonCalc. Now, if extraPage is greater than 0, pageStart minus equals extraPage which is another way of saying that pageStart equals pageStart minus extraPage. Then the newButPage variable is set to equal pageStart minus buttonCalc plus extraPage. If extraPage is not greater than zero, then pageStart minus equals buttonCalc, and newPageBut plus equals pageStart plus buttonCalc.

Now, if newPage minus buttonCalc is equal to 0, then we check to see if pageStart minus buttonCalc is greater than or equal to 0. If that's true, then pageStart minus equals buttonCalc and newPageBut plus equals pageStart plus buttonCalc. If, however, pageStart minus buttonCalc is not greater than or equal to 0, then pageStart equals 0 and newPageBut = newPage minus 1.

And finally, if newPage minus buttonCalc is less than 0, then newPageBut equals pageStart and pageStart equals 0. Now we set the 0 index of our buttonArray's selected property to false, and call the function buildPageButtons.

We are not done checking yet. If our first if statement: newPage == firstPage && newPage > 1 . If that was false then we want to see if newPage is equal to firstPage and if numPages minus newPage is equal to 0. If that is true, then pageStart equals numPages - _numButtons, and then we call the function buildPageButtons.

After all that checking is done, we call the butState function to update the page buttons selected states. The we recalculate our itemStart, setting it to equal the (_maxItems times newPage) - _maxItems. And we set our _itemsToShow variable to equal _maxItems times newPage.

More checking. If newPage is greater than curPage, and if _itemsToShow is greater than or equal to _numItems, then _itemsToShow equals _numItems.

However, if newPage is less than curPage, and if _itemsToShow is greater than _maxItems, then we create a var called mod which equals the modulo (remainder) of _itemsToShow divided by _maxItems. Now, if mod is greater than zero, then _itemsToShow minus equals mod and _itemsToShow plus equals _maxItems. What is happening here is that we are getting rid of the remainder we attached when we were moving forward through the pages.

One last check: if _itemsToShow is less than or equal to _maxItems and if _numItems is greater than or equal to _maxItems, then set _itemsToShow to be equal to _maxItems. This makes sure that we don't run past the value of _numItems.

Now that we have checked everything out and adjusted the variables accordingly, we package up the variables into a new instance of the statsArray. These are the items that we will need to have to properly update the other instance of our NextPrevPN, whether it is the top instance or the bottom one. Once the statsArray is ready, we use our Custom Event to pass it back to the document class.

The last thing we need to do is set our curPage variable to equal our newPage variable.

Next we'll look at the handler for our First Page, Prev, Next and Last Page buttons.

private function npHandler(e:MouseEvent):void{
    switch(e.target.label){
        case "Next >>":
            newPageBut++;
            newPage++;
            pageListener();
            break;
        case "<< Prev":
            newPageBut--;
            newPage--;
            pageListener();
            break;
        case "First":
            newPage = 1;
            firstPage = 1;
            newPageBut = 0;
            pageListener();
            break;
        case "Last":
            newPage = numPages;
            lastPage = numPages;
            newPageBut = (_numButtons - 1);
            pageListener();
            break;
    }
}

We are using a switch statement, with the criteria to compare, being the button's label property.

In the first case "Next >>" we know that the Next button has been clicked. We add a value of 1 to the newPageBut and the newPage variables using the short form ++, and we call the pageListener function. You'll recall the the pageListener function had it's MouseEvent parameter set to equal null. Here is where we get to use that feature. Because the function is not being called through a MouseEvent, if that parameter was not set to have a default value of null, we would not be able to call the pageListener function from here.

In the second case "<< Prev" we know that the prev button has been clicked and we want to do the same things except that instead of adding a value of 1 to our variables, we are subtracting 1.

In the third case "First" we know that the First Page button has been clicked. Now we want to reset our variables to reflect our first page, so we make newPage equal to 1, firstPage equal to 1, newPageBut equal to 0 - yes, 0, because here we are wanting it to be the first item in an array and arrays start counting at 0. Now we call our pageListener function again.

In the fourth case "Last", we know that the Last Page button has been clicked and we want to do the same things as in the First Page button, but we need to set our variables to reflect the last page. So, newPage equals numPages, lastPage equals numPages and newPageBut equals _numButtons minus 1. Again, remember that newPageBut is referencing an array.

Remember the statsArray we just packaged up? The next function we are going to look at makes use of that.

public function manualUpdate(pageSt:int, nPage:int, nPageBut:int, sItem:int, itemsTS:int, nBtn:Boolean, pBtn:Boolean, fBtn:Boolean, lBtn:Boolean):void{
    pageStart = pageSt;
    newPage = nPage;
    newPageBut = nPageBut;
    itemStart = sItem;
    _itemsToShow = itemsTS;
    nextBtn.enabled = nBtn;
    prevBtn.enabled = pBtn;
    firstBtn.enabled = fBtn;
    lastBtn.enabled = lBtn;
    buildPageButtons();
    butState();
} 

Back in our document class we have the public function reBuild(e:CustomEvent), which uses our CustomEvent to gather the information from the statsArray and then furthers that information to whichever of the two instances of the NextPrevPN class requires updating. The manualUpdate function is the receiver of that information. Notice that it is a public class. Using the access-control modifier "public" allows the function to be called from outside the NextPrevPn class. And here we see the true beauty of using classes. The instances of the NextPrevPN class we are using are called npT and npB, for top and bottom. Even though they are both products of the same class, they are essentially separate, so that when we call the function manualUpdate using the instance npB - npB.manualUpdate() - we are only updating the bottom instance's information, even though the same code is doing the work.

Back on track, we gather the incoming variables and transfer their information to our class variables and then call the buildPageButtons() function to update the visual information.

private function buildPageButtons():void{
    var j:uint = pageStart + 1;
    for(var i:uint = 0; i < _numButtons; i++){
        buttonArray[i].label = j;
        j++;
    }
    firstPage = parseInt(buttonArray[0].label);
    lastPage = parseInt(buttonArray[_numButtons - 1].label);
}

Here we simply rebuild the page buttons menu using the updated information we received in the manualUpdate function. Once the menu is done, we update our firstPage and lastPage variables to reflect the current first and last pages.

The last job we do in the manualUpdate function is call the butState() function to update the selected status of the page buttons.

private function butState():void{
    if(curPageBut != -1){
        if(curPageBut != newPageBut){
            buttonArray[curPageBut].selected = false;
            buttonArray[curPageBut].setStyle("textFormat", butFormat);
            buttonArray[newPageBut].selected = true;
            buttonArray[newPageBut].setStyle("textFormat", butDownFormat);
        }
    }else{
        buttonArray[newPageBut].selected = true;
        buttonArray[newPageBut].setStyle("textFormat", butDownFormat);
    }
    curPageBut = newPageBut;
}

The butState function looks after our selected toggle buttons. It uses the two variables curPageBut and newPageBut. You can probably guess what these variables are, but just for thoroughness I'll explain. The curPageBut holds the information of which button is currently selected. When a visitor clicks another button that becomes the newPageBut. So, in our butState function we first check to see that curPageBut is not equal to -1. If it were equal to -1 that would mean that there is currently no button selected, and therefore we would not want to deselect nothing. Now, if curPageBut does not equal -1, then we want to know whether or not curPageBut is equal to newPageBut. If curPageBut does not equal newPageBut then we can proceed to deselect the currently selected button by using the curPageBut as the index in the buttonArray and setting that button instance's selected property to false. Then we use the same technique to set the textFormat style of the currently selected button back to butFormat. Next we use the newPageBut as the index of the buttonArray and set that button instance's selected property to true and it's textFormat property to butDownFormat. If, on the other hand, it turns out the curPageBut and newPageBut are equal, then we do nothing. I am never quite sure why users click buttons that are already selected, but they do, so we must be prepared.

The else statement handles the situation where the curPageBut is equal to -1. In this example we initially set the value of curPageBut to 0 since we are showing the first page right from the get go, but there are other situations where you can use the butState function where none of the buttons are initially selected and then this will come in handy.

Lastly we set the curPageBut to equal the newPageBut so that we will know what to deselect the next time we visit the butState function.

And that's it for the NextPrevPN class.

As always, if you have any questions, don't be shy. Use the comment form below, or drop me a line./p>

Page 1 | Page 2

 

Get Adobe Flash player

Comments

No Comments


Warning: date() [function.date]: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/New_York' for 'EST/-5.0/no DST' instead in /home/xtydigi/public_html/footer.php on line 2