Search code examples
javascriptasp.netuser-controlsobject-literal

object literal handling multiple instances


My entire JavaScript library is constructed in an object literal namespace. It contains each page's logic from init() to common functions, controls, validation, etc. The page's init() function gets fired based on the page's body id.

The problem I have is in my controls section. I have an object literal named AddressEntry. This object literal contains the functionality that deals with my AddressEntry ASP.NET UserControl. It works just fine with one AddressEntry control on the page, but when there's more than one, only the last one on the page works as intended.

Here's my AddressEntry object literal (trimmed down to pertinent information):

SFAIC.ctrls.AddressEntry = {

    inputs : {

        city        : undefined,
        cityState   : undefined,

        hidden : {

            city    : undefined,
            state   : undefined

        },  

    },

    fn : {

        root : undefined,

        citySelected : function($ddl) {

            var $selected = $ddl.find(":selected");

            this.root.inputs.hidden.city.val($selected.val());          
            this.root.inputs.hidden.state.val($selected.text().split(", ")[1]);

        }

    },

    init : function(addressId) { 

        var self    = this,
            fn      = self.fn,
            inputs  = self.inputs,
            hidden  = inputs.hidden;

            inputs.city         = SFAIC.fn.getContentElement(addressId + "_ddlCity",                SFAIC.$updatePanel);
            inputs.cityState    = SFAIC.fn.getContentElement(addressId + "_ddlCityStateLocked",     SFAIC.$updatePanel);
            hidden.city         = SFAIC.fn.getContentElement(addressId + "_txtCity",                SFAIC.$updatePanel);
            hidden.state        = SFAIC.fn.getContentElement(addressId + "_txtState",               SFAIC.$updatePanel);

            fn.root = this;

        inputs.city.change(function() { fn.citySelected($(this)); });
        inputs.cityState.change(function() { fn.citySelected($(this)); });

    }

};

Then, the page object literal would look something like this (again, trimmed down):

SFAIC.pages.salesProcess.Applicant = {

    init : function() {         

        SFAIC.ctrls.AddressEntry.init("AddressGarage");
        SFAIC.ctrls.AddressEntry.init("AddressMailing");

    }

};

It's obvious to me that AddressMailing init overrides the AddressGarage init. What can I do to objectify the SFAIC.ctrls.AddressEntry object literal to be able to handle as many AddressEntry UserControls that I may have on the page without them overriding each other?


Solution

  • Here's the solution I came up with:

    SFAIC.ctrls.AddressEntry = function(addressId) {
    
        var ctrl = {
    
                inputs : {
    
                    city        : undefined,
                    cityState   : undefined,
    
                    hidden : {
    
                        city    : undefined,
                        state   : undefined
    
                    },  
    
                },
    
                fn : {
    
                    root : undefined,
    
                    citySelected : function($ddl) {
    
                        var $selected = $ddl.find(":selected");
    
                        this.root.inputs.hidden.city.val($selected.val());          
                        this.root.inputs.hidden.state.val($selected.text().split(", ")[1]);
    
                    }
    
                },
    
                init : function(addressId) { 
    
                    var self    = this,
                        fn      = self.fn,
                        inputs  = self.inputs,
                        hidden  = inputs.hidden;
    
                        inputs.city         = SFAIC.fn.getContentElement(addressId + "_ddlCity",                SFAIC.$updatePanel);
                        inputs.cityState    = SFAIC.fn.getContentElement(addressId + "_ddlCityStateLocked",     SFAIC.$updatePanel);
                        hidden.city         = SFAIC.fn.getContentElement(addressId + "_txtCity",                SFAIC.$updatePanel);
                        hidden.state        = SFAIC.fn.getContentElement(addressId + "_txtState",               SFAIC.$updatePanel);
    
                        fn.root = this;
    
                    inputs.city.change(function() { fn.citySelected($(this)); });
                    inputs.cityState.change(function() { fn.citySelected($(this)); });
    
                }
    
        };
    
        ctrl.init();
    
        return ctrl;    
    
    };          
    
    SFAIC.pages.salesProcess.Applicant = {
    
        init : function() {         
    
            var garage, mailing;
    
            garage = SFAIC.ctrls.AddressEntry("AddressGarage");
            mailing = SFAIC.ctrls.AddressEntry("AddressMailing");
    
        }
    
    };