lab-antwerp-1 / home

https://lab-antwerp-1.github.io/home/randomizer
MIT License
3 stars 13 forks source link

Is it possible to reach HTML elements which are created with JS functions? #289

Open omerjava opened 2 years ago

omerjava commented 2 years ago

Regarding code below: When clicked registerBtn, with handlerRegister() a form is created by using template literals. This form asks username, password and birthday info for registration. When submitted, info should be sent to data file. I tried to achieve that with another listener and handler. But, it didn't work. As far as I understand, it doesn't work because it can't reach to the ID (submitBtn) of Submit button which is created with handlerRegister(). I solved this problem later with creating all HTML form elements in index.html and modifying style.display property in JS. But, I want to learn whether it is possible to reach and manipulate HTML elements which are created with JS function as below. And secondly, even if it is possible, is it good practice?

const handlerRegister = () => {

    const parentElement = document.getElementById("displayScreen");

    parentElement.innerHTML=`<div class="registerContainer"><h2>Registration</h2>
    <p>Enter your information please</p>
    <form action="">
        <label for="username">Username:</label><br>
        <input type="text" id="username" name="username"><br>
        <label for="pwd">Password:</label><br>
        <input type="password" id="password" name="password"><br>
        <label for="passwordConfirm">Confirm Password:</label><br>
        <input type="password" id="passwordConfirm" name="passwordConfirm"><br>
        <label for="birthday">Birthday:</label><br>
        <input type="text" id="birthday" name="birthday" placeholder="12/10/1996"><br><br>
        <input type="submit" id="submitBtn" value="Submit">
    </form></div> `;

};

document.getElementById("registerBtn").addEventListener("click", handlerRegister);

const handlerSubmit = () => {
    const usernameData = document.getElementById("username").value;
    const passwordData = document.getElementById("password").value;
    const birthdayData = document.getElementById("birthday").value;
    data.users.push({username:usernameData,password:passwordData,birthday:birthdayData});

    document.getElementById("displayScreen").innerHTML=`<div class="registerContainer"><h2>Greetings!</h2>
                                            <p>You can login now with your account information.</p></div> `;
};

document.getElementById("submitBtn").addEventListener("click", handlerSubmit); 
CovertGravy commented 2 years ago

image

this is working because I added the event listener after the form is created.

omerjava commented 2 years ago

Thanks @CovertGravy for your comments! When you put second listener inside the first handler function, it recognize ID of submit button and start to work, but second handler (submitHandler) doesn't work properly because it can't reach to IDs of "username", "password", "birthday" and can't get/send these info to data object. When you run index.html (below) -> click Register button -> fill form and send -> then when you check console it says Form submission canceled because the form is not connected. I put all html and js code in a single file below:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="./client/public/favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
  </head>
  <body>
    <div id="root">
      <div id="login">
        <input type="button" id="registerBtn" value="Register" />
        <input type="button" value="Login" />
        <input type="button" value="Logout" />
      </div>
      <div class="registerForm" id="displayScreen"></div>

    </div>

    <script>
    const data = {
        words: [],
        sort: "oldest",
        loginStatus: false,
        users: [{username: "john", password: "1234ret", birthday: "12/10/1989"}]
    };

    alert("hello");

    const handlerRegister = () => {

        const parentElement = document.getElementById("displayScreen");

        parentElement.innerHTML=`<div class="registerContainer"><h2>Registration</h2>
                                <p>Enter your information please</p>
                                <form action="">
                                    <label for="username">Username:</label><br>
                                    <input type="text" id="username" name="username"><br>
                                    <label for="pwd">Password:</label><br>
                                    <input type="password" id="password" name="password"><br>
                                    <label for="passwordConfirm">Confirm Password:</label><br>
                                    <input type="password" id="passwordConfirm" name="passwordConfirm"><br>
                                    <label for="birthday">Birthday:</label><br>
                                    <input type="text" id="birthday" name="birthday" placeholder="12/10/1996"><br><br>
                                    <input type="submit" id="submitBtn" value="Submit">
                                </form></div> `;
        document.getElementById("submitBtn").addEventListener("click", handlerSubmit);

    }

    document.getElementById("registerBtn").addEventListener("click", handlerRegister);

    const handlerSubmit = () => {

        const usernameData = document.getElementById("username").value;
        const passwordData = document.getElementById("password").value;
        const birthdayData = document.getElementById("password").value;

        data.users.push({username:usernameData,password:passwordData,birthday:birthdayData});

        document.getElementById("displayScreen").innerHTML=`<div class="registerContainer"><h2>Greetings!</h2>
                                            <p>You can login now with your account information.</p></div> `;
    };
    </script>
  </body>
</html>

When I try to put second handler also into first handler function together with second listener, it also doesn't work. When you run index.html -> click Register button -> fill form and send -> then when you check console it says Form submission canceled because the form is not connected

CovertGravy commented 2 years ago

I copied your HTML code and created an HTML file. I am getting all the input values in the data object.

image

I updated handlerSubmit to have e.preventDefault which will remove the warning

Form submission canceled because the form is not connected

const handlerSubmit = (e) => {
       e.preventDefault();
        const usernameData = document.getElementById("username").value;
        const passwordData = document.getElementById("password").value;
        const birthdayData = document.getElementById("password").value;
        console.log({data});

        data.users.push({username:usernameData,password:passwordData,birthday:birthdayData});

        document.getElementById("displayScreen").innerHTML=`<div class="registerContainer"><h2>Greetings!</h2>
                                            <p>You can login now with your account information.</p></div> `;
    };
omerjava commented 2 years ago

Thank you so much @CovertGravy ! I didn't know e.preventDefault();. I will study this.

bermarte commented 2 years ago

Submit action implies always reloading the page, by using e.preventDefault() you prevent this from happening, so you will keep the data you filled in.

bermarte commented 2 years ago

Here the use of innerHTML is fine but in other situations, it would be better to use another approach. https://www.youtube.com/watch?v=ILcu32Nkq_I

omerjava commented 2 years ago

Here the use of innerHTML is fine but in other situations, it would be better to use another approach. https://www.youtube.com/watch?v=ILcu32Nkq_I

I watched the video. First time, I heard about document.CreateDocumentFragment(). It looks very useful. Thanks for sharing :thumbsup:

bermarte commented 2 years ago

These methods are very useful createElement() appendChild() removeChild() createTextNode() ...