Send data to external page before page is loaded into Shadowbox iframe

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Send data to external page before page is loaded into Shadowbox iframe

stefan
I'm hoping someone can help me.

I need to send dynamic data to the external page that is being loaded in my Shadowbox. I need the data to be sent at the moment (or just before) the external PHP page is loaded.

I can do this successfully by placing the data in the href of the link, and then retrieving it using $_GET on the PHP page. But this will only work if I click on the link.

If I am using Shadowbox's internal navigation, then I can not alter the href of the link as it is already cached, and I can't alter the content of the cached object as it will destroy the continuity of the navigation.


In the below code I have attempted to use Ajax to POST the said data to the external PHP page secondary_imgs.php before Shadowbox.open() is triggered.


Here is my first attempt:

                                $.ajax({
                                        type: 'POST',
                                        url: 'secondary_imgs.php',
                                        data: {shadowWidth:shadowWidth, shadowHeight:shadowHeight},
                                });
                               
                                shadowBoxSetup();
                                setTimeout("Shadowbox.open(c)", 400)



I have also tried placing `setTimeout("Shadowbox.open(c)", 400)` in the `Success` callback:

                                shadowBoxSetup();
                                $.ajax({
                                        type: 'POST',
                                        url: 'secondary_imgs.php',
                                        data: {shadowWidth:shadowWidth, shadowHeight:shadowHeight},
                                        sucess: setTimeout("Shadowbox.open(c)", 400)
                                });


And finally tried placing the entire Ajax and `Shadowbox.open(c)` in a `setTimeout`:

                                shadowBoxSetup();
                                setTimeout(function () {
                                        $.ajax({
                                                type: 'POST',
                                                url: 'secondary_imgs.php',
                                                data: {shadowWidth:shadowWidth, shadowHeight:shadowHeight},
                                                sucess: Shadowbox.open(c)
                                        });
                                }, 400);



None of the above attempts have worked. Although secondary_imgs.php opens inside the Shadowbox iframe, the data is not reaching secondary_imgs.php.

I'm not sure if anyone else has encountered this problem, or if there is a method to do this in Shadowbox itself, but I scoured the Forum and while there is plenty of data on using Shadowbox with links dynamically created via Ajax, I couldn't find anything on sending data (with Ajax or otherwise) to the link Shadowbox is opening.

Thanks for any help you can provide.
Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

arttronics
I can do this successfully by placing the data in the href of the link, and then retrieving it using $_GET on the PHP page. But this will only work if I click on the link.

   You can get any href contents without clicking on a link using standard HTML markup. Google can show zillions of methods for this.


If I am using Shadowbox's internal navigation, then I can not alter the href of the link as it is already cached, and I can't alter the content of the cached object as it will destroy the continuity of the navigation.

   You can alter the href contents or cached object while you are in a Shadowbox Gallery, but this of course will destroy continuity of the current navigation because your interfering with it. The iframe contents are not cached, only the files names!


Humm, maybe my old unpublished demo titled Shadowbox to Shadowbox iframe Morph DEMO can show you that the above is true. It's unique because Shadowbox by default does not change iframe page size for the next link. The examples in the demo can be applied to non iframe content.

Shadowbox_to_Shadowbox_iframe_Morph_DEMO.html
iframe001.html
iframe002.html
iframe003.html
iframe004.html

When posting your markup here on the forum follow these simple steps:

0. Login and paste your markup into the Message Box.
1. Mouse select the markup you just pasted.
2. Press the More Button from the Message Box Toolbar.
3. Select Raw text from the drop down menu. DONE!

If I don't respond to your POST, it's your inability to provide your markup correctly.

Check out a few DEMOS I made that are here in this forum.

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

dataload
This post was updated on .

I don't really see why altering Shadowbox.cache would destroy the continuity of the counter navigation. The shadowbox.cache is just an object and can be manipulated using standard javascript dot notation like any other object. So taking the example of the Shadowbox homepage if you were to wait for shadowbox to initialise and then call:

Shadowbox.cache.1.content = "http://www.shadowbox-js.com/gallery/mustang/blue.jpg"
when you click on the link to the red Mustang it'll load the image of the blue Mustang. You haven't destroyed the continuity of the counter, you've just modified one of its objects. I haven't actually test this but you can see that just by modifying the object in the Firebug DOM tab you can achieve the desired effect:

I'm not saying that's a complete solution to what you're trying to achieve but if you really need to pass some values via a querystring based on calculations that take place after shadowbox has been setup, then appending the relevant querystring values to the existing content strings in Shadowbox.cache might be possible (though it's not likely to be simple).

