Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functionality enhancements of with JavaScript #15

Open
GilShalit opened this issue Jul 10, 2022 · 0 comments
Open

Functionality enhancements of with JavaScript #15

GilShalit opened this issue Jul 10, 2022 · 0 comments

Comments

@GilShalit
Copy link

GilShalit commented Jul 10, 2022

Title

Functionality enhancements with JavaScript

Category

Maybe under Webcomponents?

Problem

Sometimes a webcomponent lacks a behavior or there is a need to change standard functionality. the documentation for webcomponents lists events they emit and it is possible to hook into those events to change or enhance the application.

Solution

General Steps
  • Add a js (JavaScript) file to the /resources/scripts collection of your project. I call mine events.js.
  • Include the file in your template with: <script type="text/javascript" src="resources/scripts/events.js"/> - it is usually a good idea to have this statement last in the HTML header.
  • Find the event you want to hook into and subscribe to it by writing the following in your script file:
document.addEventListener("event-name", (event)=> {
    // specific code
});
  • Use event.detail to accept the information passed by the event such as a key, id or status. See examples below. It is sometimes difficult to anticipate how the information you need will be included in event.detail, so it is useful to place a breakpoint in the listener, trigger the event in the UI and examine event.detail's members to see how the parameters are included.
  • Always test that what you will be using is not null, to avoid the listener generating an error you will not immediately see. So to read an id from the event, use:
document.addEventListener("event-name", (event)=> {
    if (event.detail && event.detail.id)
    {
        // specific code
    }
});
  • Another general point is that webcomponents generally render their output under a shadow-root, to encapsulate its behavior from the rest of the page. This means that to locate an element generated by a webcomponent, using its id (or key or other attribute) requires searching inside the shadow-root. For example, to search for all the images generated by a pb-facsimile component with an id="facsimile", use:
let shadow=document.getElementById("facsimile").shadowRoot;
let images=shadow.querySelectorAll('img');
Example

The following example includes several of these techniques. It can be seen in action in the TraveLab application.

The Benjamin of Tudela page has three versions of this traveler's log in English, Hebrew and Arabic. In the TEI-XML file, each narrative is built from tei:seg elements, grouped in tei:ab elements. The three versions are presented in three pb-view components, each showing one tei:ab element at a time. The segments of the different versions are modeled as pb-highlight webcomponents, and these are synchronized any time the mouse hovers over any pb-highlight, using the following method.

Concurrent pb-highlight components in all three versions have identical key values. This is used to synchronize them with the following listener to the pb-highlight-on event fired by the pb-highlight component when activated (through a hover action by default). See comments in the code.

document.addEventListener("pb-highlight-on", (event)=> {
    if (event.detail && event.detail.id && event.detail.source){  

        //the key is actually returned by id...
        let key=event.detail.id; 

        //Select the pb-views with the three versions
        let pbViews=document.querySelectorAll('pb-view[append-footnotes="append-footnotes"]'); 

        //loop through those pb-views
        pbViews.forEach(view => { 

            //in each version, find the corresponding pb-highlight
            let element=view.shadowRoot.querySelector('pb-highlight[key=' + key + ']'); 

            //only progress if corresponding element is found and only bring into view if not the element firing this event
            if (element && event.detail.source.id != element.id) 

                // bring corresponding elements to center of pb-view
                element.scrollIntoView({block: 'center' }); 
        });
    }
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant