Modern HTTP-Requests for login/register system I am working on a login/register system and want the register and log in process as smooth as possible. One way of making it smoother is in my opinion to make a multi-step login/register. 

What I mean: If a user want's to log in, he first have to type in his username and if this username exists, he can type in a password and log in. The user has more feedback, especially in the register process. Since I started to learn OOP and know that es6 was introduces a while ago, I want to improve in JS aswell.

I only have one button that does everything. That's why I have a switch case in my button event listener that compares the value of it to select the right method in my form class.

The code at the bottom is what I have came up with. It works but I don't think it is how it's done normally. 

Is this code 'advanced' or does it look like it's from a noob.

I am aware that doing a login like that leaks information, but I have already setup a robust protection against it. So that attackers don't have a lot of tries, while users can login wihtout a DoS.

class Form {
    content = document.getElementById('content');
    username = document.getElementById('username');
    password = document.getElementById('password');
    submit_btn = document.getElementById('right');
    loader = document.getElementById('loader');
    request;

    constructor () {
        this.request = new XMLHttpRequest();
    }

    execute(type, path, Data) {
        this.loading();
        this.request.open(type, path);
        this.request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        this.request.send(Data);
    }

    loading() {
        this.loader.style.opacity = 1;
    }

    loaded() {
        this.loader.style.opacity = 0;
    }

    submit_username () {
        this.request.onload = () =&gt; {
            this.loaded();

            //If response value is true than
            //Switch Input field to password
            //Change button value to login_two
            //else show error messages

        }

        let Data = `username=${this.username.value}`

        this.execute('post', '/login/step_one', Data);
    }

    submit_login() {
        this.request.onload = () =&gt; {
            this.loaded();

            //If response value is true than
            //Redirect the user to home
            //else show error messages

        }

        let Data = `password=${this.password.value}`

        this.execute('post', '/login/step_two', Data);

    }

}

const form = new Form();

form.submit_btn.addEventListener("click", () =&gt; {
    let method = form.submit_btn.value;
    switch (method) {
        case 'login_one':
            form.submit_username();
        break;
        case 'login_two':
            form.submit_login();
        break;
    }
});


Maybe someone can provide an example of a better way.

Codepen
Declaring a class makes sense if it can be reused, but less so if the logic and element ids are hardcoded to just one case, it only adds the unnecessary this. to variables.
It's unclear why the click listener is handled outside of the form class as it's logically and conceptually a part of the form.
JS naming convention is camelCase, not snake_case.
Consider URLSearchParams API so the HTTP headers are set automatically and values are properly escaped.
Consider making the login routes more declarative e.g. routes in the code below.
If your goal was to use a class as a namespace then it might be better to switch to modules. For example using the built-in ES modules the inner contents of the function will be the entire contents of the module.


function handleLogin() {
  const request = new XMLHttpRequest();
  const loader = document.getElementById('loader');
  const btn = document.getElementById('right');
  let step = 0;
  const routes = [{
    path: 'one',
    field: 'username',
    onload() {
      step++;
      getDataElement().focus();
    },
    onerror(e) { /* show error */ },
  }, {
    path: 'two',
    field: 'password',
    onload() { /* show home page */ },
    onerror(e) { /* show error */ },
  }];

  btn.addEventListener('click', () =&gt; {
    loader.style.opacity = 1;
    const {path, field} = routes[step];
    request.open('post', `/login/step_${path}`);
    request.send(new URLSearchParams({[field]: getDataElement().value}));
  });

  request.addEventListener('loadend', e =&gt; {
    loader.style.opacity = 0;
    routes[step][request.response === 'true' ? 'onload' : 'onerror'](e);
  });

  function getDataElement() {
    return document.getElementById(routes[step].field);
  }
}