From what I understand, you're trying to make the layout of the page you're loading in the shadowbox iframe render differently depending on the dimensions of the shadowbox (or something like that?). It kind of depends on what you're trying to achieve but I'd be tempted to forget about passing the values from the parent page and try to design the page you're loading so that it reacts to changes in the window size automatically. This could be done via pure CSS, javascript or possibly even CSS media queries to make resolution dependant layouts. That way you're maintaining separation of concerns and it's likely to be much easier to react to changes in the size of the shadowbox that would occur if the end user resizes their browser window.

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

arttronics
I wrapped the following in a Function that is started from Shadowbox.init onOpen (also tried onFinish and onChange) and do get Firebug updates that indeed the cache has changed, but Shadowbox does not show said change.


console.log(Shadowbox.cache[1].content);  // before change

Shadowbox.cache[1].content = "01-Home_files/blue.jpg";  // change applied

console.log(Shadowbox.cache[1].content); //verify cache has changed


The method of calling this right after Shadowbox.init also had same effects with an additonal "not defined" error. Perhaps this is due to Shadowbox's natural design behavior.

It's good to know Shadowbox 4.0 will include Gallery Index and updated Shadowbox Counter so that content can be dynamically added and pulled from the current Shadowbox Gallery without issue.

When posting your markup here on the forum follow these simple steps:

0. Login and paste your markup into the Message Box.
1. Mouse select the markup you just pasted.
2. Press the More Button from the Message Box Toolbar.
3. Select Raw text from the drop down menu. DONE!

If I don't respond to your POST, it's your inability to provide your markup correctly.

Check out a few DEMOS I made that are here in this forum.

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

dataload
This post was updated on .

Only just had a chance to give this a go but it works as long as you update the gallery object along with the cache. Super simple test case:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="shadowbox.css">
<script type="text/javascript" src="shadowbox.js"></script>
<script type="text/javascript">
function myOpen() {
	Shadowbox.cache[2].content = "http://www.shadowbox-js.com/gallery/mustang/red.jpg"
	Shadowbox.gallery[1].content = "http://www.shadowbox-js.com/gallery/mustang/red.jpg"
};
Shadowbox.init({
	onOpen : myOpen
});
console.log(Shadowbox.cache);
</script>
</head>
<body>
<a rel="shadowbox[myGal]" href="http://www.shadowbox-js.com/gallery/mustang/red.jpg" title="I'm red!">red</a> | 
<a rel="shadowbox[myGal]" href="http://www.shadowbox-js.com/gallery/mustang/blue.jpg" title="The link said blue but I'm red too!">blue</a> | 
<a rel="shadowbox[myGal]" href="http://www.shadowbox-js.com/gallery/mustang/grey.jpg" title="I'm grey!">grey</a>
</body>
</html>

(the numbering between the cache and galley is out by 1 since the cache is referring to an object name whereas gallery is a zero-indexed array)

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

arttronics
This post was updated on .
Thanks petemitch, your markup is an excellent method to use!

Using your markup, any preset cached gallery attribute for any gallery item can be manipulated when required while retaining all other cached aspects for that gallery item.

For other users following, changing other Shadowbox attributes in the gallery are simple:

  Shadowbox.cache[2].content = "http://www.shadowbox-js.com/gallery/mustang/red.jpg";	
  Shadowbox.gallery[1].content = "http://www.shadowbox-js.com/gallery/mustang/red.jpg";

  Shadowbox.cache[3].width = 900;
  Shadowbox.gallery[2].width = 900;

  Shadowbox.cache[3].title = "New Title";
  Shadowbox.gallery[2].title = "New Title";


EDIT: This markup and comments have been edited to reflect petemitch's valid solution and working example. Thank You!

When posting your markup here on the forum follow these simple steps:

0. Login and paste your markup into the Message Box.
1. Mouse select the markup you just pasted.
2. Press the More Button from the Message Box Toolbar.
3. Select Raw text from the drop down menu. DONE!

If I don't respond to your POST, it's your inability to provide your markup correctly.

Check out a few DEMOS I made that are here in this forum.

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

arttronics
In reply to this post by stefan
If I am using Shadowbox's internal navigation, then I can not alter the href of the link as it is already cached, and I can't alter the content of the cached object as it will destroy the continuity of the navigation.

This is no longer the case.

New markup provide to play with that's easily implemented.

When posting your markup here on the forum follow these simple steps:

0. Login and paste your markup into the Message Box.
1. Mouse select the markup you just pasted.
2. Press the More Button from the Message Box Toolbar.
3. Select Raw text from the drop down menu. DONE!

