Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript custom element's oninput function issue

Tags:

javascript

Say, I need to call a function in a custom element, such that when a slider moves in that element the text gets updated(only for that element). The main.js file,

class OninputClassDemo extends HTMLElement {
    constructor(){
        super();

        const shadow = this.attachShadow({mode:'open'});

        this.parent = document.createElement('div');

        this.slider = document.createElement('input');
        this.slider.setAttribute('type','range');
        this.slider.setAttribute('min','0');
        this.slider.setAttribute('max','99');
        this.slider.setAttribute('value','0')

        this.text = document.createElement('input');
        this.text.setAttribute('type','text');
        this.text.setAttribute('value','');

        this.parent.appendChild(this.slider);
        this.parent.appendChild(this.text);
        shadow.appendChild(this.parent);        

        this.slider.setAttribute('oninput','OninputClassDemo.changeValue()');

    }

    changeValue = function(){
        this.text.setAttribute('value',this.slider.getAttribute('value'));
    }
}

window.customElements.define('demo-element',OninputClassDemo);

On the template side,

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="main.js"></script>
</head>
<body>
    <demo-element></demo-element>
</body>
</html>

The error I am getting is,

OninputClassDemo.changeValue is not a function
    at HTMLInputElement.oninput

I do not know how to reference the method for that particular object in this.slider.setAttribute('oninput','WhatShouldIPutHere'),so that the text box for only that object gets changed.

like image 543
REVOLUTION Avatar asked May 15 '20 11:05

REVOLUTION


1 Answers

You should be binding event listeners with addEventListener. You should be binding to the method with this, not the class name. Set the value property, do not set an attribute.

class OninputClassDemo extends HTMLElement {
  constructor() {
    super();

    const shadow = this.attachShadow({
      mode: 'open'
    });

    this.parent = document.createElement('div');

    this.slider = document.createElement('input');
    this.slider.setAttribute('type', 'range');
    this.slider.setAttribute('min', '0');
    this.slider.setAttribute('max', '99');
    this.slider.setAttribute('value', '0')

    this.text = document.createElement('input');
    this.text.setAttribute('type', 'text');
    this.text.setAttribute('value', '');

    this.parent.appendChild(this.slider);
    this.parent.appendChild(this.text);
    shadow.appendChild(this.parent);

    this.slider.addEventListener('input', (event) => this.changeValue());

  }

  changeValue() {
    this.text.value = this.slider.value;
  }
}

window.customElements.define('demo-element', OninputClassDemo);
<demo-element></demo-element>
like image 90
epascarello Avatar answered Nov 19 '22 23:11

epascarello