<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>untitled</title>
<script src="prototype.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
var NiceSelect = Class.create({
initialize: function(selectElement, otherOptionValue) {
this.selectTag = $(selectElement);
this.otherOptionValue = otherOptionValue;
this.selectTag.observe('change', this.actOnChange.bind(this));
},
actOnChange: function(event) {
if (Event.element(event).value == this.otherOptionValue) {
var newLabel = prompt("Enter the new category name:", "");
var newOptionValue = 'new#' + this.selectTag.select('option').length;
var newOption = new Element('option',{'value': newOptionValue });
newOption.innerHTML = newLabel;
this.selectTag.insert({bottom:newOption});
this.selectTag.value = newOptionValue;
}
}
});
</script>
</head>
<body>
<select id="mySelect">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
<option value="---">Add other</option>
</select>
<script type="text/javascript" charset="utf-8">
new NiceSelect('mySelect', '---');
</script>
</body>
</html>
Refactorings
No refactoring yet !
theflowmustspice.blogspot.com
November 18, 2009, November 18, 2009 20:53, permalink
Just a few refinement points that I see. It's always nice to use an options hash as its more explicit and allows for defaults at the same time. Also it's safer to use "bindAsEventListener()" on your observe. Don't forget about the new event.element() shorthand instead of Event.element(event). $F(element) could have alternatively been element.getValue(), but just calling element.value is stepping around a Prototype function. Also the prototype version of ".innerHTML" is basically ".update()" which is nice when used with method chaining.
var NiceSelect = Class.create({
initialize: function(selectElement, options) {
this.options = Object.extend({otherOptionValue: "---"}, options || {});
this.selectTag = $(selectElement);
this.selectTag.observe('change', this.actOnChange.bindAsEventListener(this));
},
actOnChange: function(event) {
var element = event.element();
if (!$F(element) == this.options.otherOptionValue) return;
var newLabel = prompt("Enter the new category name:", "");
var newOptionValue = 'new#' + this.selectTag.select('option').length;
this.selectTag.insert({bottom: new Element('option', {'value': newOptionValue}).update(newLabel)});
this.selectTag.value = newOptionValue;
}
});
// Call With:
new NiceSelect('mySelect'); // Uses the default "otherOptionValue"
// Or:
new NiceSelect('mySelect', {otherOptionValue: '---'});
Denis Jacquemin
December 11, 2009, December 11, 2009 23:00, permalink
Same stuff refactored and improved, thanks
var NiceSelect = Class.create({
initialize: function(selectElement, options) {
this.options = Object.extend({otherOptionValue: "---"}, options || {});
this.selectTag = $(selectElement);
this.selectTag.observe('change', this.actOnChange.bindAsEventListener(this));
},
actOnChange: function(event) {
var element = event.element();
if (!$F(element) == this.options.otherOptionValue) return;
var newLabel = prompt("Enter the new name:", "");
if (this.alreadyTaken(newLabel)) {
alert('Name has already been taken');
this.selectTag.options[alreadyTakenIndex].selected = 'selected';
return;
}
var newOptionValue = 'new#' + this.selectTag.select('option').length;
this.selectTag.insert({bottom: new Element('option', {'value': newOptionValue}).update(newLabel)});
this.selectTag.value = newOptionValue;
},
alreadyTaken: function(label) {
var taken = -1;
var index = 0;
this.selectTag.select('option').each( function(option) {
if (option.innerHTML == label) {
taken = index;
}
index = index+1;
})
if (taken == -1) return false;
else return true;
}
});
This code works fine, I just want to improve it, thanks for your reply.
be sure to get prototype.js 1.6.1 if you want to run it.
Cheers,
Denis