Getting the SymbolInstance for an element inside of a symbol

A few people have asked how to get the symbolInstance from a child element, so I thought I would post some javascript here.

For example, if you had if you had an ‘On Mouse Click’ run javascript action on an element inside of a symbol the following code would get you the correct symbolInstance:

function getSymbolInstanceForElement(hypeDocument, element, event) {
    var symbolInstance = null;
    var parentSymbolElement = element.parentNode;
    while (symbolInstance == null && parentSymbolElement != null) {
	    symbolInstance = hypeDocument.getSymbolInstanceById(parentSymbolElement.id);
	    parentSymbolElement = parentSymbolElement.parentNode;
    }
    console.log(symbolInstance);
}
8 Likes

This is a better solution than mine, performance wise, as mine uses .closest('HYPE_scene') which is more work than .parentNode.

Is there a similar solution for getting the id of a group of elements in hype?

Could you elaborate a bit more about what you are trying to accomplish? Groups in Hype are divs that contain other elements. You can set the id directly in the identity inspector and then call hypeDocument.getElementById(‘id’) or you could add a class name and iterate up the parent chain (similar to the code I posted above) until you find that class.

Hi Stephen,

I’m having issues with this javascript code you posted.

When I attached this to an “on-click” action on an element inside a symbol, I get this code:

[Log] Object

continueTimelineNamed: function (a, b) {var c=h.V[a];c==l&&(c=h.W);b==g&&(b=0);Ac(c,1==b?k:p,k);}
currentDirectionForTimelineNamed: function (a) {a=h.V[a];a==l&&(a=h.W);return Z(a).$?1:0;}
currentTimeInTimelineNamed: function (a) {a=h.V[a];a==l&&(a=h.W);return bc(a,k);}
durationForTimelineNamed: function (a) {a=h.V[a];a==l&&(a=h.W);return L(Z(a));}
element: function () {return b;}
getSymbolInstancesByName: function (a) {a=Sf(a);for(var c=,d=0;d<a[N];d++)for(var f=a[d],e=fzb[Ua];e!=l;){if(e==b){cG;break}e=e[Ua]}return c;}
goToTimeInTimelineNamed: function (a, b) {var c=h.V[b];c==l&&(c=h.W);$b(a,c);}
isPlayingTimelineNamed: function (a) {a=h.V[a];a==l&&(a=h.W);return Z(a).ha;}
pauseTimelineNamed: function (a) {a=h.V[a];a==l&&(a=h.W);
startTimelineNamed: function (a, b) {var c=h.V[a];c==l&&(c=h.W);b==g&&(b=0);Zb(c,l,1==b?k:p);}
symbolName: function () {return h.n;}
proto: Object

Is any of the preceding the symbolInstance I can use to control that symbol?

Essentially what I am trying to do is have a button in a menu (Which is a persistent symbol) appear when the project reaches a certain score. I just can’t figure out how to control a single element in Javascript, within that symbol.

Any ideas?

Thanks!

Logan

Can you post your project. I can see that you get an object back which is what I think is expected, but it is a little unclear of how you are set up to control the element and which element you want to control

Ok. I think I realise what you want to do. The code Stephen supplied is really for getting the parent symbol of the element that triggered the function.

What you seem to need is to get an element within a symbol. And the function is triggered by an external action.

You need to give the symbol an id and then you can get the symbol using:

hypeDocument.getSymbolInstanceById('menuSymbol');

This example has a button that when clicked simulates a score . When the score reaches 4 the symbol menu button will appear.

showButtonIn Symbol.hype.zip (13.4 KB)

Note: the button is shown when the score is greater than or equal to 4.
Which means the timeline to show the button would keep firing on each new score after the score reaches and goes beyond 4.

I used a simple true/false check to stop that.
But depending on how you need it you can do similar in other ways. like set the timeline to a relative one instead of a absolute one. Which means that the time line will go to the end of the timeline from what ever position the button is already in. In an absolute on it would jump to the beginning position first and then work to the end.

The button in my example is also set to show instantly so you would not notice the repeat transition but that may not be what you want…

Hi Mark,

That’s exactly what I was looking for! Thank you for your solution!!

Best,

Logan

Hi Logan ( @lriley3 ),

Re: you question about localStoarge,I am posting this here as it may be helpful to others.

There is a simple Tutorial at developer.mozilla.org - Web_Storage_API

Which takes you through the concepts and usage of the localStorage API.

Also here is a example of basic usage of the API.

Some of the functions will call another function but this should be easy to see in the example of whats going on.
I have tried to make it so it is easy to follow and simple by making each task a separate function. But is is by no means robust.

Do read the API tutorial and you may want to google some more examples. There are many tutorials out there showing different ways and ideas of using storage, as well as which types of storage to use and why.

showButtonIn Symbol_saveScore.hypetemplate.zip (17.1 KB)

Hi Mark,

That example was exactly what I was looking for! It was very easy to understand! Thank you for taking the time to prepare that and send the link to the tutorial. Please let me know if there is anyway that I can return the favor!!

Best,

Logan

1 Like

I’m trying this without a mous-click (or any other user interaction), but from a timeline-action-javascript. So I need to get the symbolInstance id at the end of a timeline.
I’m already spending an hour looking at my screen, just can not figure it out…

I know I can get the element, hypedocument and event. It’s possible to get the name of the timeline, but I can’t get the childNode/ID from the symbolInstance which is running this timeline…

Hi @rene

Can you post the Project.?

I can't think of a way currently for you to get the symbol instance from a javascript action fired from a timeline action inside of a symbol.

However, this is a great idea so I have updated our runtime to include the SymbolInstance's element in the javascript callback. Look for it in the next Hype update.

When the next update comes out you will be able to do the following inside of a Timeline Action Run Javascript Action:

hypeDocument.getSymbolInstanceById(element.id)
3 Likes

If I understand right.

In the Symbols Custom behaviours, set a behaviour to fire the Javascript.
Name the behaviour the same name or id as the Symbol.

Set the Symbols timeline Action to fire the Custom behaviour.

Then in the Javascript you can use

Something like:

var theName  = event.customBehaviorName
var thisSymbol = hypeDocument.getSymbolInstancesByName(theName);

( I have used the name instead of the ID here )

That’s also a great way to do this, @MarkHunte thanks!
I was planning on a work-a-round: duplicating the timeline and name each duplicate after the id. It’s easy to get the id of a symbol when clicked and let it play the timeline with the name of the id. A simple script at the end of a timeline should get the name of the ended timeline.

@stephen that’s great!!! Many thanks!

Thanks, works like a charm!

Just what I was looking for! Having the symbolInstance inside of a symbol is necessary for every Javascript action that's triggered inside of Symbols. It is easier the determine the ID first… as the alternative is symbolInstance = hypeDocument.getSymbolInstanceById (element.parentNode.parentNode.id); and that is not very intuitive. And the depths of the parentNodes gets deeper for every group your element/button nested in.

It now is available as extension