app/assets/javascripts/plugins/jquery.populate.js

Summary

Maintainability
F
3 days
Test Coverage

jQuery.fn.populate = function(obj, options) {
    
    
    // ------------------------------------------------------------------------------------------
    // JSON conversion function
    
        // convert 
            function parseJSON(obj, path)
            {
                // prepare
                    path = path || '';
                
                // iteration (objects / arrays)
                    if(obj == undefined)
                    {
                        // do nothing
                    }
                    else if(obj.constructor == Object)
                    {
                        for(var prop in obj)
                        {
                            var name    = path + (path == '' ? prop : '[' +prop+ ']');
                            parseJSON(obj[prop], name);
                        }
                    }
                        
                    else if(obj.constructor == Array)
                    {
                        for(var i = 0; i < obj.length; i++)
                        {
                            var index    = options.useIndices ? i : '';
                            index        = options.phpNaming ? '[' +index+']' : index;
                            var name    = path + index;
                            parseJSON(obj[i], name);
                        }
                    }
                    
                // assignment (values)
                    else
                    {
                        // if the element name hasn't yet been defined, create it as a single value
                        if(arr[path] == undefined)
                        {
                            arr[path] = obj;
                        }
        
                        // if the element name HAS been defined, but it's a single value, convert to an array and add the new value
                        else if(arr[path].constructor != Array)
                        {
                            arr[path] = [arr[path], obj];
                        }
                            
                        // if the element name HAS been defined, and is already an array, push the single value on the end of the stack
                        else
                        {
                            arr[path].push(obj);
                        }
                    }
    
            };


    // ------------------------------------------------------------------------------------------
    // population functions
        
        function debug(str)
        {
            if(window.console && console.log)
            {
                console.log(str);
            }
        }
        
        function getElementName(name)
        {
            if (!options.phpNaming)
            {
                name = name.replace(/\[\]$/,'');
            }
            return name;
        }
        
        function populateElement(parentElement, name, value)
        {
            var selector    = options.identifier == 'id' ? '#' + name : '[' +options.identifier+ '="' +name+ '"]';
            var element        = jQuery(selector, parentElement);
            value            = value.toString();
            value            = value == 'null' ? '' : value;
            element.html(value);
        }
        
        function populateFormElement(form, name, value)
        {

            // check that the named element exists in the form
                var name    = getElementName(name); // handle non-php naming
                var element    = form[name];
                
            // if the form element doesn't exist, check if there is a tag with that id
                if(element == undefined)
                {
                    // look for the element
                        element = jQuery('#' + name, form);
                        if(element)
                        {
                            element.html(value);
                            return true;
                        }
                    
                    // nope, so exit
                        if(options.debug)
                        {
                            debug('No such element as ' + name);
                        }
                        return false;
                }
                    
            // debug options                
                if(options.debug)
                {
                    _populate.elements.push(element);
                }
                
            // now, place any single elements in an array.
            // this is so that the next bit of code (a loop) can treat them the 
            // same as any array-elements passed, ie radiobutton or checkox arrays,
            // and the code will just work

                elements = element.type == undefined && element.length ? element : [element];
                
                
            // populate the element correctly
            
                for(var e = 0; e < elements.length; e++)
                {
                    
                // grab the element
                    var element = elements[e];
                    
                // skip undefined elements or function objects (IE only)
                    if(!element || typeof element == 'undefined' || typeof element == 'function')
                    {
                        continue;
                    }
                    
                // anything else, process
                    switch(element.type || element.tagName)
                    {
    
                        case 'radio':
                            // use the single value to check the radio button
                            element.checked = (element.value != '' && value.toString() == element.value);
                            
                        case 'checkbox':
                            // depends on the value.
                            // if it's an array, perform a sub loop
                            // if it's a value, just do the check
                            
                            var values = value.constructor == Array ? value : [value];
                            for(var j = 0; j < values.length; j++)
                            {
                                element.checked |= element.value == values[j];
                            }
                            
                            //element.checked = (element.value != '' && value.toString().toLowerCase() == element.value.toLowerCase());
                            break;
                            
                        case 'select-multiple':
                            var values = value.constructor == Array ? value : [value];
                            for(var i = 0; i < element.options.length; i++)
                            {
                                for(var j = 0; j < values.length; j++)
                                {
                                    element.options[i].selected |= element.options[i].value == values[j];
                                }
                            }
                            break;
                        
                        case 'select':
                        case 'select-one':
                            element.value = value.toString() || value;
                            break;
    
                        case 'text':
                        case 'button':
                        case 'textarea':
                        case 'submit':
                        default:
                            value            = value == null ? '' : value;
                            element.value    = value;
                            
                    }
                        
                }

        }
        

        
    // ------------------------------------------------------------------------------------------
    // options & setup
        
        // exit if no data object supplied
            if (obj === undefined)
            {
                return this;
            };
        
        // options
            var options = jQuery.extend
            (
                {
                    phpNaming:            true,
                    phpIndices:            false,
                    resetForm:            true,
                    identifier:            'id',
                    debug:                false
                },
                options
            );
                
            if(options.phpIndices)
            {
                options.phpNaming = true;
            }
    
    // ------------------------------------------------------------------------------------------
    // convert hierarchical JSON to flat array
        
            var arr    = [];
            parseJSON(obj);
            
            if(options.debug)
            {
                _populate =
                {
                    arr:        arr,
                    obj:        obj,
                    elements:    []
                }
            }
    
    // ------------------------------------------------------------------------------------------
    // main process function
        
        this.each
        (
            function()
            {
                
                // variables
                    var tagName    = this.tagName.toLowerCase();
                    var method    = tagName == 'form' ? populateFormElement : populateElement;
                    
                // reset form?
                    if(tagName == 'form' && options.resetForm)
                    {
                        this.reset();
                    }

                // update elements
                    for(var i in arr)
                    {
                        method(this, i, arr[i]);
                    }
            }
            
        );

return this;
};