Jump to a scene based on the ID of the button

Thanks Jonathan ! It works perfectly well now !

There is something else I’d like to achieve but my JS is really bad for that.
My document has 3 scene. The first is the container and scene2 and scene3 can be displayed at will in the container scene using buttons. Those button’s ID’s are the name of the scene. How can I make the gotoScene JS pick the buttons ID and call the scene named after this ID ? The goal is to make a global function instead of having a function for every button
LoadSceneIntoIframe.hype.zip (40.7 KB)

As long as the triggering element is the one with the ID and the scene is in the same document, you would just use:

function dynamicGoToScene(hypeDocument, element, event) {
    hypeDocument.hypeDocument.showSceneNamed(element.id);
}

However note that IDs need to be unique in a document, so you couldn’t correctly have two buttons targeting the same scene. Instead you may want to use the class name field:

function dynamicGoToScene(hypeDocument, element, event) {
    hypeDocument.hypeDocument.showSceneNamed(element.className);
}

Thanks Jonathan,
I get the point but could not get the desired scene to display into the iframe of the main scene.
The code I used for the button which the classname is “scene2” is this one :

function goToScene(hypeDocument, element, event) {
if ( window.self !== window.top ){
hypeDocument.showSceneNamed(element.className, hypeDocument.kSceneTransitionInstant, 1.1)
}
}

And the current scene displays itself in the iframe

Oh sorry; I thought this was an entirely separate question. If you want a parent to control a child iframe you are going to need a communication mechanism using postMessage. There's a few examples if you search for this term on the forums. One example here (it is child to parent, but uses the same technique):

