tags:

views:

56

answers:

1

So, this is my first jquery plugin. It's not quite finished, but I'm running into an issue.

The general purpose of the function is to take a select box and hide it while making a better looking one that's made up of divs and such. For example, you might have:

<select class="beautify" id="items" name="select2" >
    <option value="opt1">Select A Brand</option>
    <option value="opt2">Option 2</option>
    <option value="opt3">Option 3</option>
    <option value="opt4">Option 4</option>
    <option value="opt5">Option 5</option>
    <option value="opt6">Option 6</option>
    <option value="opt7">Option 7</option>
    <option value="opt8">Option 8</option>
</select>

Then later you could call:

$('select.beautify').beautify();

So I have most of the animations working and such. I'm trying to figure out how to store the values of each option to their respective anchors. The data() function isn't quite working. I need to store each option's value into an anchor and when the anchor is clicked, then change the select's value to that one.

Here's the plugin:

    (function($){
    $.fn.beautify = function() {

        var defaults = {
            suffix: 'beautify'
        };
        var options = $.extend(defaults, options);

        return this.each(function() {
            $(this).hide();
            var selectbox = $(this);
            var suffix = options.suffix;
            var id = $(this).attr('id');
            var mainElement = '';
            var headElement = id + 'head' + suffix;
            var choicesElement = id + 'choices' + suffix;

            // Build up the main element container
            mainElement += '<div id="';
            mainElement += id + suffix;
            mainElement += '">';
            mainElement += '</div';
            $(this).before(mainElement);

            // Add the head and choices sections
            $('#' + id + suffix).append('<div id="' + headElement + '"></div>');
            $('#' + id + suffix).append('<div id="' + choicesElement + '"></div>');

            // Take care of some styling
            $('#' + id + suffix).addClass('selectouter');
            $('#' + headElement).addClass('');
            $('#' + choicesElement).addClass('selectchoices');

            // Get the choices from the input dropdown
            $('#' + headElement).append($(this).children(':first').text());
            $(this).find('option').each(function(){
                $('#' + choicesElement).append('<a href="#">'+$(this).text()+'</a>');
                $('#' + choicesElement).slideDown();
                $('#' + choicesElement + ':last-child').data('testvar', $(this).val());
            });

            // Handle animations
            $('#' + choicesElement).hide();
            $('#' + headElement).click(function(){
                $('#' + choicesElement).slideToggle();
            });
            $('#' + id + suffix).mouseleave(function(){
                $('#' + choicesElement).slideUp();
            });

            // A new option has been clicked
            $('#' + choicesElement + ' a').click(function(event){
                event.preventDefault();
                $('#' + choicesElement).slideToggle();
                $('#' + headElement).html($(this).text());

                // Up to now, it's all for looks, actually switch the select value here:
                alert($(this).data('testvar'));
            });

        });  
    };  
})(jQuery);

Even though this plugin isn't quite finished, I'd appreciate critique also.

+2  A: 

Here is your code revised the way I would write it. It will be much more performant this way. The only question I have is what you are trying to alert at the end. You are storing the data for each option, then alerting data for the entire box (which does not exist). Here is what I think you were getting at.

    (function ($) {
        $.fn.beautify = function () {

            var defaults = {
                suffix: 'beautify'
            };
            var options = $.extend(defaults, options);

            return this.each(function () {
                var selectbox = $(this).hide(),
                       suffix = options.suffix,
                       id = selectbox.attr('id'),
                       mainElement,
                       headElement = $('<div />', {id:  id + 'head' + suffix}),
                       choicesElement = $('<div />', {id: id + 'choices' + suffix});

                // Build up the main element container
               mainElement = $('<div />', {
                   id: id + suffix
               });
               selectbox.before(mainElement);

                // Add the head and choices sections
                mainElement
                    .addClass('selectouter')
                    .append(headElement)
                    .append(choicesElement);

                // Get the choices from the input dropdown
               headElement
                    .addClass('')
                    .append(selectbox.children(':first').text());

                selectbox.find('option').each(function () {
                var link = $('<a />', {
                    href: "#",
                    text:  $(this).text()
                }).data('testvar', $(this).val());

                    choicesElement.append(link)
                        .slideDown();
                });

                // Handle animations
                choicesElement.addClass('selectchoices').hide();

                headElement.click(function () {
                    choicesElement.slideToggle();
                });

                mainElement.mouseleave(function () {
                    choicesElement.slideUp();
                });

                // A new option has been clicked
                choicesElement.click(function (event) {
                    event.preventDefault();
                    choicesElement.slideToggle();
                   headElement.html(selectbox.text());

                    // Up to now, it's all for looks, actually switch the select value here:
                    alert($(event.target).data('testvar'));
                });
            });
        };
    })(jQuery);
Zacho