Friday, September 16, 2011

ExplodeBox

I wrote an "ExplodeBox". It's a select list that contains all the data from multiple text inputs. So say you wanted to make a list of your computers and their properties. This is for exactly that scenario. You input the computer's information into the text inputs, hit "add", and it is all stored away in one of the select's <option> objects.

To use ExplodeBox, you name all your elements using a baseId. So for instance, one of your text inputs might be named "ebtest_ipAddress", with "ebtest_" being an example common prefix for all the form fields you want associated with the ExplodeBox. You can name the text inputs anything you wish, as long as you use the prefix. For the select box, the add button, and the remove button, they have to have specific names. The select box must be named "ebtest_box", the add button "ebtest_add", and the remove button "ebtest_remove" (with "ebtest" standing for whatever your prefixId is).

Clear as mud? Without further ado, here's the code:
            /*
             * ExplodeBox!
             * 
             * Have a select list that breaks out data into sub-fields for editing.
             */
            var ExplodeBox = function(baseId, parts) {
                this.baseId = baseId;
                this.boxId = 'select#'+ baseId +'_box';
                this.addId = 'input#'+ baseId +'_add';
                this.removeId = 'input#'+ baseId +'_remove';
                this.cancelId = 'input#'+ baseId +'_cancel';
                
                this.partIds = [];
                for (var i = 0; i < parts.length; i++) {
                    this.partIds.push('#'+ this.baseId +'_'+ parts[i]);
                }
                               
                var box = this;
                $(this.addId).click(function() {
                    box.addEditItem();
                });
                $(this.boxId).change(function() {
                    box.showItem();                
                });
                $(this.removeId).click(function() {
                    box.removeItem();
                });
                $(this.cancelId).click(function() {
                    box.cancelEdit(); 
                });
            }
            
            ExplodeBox.itemIndex = 0;
            ExplodeBox.prototype.addEditItem = function() {
                var box = $(this.boxId);
                var addMode = ($(this.addId).val() == 'add');
                            
                var opt = null;
                if (addMode) {
                    box.append('');
                    ExplodeBox.itemIndex++;
                    
                    opt = $(this.boxId +' option:last');
                }
                else {
                    opt = $(this.boxId +' option:selected');
                    opt.text($(this.partIds[0]).val());
                    $(this.cancelId).hide();
                }
                
                for (var i = 0; i < this.partIds.length; i++) {
                    opt.data(this.partIds[i], $(this.partIds[i]).val());
                }
                                
                if (addMode)
                {
                    for (var j = 0; j < this.partIds.length; j++) {
                        $(this.partIds[j]).val('');
                    }
                }
            }
            
            ExplodeBox.prototype.cancelEdit = function() {
                $(this.boxId).val('');
                $(this.addId).val('add');
                $(this.cancelId).hide();
                
                for (var j = 0; j < this.partIds.length; j++) {
                    $(this.partIds[j]).val('');
                }                               
            }
            
            ExplodeBox.prototype.showItem = function() {
                var opt = $(this.boxId +' option:selected');
                                        
                for (var i = 0; i < this.partIds.length; i++) {
                    $(this.partIds[i]).val(opt.data(this.partIds[i]));
                }  
                 
                if (opt.length == 0) {
                    $(this.addId).val('add');
                    $(this.cancelId).hide();
                }
                else {
                    $(this.addId).val('save');
                    $(this.cancelId).show();
                }
            }
            
            ExplodeBox.prototype.removeItem = function() {
                $(this.boxId +' option:selected').detach();
                
                for (var j = 0; j < this.partIds.length; j++) {
                    $(this.partIds[j]).val('');
                }
            }
            /* End ExplodeBox */
           
           Page.explodeBox = new ExplodeBox('ebtest', ['hostname', 'ipAddress', 'purchasedDate', 'description']);