The other alternative might be to use this technique with the iframe src (but I haven't tried it in such a way):

Well, I’m not sure we talk the same thing :wink:
In the enclosed .hype, I’d like that buttons change the iframe content. On the exemple here, it perfectly works for displaying scene 2 in Intro scene, but I can’t get it to work with scene 3 to.
On the Intro scene, I may have many scenes to load in the iframe, using for each a button with the name of the scene, and I’m looking for a single function that uses each button classname to point to the desire scene bearing that classname name.
Btw, I only need display, no need for me to control the frame content from the scene that contains it
My intuition is there is a simple way o do that :slight_smile:
LoadSceneIntoIframe.hype.zip (40.7 KB)

Hah,

I see that this was my original code to get a iFrame to display a scene.

I do not think @jonathan is wrong in the suggestions… and they may be the best route.

But there is an alternative which is to use localStorage to store the button clicked id.

When the button is clicked the id is stored and the page reloaded.
The scene onload will then get the id from the localStorage and use that in the goto scene function.

iFrameMultiScene.hypetemplate.zip (34.8 KB)

To be honest, I was surprised this idea actually worked :grinning:

1 Like

Hello Mark
Yes ! it is actually working and you did a great job with this in the first place.
Reloading the page is a nice idea !
I made a little change in it following Jonathan recommandations in another post to have it work on
iPad :
This line :
var htmlWidget = hypeDocument.getElementById(“render”).children[0]; //iframe Widget

Should be written as it :
var htmlWidget = hypeDocument.getElementById(“render”).getElementsByTagName(“iframe”)[0] ; //iframe Widget

because of a div specification on mobile (I don’t really get it). See here Load scene into frame

@MarkHunte : One problem remains : instead of using button ID, I would like to use button ClassName. Any idea ?

LoadSceneInFrame.hype.zip (43.8 KB)

1 Like

Just put the names in the class name fields and change

localStorage.setItem('theScene', element.id);

to

localStorage.setItem('theScene', element.classList[1]);

The classList returns an array of class names for the element.
Hype give sall elements a hype class name. So when we add our own the element will have two or more depending how many we add.

the count of javascript arrays start from 0 not 1.
We want the second name because that is the one we added. The second item in the array is 1.

Hence we use the short hand to get that from the array.

element.classList[1]

Thanks @MarkHunte,
I tried to implement it in the document from my previous post but it’s still not working (or most probably, I did it wrong)

Lke this.

 localStorage.setItem('theScene',  element.classList[1]);
 
  if ( window.self !== window.top ){
  hypeDocument.showSceneNamed( 'intro', hypeDocument.kSceneTransitionInstant, 1.1)
 
 }
 
	//var  htmlWidget = hypeDocument.getElementById("render").children[0]; //iframe Widget
	 var  htmlWidget = hypeDocument.getElementById("render").getElementsByTagName("iframe")[0] ; //iframe Widget

	var hypeDoc = hypeDocument.documentId().split("_hype_container"); //document name	
	
	 htmlWidget.setAttribute("src", hypeDoc[0] + ".html");


LoadSceneInFrame.hype 2.zip (50.5 KB)

2 Likes

Oh, Mark ! Thanks so much ! It works now perfectly well including on mobile.
I get where I made mistakes entering your code. Everything is fine now.

1 Like

Hello @MarkHunte .
Thank you for this solution.
Local (in preview) it is full functional, but as I post it online, I get a 404 error, as I have no path to the html widget (I guess).
Can you, please, tell me how to link also to the iframe HTML from Resources? Or how to make it functional also online?

Thank you!
404

It isn't easy to say for certain without either seeing what URL it is hitting on the 404 (viewable by looking in the developer console logs) or by getting the link to that site itself to check it out. However, looking at the code from the loadIfram() function in the document:

var hypeDoc = hypeDocument.documentId().split("_hype_container"); //document name	
htmlWidget.setAttribute("src", hypeDoc[0] + ".html");

I can see that it is looking at the document container ID to try to construct a HTML filename. This could fail in a lot of ways since the document container ID gets normalized in various ways which might make it different than the filename. The preview probably works because the container name and file are both index which won't need changes. But something like LoadSceneInIFrame.html may get a container name of loadsceneiniframe, which would make a loadsceneiniframe.html a 404 on case-sensitive filesystems.

So you can either change the filename to something like index or you could probably replace those two lines with just:

htmlWidget.setAttribute("src", location.href);

I'm not exactly sure what you mean here? Can you elaborate?

2 Likes

Thank you @jonathan !
The hype file is the same as the one from Mark Hunte.

As I export the file, the HTML widget became a specific html file inside resources folder.

And the iFrame does not know how to load the scene, local (in the exported file):
Archive.zip (100.1 KB)

I don't know how to explain more than this.
Thank you!

This file is not really used. The code replaces the iframe from this file to trying to be the main hype .html document. It is just failing there.


When you export the document, you would need to export it as "index." Simply changing the filename to index after-the-fact won't work at all, since the code I showed above is assuming the element container name matches the file. Not only will it not in many cases, by renaming the filename you explicitly have broken that link.

Instead have you tried using my solution of changing the code to use the location.href?

If this does not work, you would need to either send a link of this posted live, or at least look at what URLs are failing in the developer console.

2 Likes

Thank you, @Jonathan, but I don't how to do this.

The steps would be:

  1. Show the loadIfram() function by clicking the tab if it is still open or selecting it in the Resources Library and clicking Edit Source…
  2. Delete the lines that are:
    var hypeDoc = hypeDocument.documentId().split("_hype_container"); //document name	
    htmlWidget.setAttribute("src", hypeDoc[0] + ".html");
    
  3. In the same spot, paste in this line:
    htmlWidget.setAttribute("src", location.href);
    

I've made this change:
LoadSceneInFrame-fixed.hype.zip (54.8 KB)

1 Like

Gosh, I forgot all about this code..

@Jonathan is correct. The code at the time was specific in the file name it was going to find.

Do as he suggests and also one other change I recommend .

In stead of using classes use the buttons Additional Html Attributes to set a scene value to look for.

Doing this IMHO will make the code/project more versatile since adding Hype class names and then getting them will need to be hard coded again if you want to add a new class name to the list.

So Give each button a n Additional attribute key/name of

scenelink
And then the relevant value i.e scene2 for button two and so on.


And change:

 localStorage.setItem('theScene',  element.classList[1]);
 
  if ( window.self !== window.top ){
  hypeDocument.showSceneNamed( 'intro', hypeDocument.kSceneTransitionInstant, 1.1)
 
 }
 
	//var  htmlWidget = hypeDocument.getElementById("render").children[0]; //iframe Widget
	 var  htmlWidget = hypeDocument.getElementById("render").getElementsByTagName("iframe")[0] ; //iframe Widget

	var hypeDoc = hypeDocument.documentId().split("_hype_container"); //document name	
	
	 htmlWidget.setAttribute("src", hypeDoc[0] + ".html");

to

localStorage.setItem('theScene',  element.getAttribute("scenelink"));
 
 
	 var  htmlWidget = hypeDocument.getElementById("render").getElementsByTagName("iframe")[0] ; //iframe Widget

 
	 htmlWidget.setAttribute("src", location.href  );

which will look for the additional attributes + the href which will load into the iframe.

The other thing to note:

When you use preview from Hype it will use its local Server to publish the page.

When you export to file, you cannot just double click and open the file in a browser locally and expect it to work because you will be loading a file:// in the browser from a locally store file and hit cross origin restrictions because you will not be publishing from a server which would use https:// of http://

You will need to disable the restrictions in the browser ( Safari Developer Menu > disable Cross Origin Restrictions ) and reload the page.

Make sure you turn the restriction back on when done.

There should be no problem if you upload to a server and then access it.

LoadSceneInFrame__v3.hype.zip (37.8 KB)

2 Likes

Thank you @Jonathan !

1 Like

Thank you @MarkHunte !

1 Like