How to call function described in the module by clicking on button?

Tags: , ,



I’m working on creating pizzeria site. I decided to create id as SPA with fixed navigation. To simplificy my code I created it in modules and now I have a big problem with them. How I can link module function to button in headers, because it throws an error. Here I posted my code to demonstate the error. To fix it I tried to move parts of the code and generate that error.

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>
            Mafia pizza
        </title>
       <link href="./css/styles.css" rel="stylesheet">
    </head>
    <body>
        <header>
        <button id="mainBtn" onclick="jump('')">
            Main
        </button>
        <button id="allBtn" onclick="jump('#all')">
            Catalogue
        </button>
        <button id="pizzaBtn" onclick="jump('#pizza')">
            Pizza
        </button>
        <button id="sushiBtn" onclick="jump('#sushi')">
            Sushi 
        </button>
        <button id="drinkBtn" onclick="jump('#drinks')">
            Drinks
        </button>
        
        <button id="cartBtn" style="float:right;" onclick="jump('#cart')">
            In the cart: <span id="amount">0</span>
        </button>

        </header>

        <!-- CLASS WITH CODE -->
        
        <div id="content" class="content" style="width: 100%; height: 100%;">

            
        </div>
        <!-- CLASS WITH CODE. AFTER WRITING TO MOVE TO A JS FILE -->

        <script type="module">
            import { routes } from './js/getpage.js';
            import { generatePromo,generateItems } from './js/functions.js';

            async function router(){
                let link = window.location.href;
                let buttonList = document.querySelectorAll('header button');
                for(let i=0;i<buttonList.length;i++){
                    buttonList[i].style.backgroundColor = 'darkorange';
                }

                if(link.indexOf('#')==-1)link = 'main';
                else
                    link = link.substring(link.indexOf('#'));
                console.log(link);
                switch(link){
                    case 'sushi':
                        document.getElementById('sushiBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['sushi'];
                        document.getElementById('goodsField').innerHTML = await generateItems('sushi');
                        break;
                    case 'pizza':
                        document.getElementById('pizzaBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['pizza'];
                        document.getElementById('goodsField').innerHTML = await generateItems('pizza');
                        break;
                    case 'drinks':
                        document.getElementById('drinkBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['drinks'];
                        document.getElementById('goodsField').innerHTML = await generateItems('drinks');
                        break;
                    case 'cart':
                        document.getElementById('cartBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['cart'];
                        break;
                    case 'all':
                        document.getElementById('allBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['all'];
                        break;
                    default:
                        document.getElementById('mainBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['main'];
                        let ls = await generateItems('recommended');
                        document.getElementById('goodsField').innerHTML = ls;
                        generatePromo();
                        document.getElementById("prevbutton").style.display = 'inline';
                        document.getElementById("nextbutton").style.display = 'inline';
                        break;
                }
            }

            function jump(path){
                window.location.href = "https://valerydrozd.github.io/"+path;
                router();
            }
            window.onload = router();
        </script>
        <script type="text/javascript" src='./js/slider.js'></script>
        <script type="text/javascript" src='./js/buy.js'></script>
        <footer class="foot">
            
        </footer>
    </body>
</html>

Answer

Since your script comes after the html, your jump function wont be defined when the html is rendered.

You could add an event handler to all those elements and a data attribute that contains the path. Then modify you jump function like so

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>
            Mafia pizza
        </title>
       <link href="./css/styles.css" rel="stylesheet">
    </head>
    <body>
        <header>
        <button id="mainBtn" class="nav" data-path=""> 
            Main
        </button>
        <button id="allBtn" class="nav" data-path="#all">
            Catalogue
        </button>
        <button id="pizzaBtn" class="nav" data-path="#pizza">
            Pizza
        </button>
        <button id="sushiBtn" class="nav" data-path="#sushi">
            Sushi 
        </button>
        <button id="drinkBtn" class="nav" data-path="#drinks">
            Drinks
        </button>
        
        <button id="cartBtn" style="float:right;" onclick="jump('#cart')">
            In the cart: <span id="amount">0</span>
        </button>

        </header>

        <!-- CLASS WITH CODE -->
        
        <div id="content" class="content" style="width: 100%; height: 100%;">

            
        </div>
        <!-- CLASS WITH CODE. AFTER WRITING TO MOVE TO A JS FILE -->

        <script type="module">
            import { routes } from './js/getpage.js';
            import { generatePromo,generateItems } from './js/functions.js';
            // query all elements with `nav` class.
            // add event listener to each element.
            docuemnt.querySelectorAll('.nav').forEach(el => {
              el.addEventListener('click', jump)
            })
            async function router(){
                let link = window.location.href;
                let buttonList = document.querySelectorAll('header button');
                for(let i=0;i<buttonList.length;i++){
                    buttonList[i].style.backgroundColor = 'darkorange';
                }

                if(link.indexOf('#')==-1)link = 'main';
                else
                    link = link.substring(link.indexOf('#'));
                console.log(link);
                switch(link){
                    case 'sushi':
                        document.getElementById('sushiBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['sushi'];
                        document.getElementById('goodsField').innerHTML = await generateItems('sushi');
                        break;
                    case 'pizza':
                        document.getElementById('pizzaBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['pizza'];
                        document.getElementById('goodsField').innerHTML = await generateItems('pizza');
                        break;
                    case 'drinks':
                        document.getElementById('drinkBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['drinks'];
                        document.getElementById('goodsField').innerHTML = await generateItems('drinks');
                        break;
                    case 'cart':
                        document.getElementById('cartBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['cart'];
                        break;
                    case 'all':
                        document.getElementById('allBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['all'];
                        break;
                    default:
                        document.getElementById('mainBtn').style.backgroundColor = '#F9E79F';
                        document.getElementById('content').innerHTML = routes['main'];
                        let ls = await generateItems('recommended');
                        document.getElementById('goodsField').innerHTML = ls;
                        generatePromo();
                        document.getElementById("prevbutton").style.display = 'inline';
                        document.getElementById("nextbutton").style.display = 'inline';
                        break;
                }
            }

            function jump(){
                const path = this.getAttribute('data-path')
                window.location.href = "https://valerydrozd.github.io/"+path;
                router();
            }
            window.onload = router();
        </script>
        <script type="text/javascript" src='./js/slider.js'></script>
        <script type="text/javascript" src='./js/buy.js'></script>
        <footer class="foot">
            
        </footer>
    </body>
</html>


Source: stackoverflow