Home > front end >  Why can't I access javascript function from HTML file?
Why can't I access javascript function from HTML file?

Time:11-20

Fairly basic question here. I've run into a situation where I can't seem to access Javascript functions from within my HTML file, even though I've linked the JS file as a script src. It seems like a pretty simple issue but I can't figure out what the problem is.

I'm trying to add a function called startLogin to an HTML button. I added it as an onclick, but then when I try to click the button, the console says the function is undefined. However the function is clearly defined in the JS file and as far as I can tell the syntax I'm using for the onclick and the script src link is correct.

In addition I've confirmed that the JS file is linked to the HTML file. If I try to manipulate the DOM from the JS file just to do something simple, like set the background to red, that works fine. The problem is when I try to call a function defined in the JS file. Also I've made sure the function I'm trying to call does actually work. If I stick it right in the HTML file inside script tags, it works fine.

I've already tried moving the script tags inside the body at the end of the HTML, as I know that's often the issue, but in this case it didn't work. Can anyone help me identify why I'm unable to access the "startLogin" function from the HTML button?

FYI, this is a javascript project and I'm using Vite.js for bundling. All the other HTML/JS files in my project are playing nicely together, I'm only having an issue with the Login page.

file structure:

|-pages
  |-login.html
  |-login.js

login.html

 <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial- 
    scale=1.0" />
    <title>Document</title>

    <!-- LINK JS FILE -->
    <!-- MODULE TYPE IS RELATED TO VITE.JS -->
    <script type="module" src="./login.js"></script>

  </head>

  <body>
    <!-- email login form -->
    <form name="emailLogin" id="emailLogin" style="display: none">
      <div class="row" style="width: 600px">
        <div class="col">
          <div class="form-row" style="padding-bottom: 10px">
            <input
              type="email"
              class="form-control"
              id="emailAddress"
              placeholder="email associated with your login"
              style="width: 576px"
            />
          </div>
        </div>
        <div class="form-row">
          <br />
          <button type="button" class="btn btn-primary" onclick="startLogin('email')">
            Send Email Login
          </button>
        </div>
      </div>
    </form>
  </body>
</html>

login.js

// start the login process by generating a code sent either SMS or EMAIL
      function startLogin(login_type) {

        // local variables
        var ajaxResult;
        var subs;
        var tempString;

        // get the login values and set up the call
        if (login_type == "phone") {
          // get the values
          use_country_code = $("#country").val();
          use_phone = $("#phoneNumber").val();
          use_phone = use_phone.replace(/\D/g, "");

          // do the validation
          if (use_phone.length < 10) {
            $("#errorText").html(
              "Phone number doesn't have enough digits, please try again."
            );
            $("#errorModal").modal("show");
            return;
          }

          // build the url
          post_url =
            "https://us-central1-dev-api-327415.cloudfunctions.net/user-login?cc="  
            use_country_code  
            "&phone="  
            use_phone;
        } else {
          // get the values
          use_email = $("#emailAddress").val();

          // do the validation
          if (!validateEmail(use_email)) {
            $("#errorText").html(
              "Email address does not appear to be valid, please check the format and try again."
            );
            $("#errorModal").modal("show");
            return;
          }

          // build the url
          post_url =
            "https://us-central1-dev-api-327415.cloudfunctions.net/user-login?email="  
            use_email;
        }

        // send the request to the server and process the results
        $.LoadingOverlay("show");
        $.ajax({
          type: "POST",
          url: post_url,

          // process the returned result of the Ajax call
          success: function (ajaxResult) {
            // see if we have a session token and handle the response
            session_token = ajaxResult["session_token"];
            if (session_token == "None") {
              // hide the login and show the text message area if phone, otherwise hide email and show email message
              if (login_type == "phone") {
                $("#loginMethod").hide();
                $("#phoneLogin").hide();
                $("#codeLogin").show();
                $("#loginMessage").hide();
                $("#textMessage").show();
              } else {
                $("#loginMethod").hide();
                $("#emailLogin").hide();
                $("#loginMessage").hide();
                $("#codeLogin").show();
                $("#emailMessage").show();
              }
            } else {
              // hide everything since already logged in and show the right message
              $("#phoneLogin").hide();
              $("#emailLogin").hide();
              $("#loginMethod").hide();
              $("#loginMessage").hide();
              $("#codeLogin").hide();
              $("#continueLoginAlready").show();
            }
          },

          // process after the Ajax call has been fully completed
          complete: function () {
            $.LoadingOverlay("hide");
          },

          // handle total failure
          error: function (jqXHR, exception) {
            console.log(jqXHR);
            console.log(exception);
            json_error = jqXHR["responseJSON"];
            $("#errorText").html(json_error.error_message);
            $("#errorModal").modal("show");
          },
        });
      }

CodePudding user response:

Javascript modules work a bit differently. There, variables and functions are not exposed to the global scope.

If you want to use your function from other parts of the code, you have to set it explicitly on the window object:

function startLogin(...) {
...
}
window.startLogin = startLogin;

CodePudding user response:

an other solution is to set the js at end of the html, than you don't need to use the window object (memory lag)

<html lang="en">
  <head>...</head>
  <body>
    <button type="button" id="myButton">Title</button>
  </body>
  <script>

    function myFunction(){
      console.log('running myFunction');
    }

    const button = document.querySelector('#myButton');
    
    button.addEventListener('click', function clickListener(
    {
      myFunction();
    }
  </script>
</html>

the browser is simply stupid, it loads the page from top to bottom and if you load your js after the body all your html is present and you can do it this way.

  • Related