Search code examples
javascriptcustom-component

passing parameter/input data to custom elements in javascript


I'm trying to implement the same code of this using JavaScript, so wrote the below code as btn.js file:

// Create a new object based of the HTMLElement prototype
var SaveBtn = Object.create(HTMLElement.prototype);

// Set up the element.
SaveBtn.createdCallback = function() {
// Create a Shadow Root
var shadow = this.createShadowRoot();
this.type='button';

// Add an event listener to the image.
this.addEventListener('click', function(e) {
    alert('got a click');
    document.getElementById("ShowButton").value= "Hide Filter";
 });
};

// Register the new element.
var Xbtn =document.registerElement('save-button', {
prototype: SaveBtn,
extends: 'input'
});

and called it in the other function main.js as below:

window.addEventListener("load", onLoad, false);

 function onLoad() {
     var host = document.querySelector('#host');
     var el = new Xbtn();
     host.appendChild(el);
 }

this worked fine, and gave me blanket button.

now I want to pass the 'text' to be displayed into the button, I tried the below:

in the index.html I've:

  <div id="host"></div>

 <input  id="ShowButton" type="button" value="Show Filter"/>

in main.js:

el.value = 'click me';

and in the btn.js:

this.value = this.getAttribute('text');

but failed, and the button still empty! considering that the other button value is changed upon the click

any thought?


Solution

  • The shadow DOM root is only accessible within the function-scope it is defined. You either need to assign the shadow DOM root object to an outer-scope variable, or you need to expose an in-scope function that manipulates the shadow DOM. Since you want to manipulate the shadow DOM for multiple elements, a setter function on each instance is the best option.

    You can expose the shadow DOM entirely:

    SaveBtn.createdCallback = function() {
        var shadow = this.createShadowRoot();
        this.myShadow = shadow;
        //...
    }
    
    ...
    
    el.myShadow.textContent = "click me";
    

    However, since a major feature of the shadow DOM is being able to hide DOM components from manipulation by other scripts, you may instead wish to have a setter function that (for example) validates input and performs the manipulation internally:

    SaveBtn.createdCallback = function() {
        var shadow = this.createShadowRoot();
    
        this.setShadowText = function(text) {
            shadow.textContent = text;
        }
        //...
    }
    
    ...
    
    el.setShadowText("click me");