Sources/com.elgato.pisamples.sdPlugin/index_pi.js
/** CREATE INTERACTIVE HTML-DOM
 * where elements can be clicked or act on their 'change' event.
 * Messages are then processed using the 'handleSdpiItemClick' method below.
 */
CREATE INTERACTIVE HTML-DOM
where elements can be clicked or act on their 'change' event.
Messages are then processed using the 'handleSdpiItemClick' method below.
CREATE INTERACTIVE HTML - DOM where elements can be clicked or act on their ' change ' event . Messages are then processed using the ' handleSdpiItemClick ' method below .
function prepareDOMElements(baseElement) {
    baseElement = baseElement || document;
    Array.from(baseElement.querySelectorAll('.sdpi-item-value')).forEach(
        (el, i) => {
            const elementsToClick = [
                'BUTTON',
                'OL',
                'UL',
                'TABLE',
                'METER',
                'PROGRESS',
                'CANVAS'
            ].includes(el.tagName);
            const evt = elementsToClick ? 'onclick' : onchangeevt || 'onchange';
            const inputGroup = el.querySelectorAll('input + span');
            if (inputGroup.length === 2) {
                const offs = inputGroup[0].tagName === 'INPUT' ? 1 : 0;
                inputGroup[offs].textContent = inputGroup[1 - offs].value;
                inputGroup[1 - offs]['oninput'] = function() {
                    inputGroup[offs].textContent = inputGroup[1 - offs].value;
                };
            }
            Array.from(el.querySelectorAll('.clickable')).forEach(
                (subel, subi) => {
                    subel['onclick'] = function(e) {
                        handleSdpiItemChange(e.target, subi);
                    };
                }
            );
            const cloneEvt = el[evt];
            el[evt] = function(e) {
                if (cloneEvt) cloneEvt();
                handleSdpiItemChange(e.target, i);
            };
        }
    );
    baseElement.querySelectorAll('textarea').forEach((e) => {
        const maxl = e.getAttribute('maxlength');
        e.targets = baseElement.querySelectorAll(`[for='${e.id}']`);
        if (e.targets.length) {
            let fn = () => {
                for (let x of e.targets) {
                    x.textContent = maxl ? `${e.value.length}/${maxl}` : `${e.value.length}`;
                }
            };
            fn();
            e.onkeyup = fn;
        }
    });
    baseElement.querySelectorAll('[data-open-url]').forEach(e => {
        const value = e.getAttribute('data-open-url');
        if (value) {
            e.onclick = () => {
                let path;
                if (value.indexOf('http') !== 0) {
                    path = document.location.href.split('/');
                    path.pop();
                    path.push(value.split('/').pop());
                    path = path.join('/');
                } else {
                    path = value;
                }
                $SD.api.openUrl($SD.uuid, path);
            };
        } else {
            console.log(`${value} is not a supported url`);
        }
    });
}
function prepareDOMElements ( baseElement ) { baseElement = baseElement || document ; Array . from ( baseElement . querySelectorAll ( '.sdpi-item-value' ) ) . forEach ( ( el , i ) => { const elementsToClick = [ 'BUTTON' , 'OL' , 'UL' , 'TABLE' , 'METER' , 'PROGRESS' , 'CANVAS' ] . includes ( el . tagName ) ; const evt = elementsToClick ? 'onclick' : onchangeevt || 'onchange' ; const inputGroup = el . querySelectorAll ( 'input + span' ) ; if ( inputGroup . length === 2 ) { const offs = inputGroup [ 0 ] . tagName === 'INPUT' ? 1 : 0 ; inputGroup [ offs ] . textContent = inputGroup [ 1 - offs ] . value ; inputGroup [ 1 - offs ] [ 'oninput' ] = function ( ) { inputGroup [ offs ] . textContent = inputGroup [ 1 - offs ] . value ; } ; } Array . from ( el . querySelectorAll ( '.clickable' ) ) . forEach ( ( subel , subi ) => { subel [ 'onclick' ] = function ( e ) { handleSdpiItemChange ( e . target , subi ) ; } ; } ) ; const cloneEvt = el [ evt ] ; el [ evt ] = function ( e ) { if ( cloneEvt ) cloneEvt ( ) ; handleSdpiItemChange ( e . target , i ) ; } ; } ) ; baseElement . querySelectorAll ( 'textarea' ) . forEach ( ( e ) => { const maxl = e . getAttribute ( 'maxlength' ) ; e . targets = baseElement . querySelectorAll ( ` ${ e . id } ` ) ; if ( e . targets . length ) { let fn = ( ) => { for ( let x of e . targets ) { x . textContent = maxl ? ` ${ e . value . length } ${ maxl } ` : ` ${ e . value . length } ` ; } } ; fn ( ) ; e . onkeyup = fn ; } } ) ; baseElement . querySelectorAll ( '[data-open-url]' ) . forEach ( e => { const value = e . getAttribute ( 'data-open-url' ) ; if ( value ) { e . onclick = ( ) => { let path ; if ( value . indexOf ( 'http' ) !== 0 ) { path = document . location . href . split ( '/' ) ; path . pop ( ) ; path . push ( value . split ( '/' ) . pop ( ) ) ; path = path . join ( '/' ) ; } else { path = value ; } $SD . api . openUrl ( $SD . uuid , path ) ; } ; } else { console . log ( ` ${ value } ` ) ; } } ) ; }
CREATE INTERACTIVE HTML-DOM
 where elements can be clicked or act on their 'change' event.
CREATE INTERACTIVE HTML - DOM where elements can be clicked or act on their ' change ' event .
/** Look for <input><span> combinations, where we consider the span as label for the input
             * we don't use `labels` for that, because a range could have 2 labels.
             */ /** We look for elements which have an 'clickable' attribute
             * we use these e.g. on an 'inputGroup' (<span><input type="range"><span>) to adjust the value of
             * the corresponding range-control
             */ /** Just in case the found HTML element already has an input or change - event attached, 
             * we clone it, and call it in the callback, right before the freshly attached event
            */ /**
     * You could add a 'label' to a textares, e.g. to show the number of charactes already typed
     * or contained in the textarea. This helper updates this label for you.
     */