Viewing 15 posts - 1 through 15 (of 15 total)
  • Author
    Posts
  • #318103 Score: 2
    Profile photo of Math Notermans
    Math Notermans
    Member
    contributor
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    LUC16 Attendee
    LUC16
    wise owl
    curious george
    109 pts
    @mnotermans5114

    Because i want to make my scripts and awts as reusable as possible, i always been struggling with the fact that Lectora recreates htmlnames when copying and pasting elements. Even when you make library objects of them htmlnames get recreated and are unique.

    Thus making easy reusable snippets and awts tough when javascript is used to target elements on the page.
    Previously i either scanned the complete page…got all assets into arrays and then with the use of indexnumbers targeted whatever i needed. A way to tackle it, but surely not ideal.

    Another solution i used is setting unique classes to elements, then you can target any element you need/want ..but still this isnt ideally, because either you have to name each element uniquely or you need to get a specific element from the array or list of classes in Javascript.

    Well on LUC16 in the ‘Extending Lectora with Scripting’ course, John showed a method that opens new possibilities to target specific elements.

    Token Replacement!

    Inside Lectora you can use %HTMLNAME% to get the htmlname of a specific object.

    – Add a Run Javascript action to any object
    – code in the JS is: alert(%HTMLNAME%)

    When you run it now you get a message saying: [object Object]
    This is because this is a Javascript Object with a lot of properties like name, x, y and many many more… if you want to know all properties available change your code into:
    obj=%HTMLNAME%
    for (var key in obj){
    if(obj.hasOwnProperty(key)){
    alert(key);
    }
    }

    With this code you see all properties available within this object. A lot… 🙂

    Offcourse you allready noticed name when running the code above.
    So to see the htmlname of your element ( i used images ) you run this code:
    alert(%HTMLNAME%.name);

    Ok thats fine when you code inside Lectora. I however prefer to have most of my Javascript in an external Javascript file. Untill today i ran into trouble trying to access the htmlname with token replacement in my external javascript. Found a solution to that however.

    – add a variable to your title. Mine is CurrentHTMLObj
    – make sure its used on the page. I do by adding an action OnPageShow -> Modify Variable -> Set Equal To -> test- on the object you want to get the hmtlName from…an image for me.. add an action MouseClick -> Run Javascript
    – the code is: VarCurrentHTMLObj.set(%HTMLNAME%.name);
    – and then in my external JS-file i get that variable. VarCurrentHTMLObj.getValue();

    So now i can add this to any element in Lectora..Pass my actual htmlName to my Javascript… dont have to be afraid for copying/pasting and no need to change the code afterwards. Great bonus for creating reusable elements !!!!

    This post has received 2 votes up.
    #318104 Score: 0
    Profile photo of Darrel Somoza
    Darrel Somoza
    Member
    contributor
    friend finder
    beginner
    intermediate
    junior moderator
    advanced
    wise owl
    curious george
    profile
    192 pts
    @Klaatu

    What exactly are you trying to accomplish? Please upload an example.

    #318105 Score: 0
    Profile photo of Peter Jackson
    Peter Jackson
    Member
    beginner
    intermediate
    advanced
    friend finder
    contributor
    junior moderator
    wise owl
    group mod
    entry
    winner
    17 pts
    @pjackson2462

    All you need to do is assign a unique class name to a given object and then use the following:

    
    function findObjectByClassName(objClassName){
    var ocName = objClassName.toLowerCase();
    var divs = document.getElementsByTagName("div");
    for(var i=0;i<divs.length;i++){
    var cName = divs[i].className;
    if(cName!=''){
    var cNames = cName.split(' ');
    for(var j=0;j<cNames.length;j++){
    if(cNames[j].toLowerCase()==ocName){
    var domObj = divs[i];
    var jsObj = eval(domObj.id);
    jsObj.domObj = domObj;
    return jsObj;
    }
    }
    }
    }
    return '';
    }
    

    HTH

    Regards, Peter

     

    #318109 Score: 0
    Profile photo of Math Notermans
    Math Notermans
    Member
    contributor
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    LUC16 Attendee
    LUC16
    wise owl
    curious george
    109 pts
    @mnotermans5114

    @ Darrel…will upload a sample tomorrow or so…
    @ Peter… yep, that is one of the methods i used before..and it works…only downside is as i allready mentioned in my post, you have to give an element a class in Lectora. And getting elements by classname returns a list or array… so you have to parse those too. When i post a sample..benefits will be clearer.

    #318110 Score: 0
    Profile photo of Sergey Snegirev
    Sergey Snegirev
    Member
    contributor
    intermediate
    advanced
    friend finder
    lab member
    junior moderator
    advocate
    LUC16
    LUC16 Attendee
    wise owl
    334 pts
    @ssneg

    Thanks for sharing, I did not know about %HTMLNAME% shorthand. Very useful.

    @pjackson2462, with all due respect, this is a convoluted way of replicating JavaScript’s native getElementsByClassName() function. Instead of basically all this code, you could just write literally one line of code:

    var domObj = getElementsByClassName(objClassName)[0]

    #318112 Score: 0
    Profile photo of Math Notermans
    Math Notermans
    Member
    contributor
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    LUC16 Attendee
    LUC16
    wise owl
    curious george
    109 pts
    @mnotermans5114

    And getElementsByClassName returns a list/array… Even with just a single specific classed element in Lectora… Thus needing the [0]   Thats why %HTMLNAME% can be usefull…

    #318113 Score: 0
    Profile photo of Sergey Snegirev
    Sergey Snegirev
    Member
    contributor
    intermediate
    advanced
    friend finder
    lab member
    junior moderator
    advocate
    LUC16
    LUC16 Attendee
    wise owl
    334 pts
    @ssneg

    @mnotermans5114 It returns a HTMLCollection, not an array. It is an array-like type but it is much better. For example, it gets updated live when DOM changes.

    #318121 Score: 0
    Profile photo of Math Notermans
    Math Notermans
    Member
    contributor
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    LUC16 Attendee
    LUC16
    wise owl
    curious george
    109 pts
    @mnotermans5114

    Didnot know about HTMLCollection and live updates Sergey 🙂 Like this we learn something new each day. One thing i do love about this forum! Thx 😀

    #318126 Score: 0
    Profile photo of Math Notermans
    Math Notermans
    Member
    contributor
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    LUC16 Attendee
    LUC16
    wise owl
    curious george
    109 pts
    @mnotermans5114

    Added a sample of Token Replacement and Non-centered scaling here:
    https://community.trivantis.com/shared-content/scaling-tricks-and-token-replacement/

    @klaatu
    Couldnot resist making this a sample of both scaling and token replacement 😉

    @pjackson2462
    Token replacement helps with selecting elements clicked, but you cannot target elements not clicked.(or at least i didnot find how yet)
    So for that you need other selectors. getElementById or getElementsByClassName are options for that.

    #318160 Score: 0
    Profile photo of Darrel Somoza
    Darrel Somoza
    Member
    contributor
    friend finder
    beginner
    intermediate
    junior moderator
    advanced
    wise owl
    curious george
    profile
    192 pts
    @Klaatu

    I’m still not seeing where this is necessary. By ‘necessary’ I mean it does something you can’t do otherwise. I’ve looked over Math’s firstpage script. I’m sure it’s me and I’m probably missing out on something good that’s right in front of my face. Please, I’m hoping one of you will take the time to explain it in simpler terms so that it is clearer to me.

    In case you are not aware, using the “name” attribute on img tags was deprecated in HTML4.01 and is obsolete in HTML5. While it may still work for a while, it is not recommended to use. W3C, MDN.

    Math, why do you use the ‘Meta tags’ html extension for script linking over “Header Scripting” or “Bottom of file scripting”? In production, I do not suggest it because, among other reasons, it puts them before the CSS in the head.

    #318161 Score: 0
    Profile photo of Math Notermans
    Math Notermans
    Member
    contributor
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    LUC16 Attendee
    LUC16
    wise owl
    curious george
    109 pts
    @mnotermans5114

    Basically what im trying to achieve…. apart from Meta tags vs Header and name attr. is an easy way for non-javascript developers to achieve javascript/gsap effects in Lectora by simply inserting/copying pasting elements.

    Should not be needed to check/change htmlnames or do anything in javascript besides some simple functioncalls.

    There comes the Token Replacement in function..if i can manage to get it working on other elements too..trying with onShow … then Javascript enabled elements and parts can be fully self-sufficient without any need for changing code for someone who reuses it.

    #318194 Score: 1
    Profile photo of Tim K
    Tim K
    Member
    contributor
    beginner
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    wise owl
    curious george
    Group Member
    255 pts
    @timk

    Thanks for sharing. I’ve played around with it a little:

    %HTMLNAME% seems to always refer to the object an action is added to, no matter which trigger this action uses. It can be used to get several properties of the object:

    %HTMLNAME%.name = html name of the object = id of the div
    %HTMLNAME%.w = %WIDTH% = width of the div
    %HTMLNAME%.h = %HEIGHT% = height of the div
    %HTMLNAME%.x = x-position of the div
    %HTMLNAME%.y = y-position of the div

    There’s more information available.

    You can get the same information for any object:

    text123.w = width of the div with the html name / id “text123”.

    Tim

    This post has received 1 vote up.
    #318206 Score: 0
    Profile photo of Math Notermans
    Math Notermans
    Member
    contributor
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    LUC16 Attendee
    LUC16
    wise owl
    curious george
    109 pts
    @mnotermans5114

    As Tim mentions, it is indeed related to the object %HTMLNAME% is added too. Couldnot target it in any way from outside Lectora ( external Javascript ) ..only from within Lectora.. ( http://trivantis.com/help/Lectora/16/ENG/Lectora_Help/Content/5565.html )
    Option to get access from outside is setting a variable and accessing that from outside, like in my sample.

    Experiment im doing now ( well yesterday evening ) is adding a OnShow action with %HTMLNAME% to several objects on a page, and then in the external JS dynamically create a variable for the passed HTMLNAMES so that i can access any object without ever need to know its HTMLNAME, thus making things really good reusable.

    #383331 Score: 0
    Profile photo of CarlFink
    CarlFink
    Member
    beginner
    intermediate
    contributor
    LUC16 Attendee
    wise owl
    curious george
    advanced
    13 pts
    @CarlFink

    Coming in very late, but this is highly relevant to what I’m trying to do now.

    I asked a question recently about questions: Multiple choice/select questions: scripted access to CURRENT order on page? Apparently there’s no direct support in Lectora for this. I therefore need to script around the gap.

    Could I put a Token Substitution snippet on each of the Choice nn text objects adding some unique string to their HTMLnames, say “choice”, and then in JavaScript parse the list of DOM objects on the page to get an array (or better structure?) of pointers to the labels for each question choice? Or would it be simpler to just manually name each choice label from the Lectora developer interface, for every question in every quiz?

    My final goal is to then sort the choice labels by Y position and be able to play audio clips reading each one aloud, in order by vertical position. The audio clips would be linked to each question choice and also would play if the item is clicked. (I would thus override the default behavior of selecting the appropriate radio button/checkbox when the label is clicked.)

    Thoughts?

    #383634 Score: 0
    Profile photo of Math Notermans
    Math Notermans
    Member
    contributor
    intermediate
    advanced
    friend finder
    junior moderator
    advocate
    LUC16 Attendee
    LUC16
    wise owl
    curious george
    109 pts
    @mnotermans5114

    @carlfink … i am not quite sure what you want to achieve…but any element in a Lectora.awt is accessible by Javascript externally. The order of elements is decided by the order a developer places them in a view. Actually the title explorer has the exact same order. At some point i made a setup ( Lectora 16 ) that reads any element on screen and adds them into arrays for animation.

    Reusable OOP setup in Lectora


    I do think the order in the array is the order of the element.

    If you add a sample of what your planning to achieve, i gladly jump onto it.

    Kind regards,
    Math

    PS. this sample is old… keep that in mind 😉

Viewing 15 posts - 1 through 15 (of 15 total)

You must be logged in to reply to this topic.