views:

41

answers:

2

I am pretty new to this, so go easy on me:

I am building an image gallery with a main index page which allows users to select different categories of projects, a sub-index page which allows users to select specific projects within their selected category, and then the gallery page for that project.

The code below is for the main index page. I am trying to pass the value of the src attribute of the first image of the first gallery page to the main index page to use as a thumbnail.

I have effectively been able to load the correct URL into the imageLoc variable, but I need to pass it outside of the Ajax request to pass it into my HTML document.

Simply put, I am trying to pass the value of the imageURL variable to the imageLoc variable.

Thanks for your help.

    $('.galleryIndex a img').hide().each(function(){
        var destination = $(this).parent('a').attr('href');

        var imageLoc = $.ajax({
            url: destination,
            success: function(data){
                var pageLoc = $(data).find('.galleryList a:first').attr('href');
                $.ajax({
                    url: pageLoc,
                    success: function(data){
                        var imageURL = $(data).find('.galleryBox img:first').attr('src');
                        return imageURL
                    }
                });
            }
        });

        alert(imageLoc);

    });
+1  A: 

This will cause troubles do to the way the callback function is handled. It's a closure block that is called after the request has returned, so it runs apart from your main code in the function. If you want to alert the imageURL variable, alert it inside the callback function, or call another function to handle it. Since it is a callback function for an asynchronous server request, the part that alerts "imageLoc" will have run long before you ever get your async request back.

Edit: The only way to achieve what you're trying to do is to not make the ajax request asynchronously. If you set async:false, then you can call on the "responseText" property like this:

var html = $.ajax({
    url: "some.php",
    async: false
}).responseText;

But be warned...this will halt browser operation while the request is pending. It's usually best to block user interaction by other means if you don't want them to screw with the page while something is loading.

treeface
I find it hard to understand why I could alert the string, but not return it as a variable...
Squirkle
The reason I need to send it outside is so that I can make it operate on EACH of the `$('.galleryIndex a img')` objects: something like `$(this)attr('src', imageLoc)`. I am not just trying to alert the value (otherwise I **would** just do it inside of the callback).
Squirkle
So when you have 5 images, you're making 5 separate ajax calls? This seems a bit wasteful...why not just collect the href information for all of the images inside your each, then pass that data to your server where you can get in return all the data you need, thus being able to perform all the image src manipulation inside the callback function?
treeface
The reason you can't return is that your request is async. That means that the code that actually calls the function (and can get its return value) is not your code. It's a callback. By the time the callback gets called, this stack frame is long gone, so it can't be the return value for the $.ajax call. Working asynchronously makes coding a bit harder but much easier on the user since you don't need to block the system.
Juan Mendes
@treeface: the page is set up through a CMS, so filename/location of the images are likely to change, and all of the images are on seperate pages two layers deep. Maybe I am just not understanding your suggestion, but I don't see any way to do this more efficiently...
Squirkle
Let's get this straight...you're performing this action on every '.galleryIndex a img'. You're getting the href of the parent anchor and sending it off to the server **for every image**. This becomes bloated the moment you have more than one image in '.galleryIndex a img'. Instead, add the href to an array of hrefs, make your ajax call AFTER you've iterated through the images, sort out the data on your server, return an array of image urls, and assign them to the images after the *single* call has returned. Whenever possible, you want to avoid multiple AJAX requests where one will suffice.
treeface
I'm sorry, as I've said, I'm very new to this, but I still don't understand how I can grab 5 different src attributes from 5 different pages with a single Ajax call...
Squirkle
@Squirkle No worries...but look: you're missing the larger problem here. You need to rethink how you're making these requests. Create a script on your server that can handle the information...there's no good reason why you should be doing more than one http request here. Http requests are expensive...way more expensive than writing the logic to make it work in one http request.
treeface
Any ideas for resources to help me figure out how I would go about making such a script? I'm not sure what that would look like. Thanks so much for your help, by the way.
Squirkle
No worries, Squirkle. What server language are you using? The logic here would be: 1) compile an array of information that will allow your server script to do what it needs to do, 2) send the information to your server *once*, 3) have a server script take this information, do whatever you need to do to get a result (again, not entirely sure what you're doing here), and send it back to Javascript, 4) have the Javascript process it and put on the page whatever you like. I'm really talking about a generic approach to this problem of having too many server requests...the specifics are up to you.
treeface
It's fun being new to this stuff--this all sounds pretty exciting to me. Heh. I am using PHP. I'm beginning to see how this could work. Thanks so much for your help. I'm going to keep digging and take a shot at this.
Squirkle
A: 

I was able to get what I wanted as follows:

    $('.galleryIndex a img[id!="fp"]').hide().each(function(){
        var destination = $(this).parent('a').attr('href');
        $.ajax({
            url: destination,
            context: $(this),
            success: function(data){
                var pageLoc = $(data).find('.galleryList a:first').attr('href');
                $.ajax({
                    url: pageLoc,
                    context: $(this),
                    success: function(data){
                        var imageURL = $(data).find('.galleryBox img:first').attr('src'); //returns the src for the thumbnails
                        $(this).attr('src', imageURL);
                        $(this).load(function(){
                            $(this).show();
                        });
                    }
                });
            }
        });
    });
Squirkle