I’m working on my first plugin. It converts a standard select element into a stylized div. The code works just fine if I call a jQuery function that gathers all my $(".special_selctor") selects and does the logic, so I decided to pull that logic into a plugin so I could just directly call stylize on the select rather than iterating over all my special classes.
Here’s a snipped of the code from the NON-plugin ( $(this) is an instance of a select marked with my custom class):
var tmp = '';
tmp += '<div class="jm-select"' + (f_width ? ' style="width:' + (parseInt(f_width) + 7 + 32) + 'px;"' : '') + '>';
tmp += '<a ' + (f_width ? ' style="width:' + f_width + 'px;"' : '') + ' href="javascript:void(0)"><span class="display">' + display + '</span><span class="arrow"></span></a>';
tmp += '<div class="options"' + (f_width ? ' style="width:' + (parseInt(f_width) + 7) + 'px;"' : '') + '>';
$(this).children('option').each(function () {
tmp += '<div class="option"><span class="display">' + $(this).html() + '</span><span class="value">' + $(this).attr('value') + '</span></div>';
});
tmp += '</div>';
tmp += '</div>';
$(this).after(tmp);
$(this).hide();
We create the special div then hide the select
My plugin code (note: It’s in CoffeeScript):
if this.attr('data-width')
f_width = this.attr('data-width')
tmp = ''
tmp += '<div class="jm-select"' + (if f_width then ' style="width:' + (parseInt(f_width) + 7 + 32) + 'px;"' else '') + '>'
tmp += ' <a ' + (if f_width then ' style = "width:' + parseInt(f_width) + 'px;" ' else ' ') + ' href = "javascript:void(0)" > <span class="display" > ' + display + ' </span><span class="arrow"></span > </a>'
tmp += '<div class="options"' + (if f_width then ' style="width:' + (parseInt(f_width) + 7) + 'px;"' else '') + '>'
this.children('option').each () ->
tmp += '<div class="option"><span class="display">' + $(this).html() + '</span><span class="value">' + $(this).attr('value') + '</span></div>'
tmp += '</div>'
tmp += '</div>'
this.after(tmp)
this.hide()
the this.hide() hides both the select and the newly created div (this is now an array). If I call this.hide() before this.after(tmp), it works fine.
Why is this.hide() iterating over the new this “array” instead of just the this select object?
Full plugin code converted from CoffeeScript
var $;
$ = jQuery;
$.fn.jmselect = function() {
var display, f_width, name, tmp, value;
name = this.attr('name');
value = this.val();
display = this.children("option:selected").text();
if (this.attr('data-width')) {
f_width = this.attr('data-width');
}
tmp = '';
tmp += '<div class="jm-select"' + (f_width ? ' style="width:' + (parseInt(f_width) + 7 + 32) + 'px;"' : '') + '>';
tmp += ' <a ' + (f_width ? ' style = "width:' + parseInt(f_width) + 'px;" ' : ' ') + ' href = "javascript:void(0)" > <span class="display" > ' + display + ' </span><span class="arrow"></span > </a>';
tmp += '<div class="options"' + (f_width ? ' style="width:' + (parseInt(f_width) + 7) + 'px;"' : '') + '>';
this.children('option').each(function() {
return tmp += '<div class="option"><span class="display">' + $(this).html() + '</span><span class="value">' + $(this).attr('value') + '</span></div>';
});
tmp += '</div>';
tmp += '</div>';
this.hide();
this.after(tmp);
this.children("a").click(function(event) {
event.stopPropagation();
$('.jm-select').addClass('inactiveSelect');
$(this).parent('.jm-select').removeClass('inactiveSelect');
$('.inactiveSelect').children('.options').hide();
return $(this).parent('.jm-select').children('.options').toggle();
});
this.find(".options .option").click(function() {
var tmp2;
tmp = $(this).children('span.value').html();
tmp2 = $(this).children('span.display').html();
$(this).parent('.options').parent('.jm-select').prev('select').val(tmp).trigger('change');
$(this).parent('.options').parent('.jm-select').children('a').children('.display').html(tmp2);
return $('.jm-select').children('.options').hide();
});
return this;
};
I think you need to wrap your plugin behavior in a
.eachloop: