views:

373

answers:

3
$("select[name=field[]]").live("change", function() {
         $.getJSON("/json.php",{id: $(this).val(), ajax: 'true'}, function(j){
             options = '';
          for (var i = 0; i < j.length; i++) {
           options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';
          }
         });
         $(this).siblings("[name=logic[]]").html(options);
        });

So, I'd like to stick the result of the json callback (which it puts in options, a global variable) into a sibling of the object that is activating the event in the first place. The code I have above almost succeeds at this, but doesn't quite work because the callback doesn't happen instantly, so it sticks a blank string in the sibling. Thanks in advance and sorry if I got any terminology wrong there :)

+1  A: 

Why not place the $(this).siblings("[name=logic[]]").html(options); line within the callback itself? The best place seems to be immediately after the for loop is complete.

  $("select[name=field[]]")
  .live
  (
    "change", 
    function() {
      var selectElem = $(this);
      $.getJSON
      (
        "/json.php",
        {id: $(this).val(), ajax: 'true'}, 
        function(j) {
          options = '';
          for (var i = 0; i < j.length; i++) {
            options += '<option value="' + 
                       j[i].optionValue + '">' + 
                       j[i].optionDisplay + 
                       '</option>';
          }

          selectElem.siblings("[name=logic[]]").html(options);
        }
      );
    }
  );

EDIT: Added alternative code.

David Andres
This will make $(this) null, and that means I cannot find the sibling of it.
Harris
Yep, that's the only way you're going to get it, try David's solution. Your code is almost exactly the same as I have in one of my jQuery scripts, except I execute everything within the callback.
jakeisonline
@Harris: I've updated the answer with a code sample. You're right, the this keyword will no longer refer to the select element(s). Take a look at the selectElem variable and how it is used within the getJSON callback.
David Andres
Thanks so much!
Harris
A: 

Hi,

JQuery has some issues with ajax, mainly when you want to trigger functions "only when the request finishes". post, get, live, and so on, have those issues. The only one that works fine is the global $.ajax, wich I recommend you to use.

yoda
+2  A: 

I think you're looking at it backwards. You can make outer variables available to the inner function more easily. Here's the idea:

$("select[name=field[]]").live("change", function() {
    var theSelect = $(this);
    $.getJSON("/json.php",{id: $(this).val(), ajax: 'true'}, function(j){
        options = '';
            for (var i = 0; i < j.length; i++) {
                   options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';
            }
            theSelect.siblings("[name=logic[]]").html(options);
            });
    });

I have a concern also. It appears that you're trying to add the options into the select that triggered the event. They are children, not siblings. They way you have it, this will add options to every select that is a sibling of the event source. If my assumption is correct, you could do something like this in your inner for loop, rather than building a gigantic HTML string:

$('<option>blah blah</option>').appendTo(theSelect);
Barnabas Kendall
Thank you very, very much! This is exactly what I was looking for. Thanks for the concern also, but in my case this will work. Thanks again!
Harris