If I don't respond to your POST, it's your inability to provide your markup correctly.

Check out a few DEMOS I made that are here in this forum.

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

dataload
In reply to this post by arttronics
arttronics wrote
I believe your example required both items to be for item [1].
If you want to keep the cache object in sync with the gallery object they have to be different by 1 for the reason I stated above (arrays are zero-indexed), try it with a single link instead of a gallery if you want proof.
Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

arttronics
I've edited my remarks above, because I discovered my own browser needed to be flushed as your example replaced the whole cached item in the gallery, not just the href. This is not the case any longer. Thanks for posting back which made me aware of my browser glitch (although I always use CTRL and F5, I don't know what happened!).

In your version the line with the Shadowbox.cache has no effect when it's there or when it's removed. The key item making everything a go is the line thereafter, by writing to the Shadowbox.gallery directly will supersede the Shadowbox attribute that's cache. This is true when only one item is used in a non-Shadowbox gallery (but the index will need to be 0 in that case). I notice no sync issues when removing the Shadowbox.cache line, so it appears that this line is redundant.

However, forget that last paragraph!

Even though there is no visual abnormalities when the line with Shadowbox.cache is removed, the contents of the cache remain for the older content. I think your point is to "update" the cache so that it can be used internally by other calls, so that the cache reflects the new contents.

When posting your markup here on the forum follow these simple steps:

0. Login and paste your markup into the Message Box.
1. Mouse select the markup you just pasted.
2. Press the More Button from the Message Box Toolbar.
3. Select Raw text from the drop down menu. DONE!

If I don't respond to your POST, it's your inability to provide your markup correctly.

Check out a few DEMOS I made that are here in this forum.

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

dataload
This post was updated on .

Not suggesting it's necessary (or even necessarily useful), just playing around with the alternatives. Try this sample for an idea of what you could do by modifying the cache and not touching the gallery. Since the gallery object is built from the objects in the cache the first time you launch the shadowbox it shows the red car, on subsequent launches it shows the grey car (like I said, not necessarily useful, but interesting nonetheless).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="shadowbox.css">
<script type="text/javascript" src="shadowbox.js"></script>
<script type="text/javascript">
function myOpen() {
    Shadowbox.cache[1].content = "http://www.shadowbox-js.com/gallery/mustang/grey.jpg"
};
Shadowbox.init({
    onOpen : myOpen
});
</script>
</head>
<body>
<a rel="shadowbox" href="http://www.shadowbox-js.com/gallery/mustang/red.jpg" title="Red first time, grey thereafter!">Link</a>
</body>
</html>
Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

dataload
This post was updated on .
In reply to this post by stefan

Just to bring this thread back somewhere closer to an answer to the original question here's a quick sample that actually updates the gallery objects by appending querystrings based on some parameters passed to it. In this case once you navigate within the gallery it uses google calculator to multiply the dimensions of the shadowbox you've just navigated from (useful eh?)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="shadowbox.css">
<script type="text/javascript" src="shadowbox.js"></script>
<script type="text/javascript">
function updateQueryString(a, k, v) {
  var re = new RegExp("([?|&])" + k + "=.*?(&|$)", "i"),
  separator = a.indexOf('?') !== -1 ? "&" : "?";
  if (a.match(re))
    return a.replace(re, '$1' + k + "=" + v + '$2');
  else
    return a + separator + k + "=" + v;
};
function myFinish() {
  for each(var i in Shadowbox.gallery) {
    i.content = updateQueryString(i.content,"q",Shadowbox.dimensions.innerWidth+"*"+Shadowbox.dimensions.innerHeight)
    console.log(i.content);
  };
};
Shadowbox.init({
  onFinish : myFinish
});
</script>
</head>
<body>
<a rel="shadowbox[myGal];width=900;height=300" href="http://www.google.co.uk/search" title="Multiply Shadowbox dimensions">Link1</a> | 
<a rel="shadowbox[myGal];width=1000;height=400" href="http://www.google.co.uk/search" title="Multiply Shadowbox dimensions">Link2</a>
</body>
</html>

This example uses onFinish since you don't know the dimensions of shadowbox until you've shown at least one piece of content

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

stefan
Wow, petemitch, I can't thank you enough. It's funny because I was playing around with changing the cache content myself, but it wasn't working. I didn't even think to change the gallery item as well. Very interesting indeed.

About your example using onFinish: Would it also be possible to use onChange do you think? I haven't used onFinish so I'm not sure how it works, but I would like to know your opinion.

