views:

40

answers:

1

I have the following code, which is written for the Titanium framework for mobile application development. The problem that I am having is that the loadPage() method is not calling the other methods. What am I missing here?

Titanium.UI.currentWindow.barColor = Titanium.UI.currentWindow.barColor;
Titanium.UI.currentWindow.title = 'My Media';


function Media()
{

this.properties = {
    currentPage : 1,
    url : 'http://localhost/past?return=json&count=20&page=',
    rowColor: '#fff',
    rowSelectedColor: '#6BBBFA',
    filter: 'filter'
};

this.table = false;
this.wrapper = false;
this.products = false;

/*
    Allow the user to search through all of their media
*/
this.showSearch = function()
{
    var search = Titanium.UI.createSearchBar({
        barColor: Titanium.UI.currentWindow.barColor, 
        showCancel: false
    });

    search.addEventListener('change', function(e)
    {
       e.value; // search string as user types
    });

    search.addEventListener('return', function(e)
    {
       search.blur();
    });

    search.addEventListener('cancel', function(e)
    {
       search.blur();
    });

    return search;
};


/*
    Create a row in the table.  This will actually
    append the row to a pre-existing table
*/
this.createRow = function(product)
{
    var row = Ti.UI.createTableViewRow();

    var image = Ti.UI.createImageView({
        image: product.image,
        top: 5,
        left: 5,
        width:100,
        height:70,
        canScale: true
    });

    var video = Ti.UI.createLabel({
        color: '#000',
        font: {
            fontSize: 14,
            fontWeight: 'bold', 
            fontFamily: 'Arial'
        },
        left: 110,
        top: 2,
        height: 20,
        width: 170,
        clickName: 'video',
        text: product.name
    });

    var date = Ti.UI.createLabel({
        color: '#999',
        font: {
            fontSize: 13,
            fontWeight: 'normal', 
            fontFamily: 'Arial'
        },
        left: 110,
        top: 22,
        height: 20,
        width: 100,
        clickName: 'date',
        text: product.date
    });

    row.height = 80;
    row.className = 'mediaItem';
    row.selectedBackgroundColor = this.properties.rowSelectedColor;
    row.hasDetail = true;
    row.filter = video.text;

    row.add(image);
    row.add(video);
    row.add(date);

    // Add the row to the table
    this.addRowToTable(row);
};


/*
    Add the products to the table view
*/
this.addRows = function()
{
    var item;
    for(item in this.products)
    {
        if(item)
        {
            this.createRow(this.products[item]);
        }
    }

    this.showMoreButton();
};


/*
    If we do not already have a table, let's go ahead and build one now
*/
this.buildTable = function()
{
    if(!this.table)
    {
        // Build out the table
        this.table = Titanium.UI.createTableView({
            search: this.showSearch(),
            filterAttribute: this.properties.filter,
            backgroundColor: '#ffffff'
        });

        this.wrapperView = Titanium.UI.createView({
            backgroundColor: 'transparent'
        });

        this.wrapperView.add(this.table);
        Titanium.UI.currentWindow.add(this.wrapperView);
    }
};


/*
    Append a row to the table (if the table exists)
*/
this.addRowToTable = function(row)
{
    if(this.table)
    {
        this.table.appendRow(row);
    }
};


/*
    Allow the user to choose to show more videos
*/
this.showMoreButton = function()
{
    var row = Ti.UI.createTableViewRow();
    row.backgroundColor = '#6BBBFA';
    row.selectedBackgroundColor = '#666';

    // add custom property to identify this row
    row.isUpdateRow = true;

    var rowText = Ti.UI.createLabel({
        color: '#fff',
        font: {
            fontSize:16, 
            fontWeight:'bold'
        },
        text: 'Show More Videos',
        width: 'auto',
        height: 'auto'
    });
    row.className = 'updated_row';
    row.add(rowText);

    row.addEventListener('click', function(e){
        this.loadPage();
    });

    // Add the row to the table
    this.addRowToTable(row);
};


/*
    We don't want to load the same page 
    multiple times, so increment the page each time
*/
this.incrementPage = function()
{
    this.properties.currentPage = this.properties.currentPage + 1;
};


/*
    Let's go ahead and load a URL and parse it as JSON
    This method will automatically paginate
*/
this.loadPage = function()
{
    xhr = Titanium.Network.createHTTPClient();
    xhr.open('GET', this.properties.url + this.properties.currentPage);

    xhr.onload = function()
    {
        // Set the response
        var response = JSON.parse(xhr.responseText);
        this.products = response.products;

        // Build the table.  This method will only build it if it doesn't yet exist
        this.buildTable();

        // Add rows to the table
        this.addRows();

        // Go ahead and increment the page that we are on
        this.incrementPage();
    };


    xhr.onerror = function(e)
    {
        // If there has been an error, let the user know about it
        var a = Titanium.UI.createAlertDialog({
            title:'Error',
            message: 'There was an error with the request.  Please try again later'
        });

        a.show();
    };

    xhr.send();
};

};

var media = new Media();
media.loadPage();
+2  A: 

you have a scope issue. when you get to this point

xhr.onload = function() 
{ 
    // Set the response 
    var response = JSON.parse(xhr.responseText); 
    this.products = response.products; 

    // Build the table.  This method will only build it if it doesn't yet exist 
    this.buildTable(); 

    // Add rows to the table 
    this.addRows(); 

    // Go ahead and increment the page that we are on 
    this.incrementPage(); 
}; 

the name this refers to xhr rather than the Media object. this is commonly addressed by creating a new variable at the top of the Media constructor which points to itself, like

function Media()     
{     
     var self = this;

you would then use the self name to refer to the Media object from within xhr.onload.

xhr.onload = function() 
{ 
    // Set the response 
    var response = JSON.parse(xhr.responseText); 
    self.products = response.products; 

    // Build the table.  This method will only build it if it doesn't yet exist 
    self.buildTable(); 

    ...
lincolnk
Awesome! Thank you very much!
Brandon Hansen