Adding removing options from drop downs can be down right annoying, but I came up with a simple prototype function that I think makes it a lot easier.
You just pass your select box object, an object with an enumerable-esque 'each' method, and a method for creating the individual options. On the advice of my wonderful co-worker Jim, you can pass an optional 4th argument that lets you maintain the options length. It's defaulted to 1 in order to preserve the first element in a drop down, which we typically leave blank.
Here's the function:
// Requires Prototype: http://www.prototypejs.org/
function setDropDown(field, data, method, index) {
field.options.length = index == null ? 1 : index;
data.each(
function(e) {
field.options.add(method(e));
}
);
}
And here are some quick examples:
To clear a drop down:
setDropDown(selectBoxObject,[]);
To copy items from one drop down to another:
setDropDown(
selectBoxObject,
otherSelectBoxObject.options,
function(e) {
return new Option(e.text, e.value);
}
);
Quick example using JSON
var json = Object.toJSON( {"COUNTRIES":[{"COUNTRY":"Hong Kong","ID":1},{"COUNTRY":"Japan","ID":2}]} );
setDropDown(
selectBoxObject,
json.COUNTRIES,
function(e) {
return new Option( e.COUNTRY, e.ID );
}
);
Tags: javascript, prototype
I wrote a little script using ColdFusion and JavaScript to merge two NetFlix accounts. It's ugly and cheesy, but it works so I thought I'd share.
Here's how you do it:
<!--- enter your feed here! --->
<cfset feed = "http://rss.netflix.com/QueueRSS?id=P4806480653914107620156446228102116" />
<!--- enter your consumer key here! --->
<cfset key = "your-consumer-key-here" />
<cfset href = "http://widgets.netflix.com/addToQueue.jsp?output=json&devKey=#key#&queue_type=disc&movie_id=http://api.netflix.com/catalog/movie/" />
<cffeed action="read" name="queue" source="#feed#" />
<cfset movies = queue.item />
<cfset idList = "" />
<cfloop array="#movies#" index="i">
<cfset idList = ListAppend(idList,ListLast(i.guid.value,"/")) />
</cfloop>
<cfoutput>
<script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js"/>
<--- Pop up a new window, swap the href every second. Told ya it was cheesy! --->
<script>
var popUp = window.open('http://google.com');
var idList = [#idList#];
new PeriodicalExecuter(
function(pe) {
if (idList.length == 0) {
pe.stop();
} else {
popUp.location.href = "#href#" + idList.pop();
}
},
1
);
</script>
</cfoutput>
Note: I don't know if this allowed by the EULA, or if there even is a EULA...so, use at your own risk!
Tags: coldfusion, javascript, netflix, prototype
I've been wanting to check out Rhino for a while, and I've been particularly interested in seeing how it compares to Ruby in terms of speed. The results have been a little varied, and it's a deeply flawed comparison. But it's something.
These scripts are just ports of my ruby solutions. There are a few places where I had to roll my own JavaScript functions instead of baked in Ruby methods, but other than that it was nearly line by line translation.
Add all the natural numbers below one thousand that are multiples of 3 or 5.
var total = 0;
for(var i = 0; i < 1000; i++) {
if(i % 3 == 0 || i % 5 == 0) {
total += i;
}
}
print(total);
Find the sum of all the even-valued terms in the Fibonacci sequence which do not exceed four million.
function fib(stack, n) {
if(n == 0) {
return 1;
}
if(n == 1) {
return 2;
}
return stack[n - 1] + stack[n - 2];
}
var max = 4000000;
var total = 0;
var stack = [];
for(var i = 0; i < max; i++) {
stack[i] = fib(stack,i);
if(stack[i] > max) {
break;
}
if(stack[i] % 2 == 0) {
total += stack[i]
}
}
print(total);
Find the largest prime factor of a composite number.
function find_highest_prime_factor(n) {
var max = Math.round(Math.sqrt(n));
for(var i = max; i >= 2; i--) {
if(n % i == 0 && find_highest_prime_factor(i) == 1) {
return i;
}
}
return 1;
}
var target = 600851475143;
print(find_highest_prime_factor(target));
Find the largest palindrome made from the product of two 3-digit numbers.
function get_highest_palindrome(high, low) {
var highest = 0;
for(var i = high; i >= low; i--) {
for(var j = high; j >= low; j--) {
sum = i * j;
if(sum <= highest) {
break;
}
if(is_palindrome(sum.toString())) {
highest = max(highest, sum);
}
}
}
return highest;
}
function reverse(string) {
var array = string.split('').reverse();
var out = '';
for(key in array) {
out += array[key];
}
return out;
}
function max(a,b) {
if(a > b) {
return a;
}
return b;
}
function is_palindrome(string) {
return string == reverse(string);
}
print(get_highest_palindrome(999, 100));
What is the smallest number that is evenly divisible by all of the numbers from 1 to 20?
function gcd(a,b) {
var x = a;
var y = b;
var result;
while (y != 0) {
result = x % y;
x = y;
y = result;
}
return x;
}
function lcm(a,b) {
return (a * b) / gcd(a, b);
}
var max = 20;
var min = 11;
var n = min;
for(var i = min; i <= max; i++) {
n = lcm(n,i);
}
print(n);
Tags: javascript, project euler, rhino
I revisited my Event.observe proof of concept and tidied it up a bit with a little help from stackoverflow.com.
Here's how it do
This here defines a method to determine which method is currently running. There's a slicker way to do this in 1.9 and you can read about them both on stackoverflow.com.
module Kernel
private
def current_method_name
caller[0] =~ /`([^']*)'/ and $1
end
end
Here's my actual observer class, named after it's inspiration.
class Event
def initialize
@events = []
end
def observe object, method, callback
handle = Handle.new self, object, method, callback
@events << handle
handle
end
def delete handle
@events.delete handle
end
def call object, method
handle = Handle.new self, object, method
@events.each do |e|
e.call if e.shares_type_with
end
end
end
And finally there's a basic handle class:
class Handle attr_readerbserver,
bject, :method, :callback def initialize observer, object, method, callback = nil @observer = observer @object = object @method = method @callback = callback end def shares_type_with? handle object == handle.object && method == handle.method end def call callback.call end def stop_observing observer.delete self end end
And here's how you use it, In the following example we want our "second" Test_Object to run it's test_method whenever we run the same method for our "first" object.
The important thing here is the "notify" method, you'll need to drop this method into whatever you'd like to be able to observe. If you wanted to be able to observe everything you could always loop through the methods, alias and override.
class Test_Object
def initialize observer, label
@observer = observer
@label = label
end
def notify method
@observer.call self, method
end
def test_method
puts "Calling => #{@label}"
notify current_method_name
end
end
observer = Event.new
first = Test_Object.new observer, "First"
second = Test_Object.new observer, "Second"
h1 = observer.observe(
first,
"test_method",
second.method :test_method
)
first.test_method
# Calling First
# Calling Second
#=> nil
And we can drop the handle by simply calling it's stop_observing method
h1.stop_observing first.test_method # Calling First #=> nil
That's it.
Download the Proof of Concept!
Tags: javascript, prototype, ruby
I love Prototype. I wanted to implement something akin to Event.observe in some of the gui applications I've been playing with. The code's fugly, but it's a first pass and I just finished my last Netflix.
Example JavaScript Implementation is pretty:
a = new Test_Object( "First" )
b = new Test_Object( "Second" )
Event.observe(
a,
"test_method",
b.test_method
)
Event.observe(
b,
"test_method",
function(e) { new Test_Object("Third").test_method() }
)
Example Ruby Implementation..not so pretty.
$event = Event.new
a = Test_Object.new( "First" )
b = Test_Object.new( "Second" )
$event.observe(
a,
"test_method",
b.method( "test_method" )
)
$event.observe(
b,
"test_method",
Proc.new { Test_Object.new("Third").test_method }
)
a.test_method
Yep, that's a global. I'm still working on it. Any ideas would be welcome!
Tags: javascript, prototype, ruby