Also, I have been using the following jQuery to update a link at the time of click (not while in the navigation). It has been working quite well for me, but I'm thinking, perhaps, since the method you have presented works so well, I should use yours instead of the one I will show below. Let me know what you think.



        function secondaryImgs() {
                $("a[href^='secondary_imgs.php']").click(function(){
                        var pageWidth = $(window).width();
                        var pageHeight = $(window).height();
                        var maxshadowWidth = pageWidth - 100;
                        var maxshadowHeight = pageHeight - 88;
                        var mWidth = parseInt($(this).attr("mwidth"), 10);
                        var mHeight = parseInt($(this).attr("mheight"), 10);
                        var maxSecondaryWidth = mWidth + 60;
                        var maxSecondaryHeight = (Math.ceil(mHeight/0.88235294)) + 41;
                        if(maxSecondaryWidth <= maxshadowWidth) {
                                var shadowWidth = maxSecondaryWidth;
                        } else {
                                var shadowWidth = maxshadowWidth;
                        }
                        if(maxSecondaryHeight <= maxshadowHeight) {
                                var shadowHeight = maxSecondaryHeight;
                        } else {
                                var shadowHeight = maxshadowHeight;
                        }
                        var shadowboxrel = 'shadowbox;height=' + shadowHeight + ';width=' + shadowWidth;
                        $(this).attr('rel', shadowboxrel); // <= The important bit starts here!
                        var url = $(this).attr('href');
                        var idx = url.indexOf('&shadowWidth=');
                        if (idx != -1) {
                                url = url.substr(0, idx);
                        }
                        url += '&shadowWidth=' + shadowWidth + '&shadowHeight=' + shadowHeight;
                        encodeURIComponent(url);
                        $(this).attr('href', url);
                        Shadowbox.clearCache(); // <= clear Shadowbox's cache
                        shadowBoxSetup(); // <= set up all Shadowbox links
                });
        }

The only thing that I'm thinking is good about the above method, is that, instead of fiddling around with the Shadowbox Cache, it just recreates it. And in this circumstance, that doesn't seem to inhibit the function. So I'm debating what to do. I'll try both methods out, but your opinion would be fantastic.

Thanks again for all the help. You're a godsend! :)
Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

dataload

Yeah you could probably use onChange instead of onFinish. They're both callbacks, the only difference is that onFinish fires after a piece of content has finished loading whereas onChange fires once you actually click to navigate within the gallery.

If you've got a working method that uses the API instead of messing around hacking objects then I'd be tempted to stick with it. The only thing I still don't understand is why you want to pass the shadowbox dimensions from the parent page in the first place. It would be much easier, more reliable and maintainable to just get the dimensions of the window in the content page you're loading and use that for the basis of whatever it is you want to do. Another really simplified example (the first bit of code is a page that loads the second):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="shadowbox.css" />
<script type="text/javascript" src="shadowbox.js"></script>
<script type="text/javascript">
  Shadowbox.init();
</script>
</head>
<body>
  <a rel="shadowbox;width=400;height=200" href="content.html" title="I know my dimensions!">Link</a>
</body>
</html>

which loads:

A page called content.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="jquery-1.6.4.min.js"></script>
</head>
<body style="background:white;margin: 10px;">
<span id="JustSomeID"></span>
<script type="text/javascript">
$(function() {
  var pageWidth = $(window).width(); 
  var pageHeight = $(window).height();
  $("#JustSomeID").text("I'm " + pageWidth + " pixels wide and " + pageHeight + " pixels high!")
}); 
</script>
</body>
</html>

Maybe there's some overriding reason why you can't do it this way, but if not then it's going to be much easier.

Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

stefan
I remember you mentioning that, was it last week? Anyway, I thought about it because I was surprised to know that one could figure out the dimensions the an iframe an external source was in, from the external source. When I found that out it was like a revelation that I had been doing all this work for nothing.

But then I realized it wasn't all for nothing. The data being loaded on the external page (in the shadowbox) are images, governed by a database. The dimensions being passed are utilized by PHP to form the actual page, i.e. css, thumbnail dimensions, viewing area dimensions, etc. And although I probably could work it so all those things are done via javascript, I'm very happy with the results at this time with it being done server side.

Does that clarify my reasoning a bit?
Reply | Threaded
Open this post in threaded view
|

Re: Send data to external page before page is loaded into Shadowbox iframe

dataload
yeah that makes sense, I was assuming that you were retrieving the querystring parameters client side and doing something with them using javascript, but if you're doing the heavy lifting server side then I can see where you're coming from.