0

I am writing a simple js tab in new ES6 code but i am a bit troubles with scope of variables and exporting class.

Here is my code

import $ from 'jquery';
import '../css/_style.scss';
import './mediaupload.js';
//
let i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
tablinks = document.getElementsByClassName("tablinks");
class SMDVadmin{
    openTab(evt, tabname){
        for (i = 0; i < tabcontent.length; i++) {
            tabcontent[i].style.display = "none";
        }
        for (i = 0; i < tablinks.length; i++) {
            tablinks[i].className = tablinks[i].className.replace(" active", "");
        }
        document.getElementById(tabname).style.display = "block";
        evt.currentTarget.className += " active";
    }
}
export default SMDVadmin;

and i am using the function openTab as

<ul>
   <li><a href="#" onClick="openTab(e, tab1)" id="th1">HOme</a></li>
   <li><a href="#" onClick="openTab(e, tab2)" id="th2">Address</a></li>
</ul>

But on clicking there is an error Uncaught ReferenceError: openTab is not defined

BUT, if i code like this,its working :) :

let i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
tablinks = document.getElementsByClassName("tablinks");

const openTab = (evt, tabname) => {
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(tabname).style.display = "block";
    evt.currentTarget.className += " active";
}

window.openTab = openTab;

But i have more other functions and I want them to keep in a class to maintain a integrity

Tick Twitch
  • 513
  • 10
  • 23
  • 1
    SMDVadmin.openTab() ? – Sean T Sep 24 '18 at 16:04
  • No, you don't want to use `class` if you don't want to construct instances. To keep them maintainable, putting them all in the same module (or object) is enough. – Bergi Sep 24 '18 at 16:07
  • First of all, stop declaring that `i` variable as a global. Declare it as local inside that function! – Bergi Sep 24 '18 at 16:07
  • [Don't use inline `onclick` attributes](https://stackoverflow.com/q/6941483/1048572). Also the `tab1` and `tab2` that you want to pass to the function should be string literals. – Bergi Sep 24 '18 at 16:08

1 Answers1

-1

You've effectively "namespaced" your openTab method by putting it in a class. You must create an instance of the class and then call the method on that instance.

var smdvAdmin = new SMDVadmin()

smdvAdmin.openTab()

Alternatively, you could make the method a static, thus not requiring a new instance:

class SMDVadmin{
    static openTab(evt, tabname){}
}

SMDVadmin.openTab()

You may not need the class at all if you are importing a single method from a file.

You could instead just export the method

const openTab = (evt, tabname) => {}

export default openTab;
Kevin Jantzer
  • 9,215
  • 2
  • 28
  • 52
  • Why the downvote? This properly addresses the OP's misunderstanding – Kevin Jantzer Sep 24 '18 at 16:14
  • I downvoted before you added "*You may not need the class at all …*" (which is the proper solution), but unfortunately the edit was during the grace period and my vote is now locked. – Bergi Sep 24 '18 at 16:22
  • I would disagree that it is the "proper" solution. The OP states: "I have more other functions and I want them to keep in a class" – so explaining to them how they can use their method from the class is not worth a downvote. – Kevin Jantzer Sep 24 '18 at 18:21
  • No, but keeping plain functions (that are no instance methods) in a `class` is wrong. – Bergi Sep 24 '18 at 18:33