My first jQuery plugin — Heftybox

I’m getting started with my first official jQuery plugin, and I’m just turning now looking for input. I want to know what I’m doing wrong or right so far and if everything is being developed in a manner that won’t cause issue down the road. With no further adieu:

$.fn.heftyBox = function(args) {
   
if ($(this).length) {
   
//Set up defaults
   
var a    =  $.extend({
        type  
:  "checkbox",
        width  
:  "auto",
        height
:  ($(this).innerHeight() > 150) ? $(this).innerHeight() : 150
   
}, args);

   
//Gather original attributes, convert DOM, then reassgign attributes
   
var attributes = $(this)[0].attributes;
   
var optionsHTML = $(this).html();
    $
(this).after('<ul id="tmpul">' + optionsHTML + '</ul>');
    $
(this).remove();
   
var ul = $('#tmpul')[0];
   
for (var i = 0; i < attributes.length; i++) {
        $
(ul).attr(attributes[i].name, attributes[i].value);
   
}


   
//Convert options to checkbox or radios
   
var options = $(ul).children('option');
   
var name = $(ul).attr('name');
    $
(ul).removeAttr('name');
   
var f = 0;
    $
.each(options, function(key, option) {
       
var itemAttributes = $(this)[0].attributes;
       
var value = $(this).attr('value');
       
var label = $(this).text();
       
var selected = $(this).attr('selected') ? "checked" : ''
        selected
+= $(this).attr('disabled') ? " disabled" : ''
       
var newLi;
        $
(this).replaceWith(newLi = $('<li ' + selected + '><input type="' + a.type + '" id="option_' + name + '_' + f + '" name="' + name + '" value="' + value + '" ' + selected + '/><label for="option_' + name + '_' + f + '">' + label + '</label></li>') )
       
for (var i = 0; i < itemAttributes.length; i++) {
            $
(newLi).children('input').attr(itemAttributes[i].name, itemAttributes[i].value);
       
}
        f
++;
   
})

   
//Add Filter Box
    $
(ul).before('<input id="' + name + '_filter" class="list_filter" />');
   
var list = $(ul).children('li');
   
var filter = $('#' + name + '_filter');
    filterBox
($(filter), list);

   
//Contain it all
    $
(filter).before('<div class="heftyBox" id="' + name + '_container"></div>');
   
var container = $('#' + name + '_container');
    $
(filter).appendTo($(container));
    $
(ul).appendTo($(container));

   
//Select all box for checkboxes
   
if (a.type == "checkbox") {
        $
(filter).after($('<a href="#">Select All</a>').bind('click', function() {
           
var checkboxes = $(this).next('ul').find('input:not([disabled])');
           
if ($(checkboxes).length > $(checkboxes + ':checked').length) {
                $
(checkboxes).attr('checked', 'checked').closest('li').attr('checked', 'checked');
           
} else {
                $
(checkboxes).removeAttr('checked', 'checked').closest('li').removeAttr('checked');
           
}
           
($(this).text() == "Select All") ? $(this).text("Select None") : $(this).text("Select All")
            $
(this).next('ul').trigger('change')
           
return false;
       
}))
   
}

   
//Write the Data to the DOM
    $
(ul).data({
        heftyBox
: a
   
})

   
//Apply DOM data
    updateheftyBox
($(ul));

   
//Handle Value Change
    $
(this).bind('change', function() {updateheftyBox($(this));})
   
}

   
//scroll to first selected DOM
   
if ($(ul).find('li[checked]:first').length) {
       
var itemTop = $(ul).find('li[checked]:first').offset().top || $(ul).offset().top;
       
var ulTop = $(ul).offset().top;
        $
(ul).scrollTop(itemTop - ulTop);
   
}
}

updateheftyBox
= function(target) {
   
var a = $(target).data().heftyBox;
   
var container = $(target).parent('.heftyBox');
   
var filter = $(target).siblings('.list_filter');
   
var ul = $(target);

   
//Gather created data
    a
.value = [];
    $
(ul).find('input:checked').each(function() {
        a
.value.push($(this).val())
   
})

    $
(container).css({
        width
: a.width,
        height
: a.height,
       
"min-width": $(filter).outerWidth()
   
});
    $
(ul).css({
        height
: a.height - $(filter).outerHeight(),
       
"margin-top": $(filter).outerHeight()
   
})
    $
(ul).val(a.value);
}


filterBox
= function(target, blocks) {
    $
(target).unbind('keyup change');
    $
(target).bind('keyup change', function() {
       
var inText = $(this).val().trim(); //remove trailing whitespace

        $
.each(blocks, function() {
           
var title = $(this).children('label').text(); //the title in the block
           
if (matchAll(title, inText)) {
                $
(this).show();
           
} else {
                $
(this).hide();
           
}
       
})

   
})
}

matchAll
= function(string, args) { //string= string to match, args= search input
   
var die = 0; //return switch
   
var checks = args.split(' '); //break input into array
    $
.each(checks, function() {
       
var myReg = new RegExp(this, 'i'); //search term to regex
       
if (!string.match(myReg)) { //if it doesn't match, kill the function
           
die = 1;
       
}
   
})

   
if (die == 1) {
       
return false;
   
} else {
       
return true;
   
}
}

$
('.heftyBox li:has(input:checkbox)').live('click', function() {
   
($(this).has(':checked').length) ? $(this).attr('checked', 'checked') : $(this).removeAttr('checked')
})

The concepts of thus plugin:

  • The HeftyBox should be dynamic and not affect any attributes or user input that coould be collected by the original Select box
  • The HeftyBox should accept many options to match styling and uniqueness of the application it is being used for
  • The HeftyBox should be able to be modified and customized with calls to the object after it is initiated
  • The HefyBox should be easy to implement, attractive, and functional with defualt setting

Source github/kmacey1249/heftybox

Implemented like so:

Initial HTML

<select name="test" id="test" multiple="multiple" bar="baz">
 
<option value="1">One</option>
 
<option value="2">Two</option>
 
<option value="3" foo="bar">Three</option>
</select>

jQuery Call

$('#test').heftyBox(); //{type: "checkbox"/"radio", width: "auto", height: 150}

Result:

<div class="heftyBox" id="test_container" style="width: auto; height: 178px; min-width: 155px; ">
 
<input id="test_filter" class="list_filter" />
 
<a href="#">Select All</a>
 
<ul id="test" multiple="multiple" bar="baz" style="height: 155px; margin-top: 23px; ">
   
<li>
     
<input type="checkbox" id="option_test_0" name="test" value="1">
     
<label for="option_test_0">One</label>
   
</li>
   
<li>
     
<input type="checkbox" id="option_test_1" name="test" value="2">
     
<label for="option_test_1">Two</label>
   
</li>
   
<li>
     
<input type="checkbox" id="option_test_2" name="test" value="3" foo="bar">
     
<label for="option_test_2">Three</label>
   
</li>          
 
</ul>
</div>
Source: codereview.stackexchange.com