0

I've read a lot on this topic around this site, but being extremely new to jquery/js I'm having trouble wrapping my head around it and implementing it where I need to.

I'm trying to change the links in an iFrame so that they point back to the parent object, and yes they are on the same domain so no cross-security issues.

The links are onclick objects like this

<td class="partial wd2" onclick="window.top.location.href='https://www.planyo.com/booking.php?calendar=34264&amp;planyo_lang=EN&amp;mode=reserve&amp;prefill=true&amp;one_date=14%20Aug%202018&amp;start_date=14%20Aug%202018&amp;start_time=&amp;end_time=&amp;resource_id=104777'" title="Available for part-day rental only. Click on the date above for details.">•</td>

and I want to change all of them to target the parent.

I think I need to change them to:

<td class="partial wd2" onclick=window.open('https://www.planyo.com/booking.php?planyo_lang=EN&mode=reserve&prefill=true&one_date=14%20Aug%202018&start_date=14%20Aug%202018&start_time=&end_time=&resource_id=104777','_parent')>•</td>

or an alternative that may be better, like window.parent.location...

My main problem is I can't seem to select that deep using a class/id selector. I can select the preceding divs with IDs but cannot go further than that and I have no idea why.

<!--Custom JS Overrides -->
<script>
var f=$('#calp_852795051')
f.load(function(){ 
        f.contents().find('#horizontal_calendar').css({'border' : '1px solid red'});
        f.contents().find('#caltop').css({'border' : '1px solid yellow'});
        f.contents().find('#cal').css({'border' : '1px solid green'});
        })

</script>

results in (where #calp_852795051 is the iframe id):

<div id="caltop" class="page" style="padding: 2px; background: transparent; border: 1px solid yellow;">
<div id="horizontal_calendar" class="left" style="border: 1px solid red;">
<table id="cal" class="calhoriz" cellpadding="0" cellspacing="0"> ......

because #cal is null.

Coding is not something I do that often and I'm obviously missing something here, and I can't seem to figure it out.

The page is: https://www.planyo.com/booking.php?calendar=34264&feedback_url=https%3A%2F%2Fwww.planyo.com%2Fbooking.php%3Fcalendar%3D34264&presentation_mode=1&planyo_lang=en&resource_id=104777&mode=resource_desc

Any help offered is much appreciated.

edit

So i've tried another method based on juan's reference, but I'm still not getting anywhere and I think it's my lack of understanding here that's the issue. Unfortunately no matter how much I read I'm just not getting it.

    <script>
    var f = document.getElementById('calp_852795051');
    f = (f.contentWindow) ? f.contentWindow : (f.contentDocument.document) ? f.contentDocument.document : f.contentDocument;
    f.document.querySelector('#horizontal_calendar').css({'border' : '1px solid red'});
</script>

but #horizontal_calendar is null this time.

edit2

So I've reverted back to the original method as I'm struggling to grasp the suggestion by juan.

What I don't understand is how I can target some elements/selectors but not others, when they're all part of the same iframe?

var b=$("[id^=calp]");
    b.load(function(){ 
            b.contents().find('script').remove(); //works
            b.contents().find('body').css({'border' : '2px solid green'}); //works
            b.contents().find('#caltop').prepend('<p>Blah Blah</p>'); //works
            b.contents().find('#horizontal_calendar').css({'background' : '#c9c9c9'}); //works
            b.contents().find('#horizontal_calendar').prepend('<p>Blah Blah</p>'); //any element/selector thing from this point is not working
            b.contents().find('td').css({'border' : '3px solid black'}); //doesn't work as is inside #horizontal_calendar
    })

It just seems to hit a wall at #horizontal_calendar and anything before is fine.

edit3 Turns out was a timing thing.

var b=$("[id^=calp]");
b.load(function(){ 
        b.contents().find('script').remove(); //works
        b.contents().find('body').css({'border' : '2px solid green'}); //works
        b.contents().find('#caltop').prepend('<p>Blah Blah</p>'); //works
        b.contents().find('#horizontal_calendar').css({'background' : '#c9c9c9', 'width' : '100%'}); //works

        function timeout(){ 
            b.contents().find('#horizontal_calendar').prepend('<p>Blah Blah</p>'); //any element/selector thing from this point is not working
            b.contents().find('td').css({'border' : '3px solid black'}); //doesn't work as is inside #horizontal_calendar
            var element =b.contents().find('#cal');

            console.log(element);
        }

        setTimeout(timeout, 10000);
})

by setting a timeout for the operations it did eventually find them, so for whatever reason they hadn't formed in the DOM tree as fast as the others and so were coming back null.

I'm sure there are more elegant ways to handle this but at least i'm on the right track.

Always welcome for suggestions on better methods to achieve the same results.

N.Moore
  • 1
  • 1
  • You need to pass the correct context to jQuery. See this question and take a look at Ran's answer. https://stackoverflow.com/questions/2150327/what-is-the-jquery-javascript-context-of-a-frame-within-an-iframe – Juan Aug 14 '18 at 16:37
  • Thanks for the reply Juan. I've read through but I'm still struggling with this. I thought I understood it but I can't seem to even achieve what I did before using this method (edited the post above to show) – N.Moore Aug 15 '18 at 09:48

1 Answers1

0

Following my comment (giving jquery a context in the iframe) I got #cal doing:

var $ctx = $("#calp_852795051").get(0).contentDocument;  
$cal = $("#cal", $ctx);
Juan
  • 5,525
  • 2
  • 15
  • 26
  • That's great Juan How do I go about manipulating the contents using this method? – N.Moore Aug 17 '18 at 11:42
  • Well you now have a way of using jQuery with the elements in the iframe, just provide the context together with the selector. I thought that is what you were asking for. – Juan Aug 17 '18 at 11:46
  • I already had a way of using jQuery in the iframe, it was just executing before the full content had loaded and setting a timeout seems to allow it to work. Same as with your method, if I don't set a timeout only the head and body html elements are loaded, but with a timeout, all html elements are loaded. Forgive me my jquery knowledge is very small, and I just didn't understand how to use your method and achieve the same results (i'm learning as I go). – N.Moore Aug 17 '18 at 14:26
  • I am sorry but I understood the main problem you had was trying to get hold of #cal which was returning null. If it is something different, then I am afraid I don't understand the question. – Juan Aug 17 '18 at 14:33
  • My first post details what I'm trying to achieve: "I'm trying to change the links in an iFrame so that they point back to the parent object" And the problem: "My main problem is I can't seem to select that deep using a class/id selector. I can select the preceding divs with IDs but cannot go further than that and I have no idea why." This wasn't about #cal specifically, but about why it stopped there, and I believe the reason has been discovered. It just wasn't loaded by the time the script ran. I appreciate the response Juan, but I thought I was pretty clear, I'm sorry if I wasn't – N.Moore Aug 17 '18 at 15:16