\$\begingroup\$
\$\endgroup\$
5
I am new to JavaScript, HTML and CSS, although not to programming.
I wanted to style 'select' dropdowns, so I wrote this:
What noob mistakes am I making? Is this a good or evil use of JS?
<head>
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<!--
<link href="./font-awesome-4.0.3/css/font-awesome.css" rel="stylesheet">
-->
<style>
body { font-family: sans-serif; }
.control { display: none; }
.dropdown > dl { margin: 4px; font-family: sans-serif; }
.dropdown > dl > dt { display:inline-block; width: auto; }
.dropdown .value { display: none; }
.dropdown > dl > dd { position: absolute; left: 0; top: 27px; display: none; }
.dropdown > dl { display:inline-block; width: auto; position: relative; cursor: pointer; }
.dropdown > dl > dt { border: 1px solid #ddd; background-color: #eee; color: black; padding: 3px 6px; font-weight: bold; }
.dropdown > dl > dd { border: 1px solid #ddd; background-color: white; margin:0;}
.dropdown > dl > dd > ul { padding:0; margin:0 }
.dropdown > dl > dd > ul > li { list-style: none; padding:5px 10px; padding-left: 28px; }
.dropdown > dl > dt:hover,
.dropdown > dl > dd > ul > li:hover { background-color: #333; color: white; }
.dropdown > dl > dd > ul > li { display: none; }
.dropdown li.selected:before { font-family: 'FontAwesome'; content: '\f00c'; margin: 0 5px 0 -22px; font-weight: normal; }
.dropdown li.selected { font-weight: bold; }
</style>
<script src="http://code.jquery.com/jquery-2.0.3.js"></script>
<!--
<script src="jquery-2.0.3.js"></script>
-->
<script>
function Dropdown(name) {
this.name = name;
this.$root = $('#dropdown').clone().removeAttr('id').show();
this.$root.children('dl').css('z-index', Dropdown.zindex.next());
Controls.registerControl(this);
this.$selected = this.$root.find('dt');
this.$selectedContents = {
$text: this.$selected.children('span.text'),
$value: this.$selected.children('span.value') };
this.$popup = this.$root.find('dd');
this.$options = this.$popup.children('ul');
this.$option = this.$options.children('li');
this.$optionContents = {
$text: this.$option.children('span.text'),
$value: this.$option.children('span.value') };
var that = this;
this.$selected.click(function(event) {
if (!that.$popup.is(':visible')) {
Controls.blurAll();
}
that.$popup.toggle();
});
this.$options.click(function(event) {
that._selectOption($(event.target).is('li') ? $(event.target) : $(event.target).parent('li'));
that.$popup.hide();
});
}
Dropdown.prototype = {
constructor: Dropdown,
_makeOption: function(text, value) {
this.$optionContents.$text.text(text);
this.$optionContents.$value.text(value);
return this.$option.clone();
},
setOptions: function(optionsMap) {
for (var value in optionsMap) {
var text = optionsMap[value];
this._makeOption(text, value).appendTo(this.$options).show();
}
return this;
},
_selectOption: function($option) {
var text = $option.children('span.text').text();
var value = $option.children('span.value').text();
this.$selectedContents.$text.text(text);
this.$selectedContents.$value.text(value);
this.$options.children('.selected').removeClass('selected');
$option.addClass('selected');
this.$root.closest('form').find('[name="'+this.name+'"]').val(value);
},
selectOption: function(value) {
var that = this;
this.$options.find('li').each(function (idx, li) {
if ($(li).find('span.value').text() == value) {
that._selectOption($(li));
}
});
return this;
},
blur: function() {
this.$popup.hide();
}
};
Dropdown.replaceSelect = function($select) {
var options = {};
$select.children('option').each(function (idx, el) {
options[$(el).val()] = $(el).text();
});
$select.hide().before(
new Dropdown($select.prop('name'))
.setOptions(options)
.selectOption($select.children('option:selected').val())
.$root);
};
Dropdown.replaceSelectByName = function(name) {
Dropdown.replaceSelect($('select[name="' + name + '"]'));
};
Dropdown.replaceAllSelects = function() {
$('select').each(function (idx, el) {
Dropdown.replaceSelect($(el));
});
};
Dropdown.zindex = {
_idx: 100,
next: function() { return this._idx--; }
};
Controls = {
_controls: [],
registerControl: function (control) {
this._controls.push(control);
},
blurAll: function () {
$.each(this._controls, function (idx, control) {
control.blur();
});
}
}
</script>
</head>
<body>
<form method="POST" action="http://www.htmlcodetutorial.com/cgi-bin/mycgi.pl">
<p>Naci en el mes de <select name="month">
<option selected value=1>enero</option>
<option value=2>febrero</option>
<option value=3>marzo</option>
<option value=4>avril</option>
<option value=5>mayo</option>
<option value=6>junio</option>
<option value=7>julio</option>
<option value=8>agosto</option>
<option value=9>septiembre</option>
<option value=10>octubre</option>
<option value=11>noviembre</option>
<option value=12>diciembre</option></select></p>
<p>Me gusta las <select name="fruit">
<option value=1>manzanas</option>
<option selected value=2>peras</option>
<option value=3>naranjas</option></select></p>
<input type="submit" name="Submit" value="Submit">
</form>
<span class="control dropdown" id="dropdown">
<dl>
<dt><span class="text"></span><span class="value"></span> <i class="fa fa-caret-down"></i></dt>
<dd><ul>
<li><span class="text"></span><span class="value"></span></li>
</ul></dd>
</dl>
</span>
</body>
<script>
$(document).ready(function () {
Dropdown.replaceAllSelects();
});
</script>
200_success
145k22 gold badges190 silver badges478 bronze badges
1 Answer 1
\$\begingroup\$
\$\endgroup\$
10
Tip for your code:
- Use
$name
for var names that represent a jQuery selection, nor for a member (it is the convention). - Since you use jQuery, consider writing a plugin extending
jQuery.fn
instead of prototyping
Malachi
29k11 gold badges86 silver badges188 bronze badges
-
1\$\begingroup\$ You couldn't have his code working? Weird. jsfiddle.net/sciencepharaoh/JwXPc \$\endgroup\$Daniel– Daniel2013年12月27日 14:04:17 +00:00Commented Dec 27, 2013 at 14:04
-
\$\begingroup\$ How did you get it to work @DanielCook ??? \$\endgroup\$Malachi– Malachi2013年12月27日 14:28:16 +00:00Commented Dec 27, 2013 at 14:28
-
\$\begingroup\$ @Malachi I put it in JSFiddle? Is it not working? I'm confused. It looks like it works to me. Though my linked fiddle removed some of the options but it worked with them in there as well. Actually, I did add 1 unnecessary semi-colon to make JSHint happy... \$\endgroup\$Daniel– Daniel2013年12月27日 14:43:52 +00:00Commented Dec 27, 2013 at 14:43
-
\$\begingroup\$ @DanielCook, I tried to take the code from the original question post, and it was a plain drop down menu. I am probably making noob mistakes myself \$\endgroup\$Malachi– Malachi2013年12月27日 15:41:20 +00:00Commented Dec 27, 2013 at 15:41
-
\$\begingroup\$ @Sinsedrix, the
tip for your code
section is the only section that is actually a review in my opinion \$\endgroup\$Malachi– Malachi2013年12月27日 16:04:30 +00:00Commented Dec 27, 2013 at 16:04
default
select
dropdowns, you may have a look at this code. \$\endgroup\$