views:

478

answers:

3

I'm using jquery in a greasemonkey user script. I'm trying to add a bunch of options to a select based on an array and also stick the corresponding object in the element with jquery.data like this:

$.each(some_array, function(item){
  // These next 2 statements seem awkward to me and I was also hoping 
  // a jquery master could show me a slicker way to perhaps 
  // combine them into something simpler
  $('select').append('<option>dummy</option>');
  $('select option:last-child').data('obj', item);
});

Then I'd like to get the object back out on selection:

$('select').change(function(){
   var theObj = $('option:selected', this).data('obj');
});

However in my greasemonkey user script, theObj is undefined. I know there's some monkey business going on with wrappers, unsafeWindow etc. I was just hoping somebody might know what exactly makes this not work.

+1  A: 

theObj should be undefined unless the last option of the first select box on the page is selected, because the data was only added to all of the last options on any selectbox, but was retrieved for the first selected option on the page.

Just as a style guide, you should consider using "this" more. e.g.

$('select').change(function(){
   var theObj = $('select option:selected').data('obj');
});

should be:

$('select').change(function(){
   var theObj = $('option:selected',this).data('obj');
});

or

$('select').change(function(){
   var theObj = $(this).find('option:selected').data('obj');
});
John C
I tried to clarify the question a bit more. I'm trying to put things in each new option as its added to the select. Does that loop above not work? I've done similar things outside of greasemonkey and it worked ok. Thanks for the feedback on using this.
polarbear
A: 

I may not be understanding the question very well, but I'll give the answer a shot.

You can iterate through an array, and in doing so use that object. Here's an example

var array_items = [0,1,2,3,4,5];
$.each(array_items, function(item) {
  $('select').append('<option>dummy</option>');
  $('select option:last-child').data('obj', item);
});

Hard to know exactly what "list" is in your question.

Rockitsauce
The problem is not really with iterating over the list of objects. (Though using $.each looks nicer). I need the objects that I cache using jquery.data to be available in the change handler and they're not for some reason. I think it has something to do with being run in a greasemonkey userscript
polarbear
+1  A: 

I found that all I needed to get it to work was this:

$.each(some_array, function(item){
 $('select').append('<option>dummy</option>');
 $('select option:last-child').each(function(index, elem){
    $(elem.wrappedJSObject).data('obj', item);
 });
});

$('select').change(function(){
  var theObj = $('option:selected', this.wrappedJSObject).data('obj');
});

It all has to do with XPCNativeWrappers. I'm not sure where in the jquery code it was using code that won't work with these wrappers (I looked a little but not too hard). This definitely presents a big security issue though, so I wouldn't put this into anything important.

polarbear