So let's dive into this form
and here we'll need a couple of form input elements.
And of course we learned about a lot of form input elements
early in the course in this forms section.
Now, for example, we'll need a element for
getting the email address of a user.
For this, we can add an input of type email.
That's a specific built-in type,
which will also ensure that the right soft keyboard
is presented on mobile devices.
But of course, that's not all we need for this.
Instead, you learned that you also want to add a label
so that you have a text that describes
which kind of value is expected.
And this label should also be logically connected
to the input with help of the for and id HTML attributes.
Here, I'll name it email and hence give this an id of email,
but this doesn't have to be email.
The type does have to be email.
This doesn't have to be email.
Instead, this can be any identifier of your choice.
And then here, I'll just say email like this, or like this.
And that's the first input.
Now to later be able to extract the email
from the incoming request on the server,
we also have to give this input the name attribute,
which is another built in HTML attribute on input elements,
because that name which we assign here will be the key
which we can later use on the server side
to extract the value entered by the user
in that input field.
So here I'll also choose email.
And last but not least,
I want to ensure that this is never empty,
that it's not valid to submit this in an empty state.
We can do that by adding the required attribute.
Now we'll have a couple of label input combinations
and therefore, I want to group them together
so that we also have some space in between them.
And we could use a div for that
with a class that adds some spacing.
That is what I did in various course sections before.
And that is absolutely fine.
You'll see it a lot out there.
We could also use a paragraph instead, though.
A paragraph might sound like it's only
intended to be used on text,
but actually it is also quite common
and fine to use a paragraph instead of forms
to basically mark and group your different
form inputs and labels that belong together.
And therefore, here, I'll add my paragraph
for this first form input.
Now we can, of course, copy that,
this entire paragraph and add it below that
to also add a second input for the confirm email field.
For that, I'll give this an id of confirm-email
also here
and set the name to confirm-email.
The type will stay email because it's still an email input.
We just use it later to double check that
the email address entered here doesn't have any typo,
but instead matches the email address entered here.
Then I'll copy and paste in this paragraph again.
And now also add a password field here.
Now I'll use password as an id and as a name,
though, that's up to you, and also as a type
and that's not up to you because this type
will ensure that the characters are not visible
whilst typing so that if someone is standing behind you,
he or she can't see your password.
Now on this password input,
I also don't just want to require it.
Instead, I'll also add a minlength attribute here
and set this to six.
That's another built-in official HTML attribute,
which you can add on input elements to enforce a certain,
guess what, minimum length.
And therefore, now, we ensure that passwords
that are entered here are at least six characters long.
Now that's the main area of the signup form.
It is not all though.
Instead, I then also want to gather personal data
about the user, the user's name, the address, and so on.
Therefore, I'll add another element here.
The hr element, which is basically just a horizontal line,
a little divider.
It's mostly a visual element which I use here
to set the basic authentication information
apart from the personal information.
So below the hr element here,
I'll then paste in my paragraph here again.
And now I'm asking for the full name of the user, and hence,
I'll give this an id of full name
and a name of full name.
I don't want to have a minlength here.
I don't want to tell people how long their name has to be,
but I do change the type and I will set it to text,
which is just some standard text that I want here.
Now, I'll copy it again because now I also want to get
some address data like the street the user lives in
and hence, street sounds like a fitting id and name.
And the type will still be text here.
Now you can erase that and place your cursor
between the double quotes and then hit control space
for some auto-completion.
And here in the Visual Studio Code,
you will then see the valid types you could use.
Though, I will say that not all types are supported
in all browsers.
Text, however, definitely is.
Now, that's not all though.
The street is one thing and I will assume
that the user enters the number of the house
in the street in that street field.
But I also want to get the postal code,
so I'll accept this as well.
And I give it an id of postal and the name of postal.
And now there might be different postal codes
all over the world.
And there are definitely also are a lot of countries
without any postal codes at all.
But I will just assume that I'm building my shop here
for Germany in my case.
And here, I know that postal codes are five characters long.
They used to be four characters long in the past.
That's not in use anymore to my knowledge, at least.
And therefore here I will expect a minlength of five
and a maxlength of five
so that this is exactly five characters long.
And of course you can accept different lengths here.
I will still use type text here,
not number or anything like this,
because this should not be a number
which the user enters here.
It should be text, which looks like a number,
but it's not a number I'll use
for mathematical calculations or anything like this.
Instead, I'll use it as a raw text
and hence I'll set this to type text.
And to make this a bit easier to read,
I will now actually split all these HTML attributes
across multiple lines.
That is something we can do because you learned
that line breaks and line space like this is not a problem.
The browser will ignore it
and will still see this as one element,
but it is a bit easier to read for us humans.
And that's why I'm doing this for elements
that have a lot of HTML attributes like this one does.
And therefore now, it's time to add the last input here.
And that will be the input for the city.
So city sounds like a fitting id we can use here
and it's still of type text so I don't have any minlength,
maxlength rules.
Now below all of that, we need a button
for submitting the form and I'll give it a label,
a caption of create account.
And I will also give it a CSS class,
which we haven't defined yet,
but which I will add very soon.
The class is btn, which will be a class
that we write together that sets some base styles
for buttons or for all the elements
that have this class to be precise.
And below this button, I'll add a paragraph
with an anchor element inside.
And the anchor element will point to /login
and inside of the anchor element,
I will say Login instead.
And that should be a little utility link below this button,
which allows us to switch to the login form
in case we don't have an account yet.
I'll give this paragraph an id of switch-form,
because I want to use that for styling later
to give this paragraph and this link in there
a specific style.
Of course, it's up to you whether you want to use IDs
for selecting this paragraph later
and whether you want to use this exact id.
It's just the id I will use in this section.
Now with that, we get this very basic markup finished
for this signup page.
We of course got no styling at all, but we got the markup.
Now I want to see whether that all renders,
at least in an ugly form.
And for that, we can go to the auth.controller, again
to the getSignup function.
And now finally add some working logic here,
and to be precise, we want to render a template
for the response and to achieve this,
we use the res object here,
which is given to us by Express,
and this will have a render method
even though my auto-completion doesn't know it here.
But we'll have a render method here
and this will do multiple things in one step.
It will render a template,
which means it takes the template,
parses it with the EJS language,
and replaces all the dynamic parts with text.
And then once the HTML code is finished,
which doesn't have any dynamic segments in it anymore,
this HTML code is sent to the visitor in the response.
Render will do all these things for us.
And all it wants for that is the name of our view
or a path to our view seen relative
from inside the views folder
because that is the configuration we gave to Express earlier
that our views live in that folder.
So in my case here, I want to render
this signup.ejs file here for getSignup.
So in the views folder, I want to render the
customer/auth/signup template.
Dive into the customer folder, the auth folder,
and then the signup file.
And if we know save all of that,
we should be able to give this a try.
We can open up this integrated terminal here
and then run npm start to run
this start script we defined before,
which uses nodemon for starting our web server
and watching our project.
And now this started up.
We can now visit localhost:3000 but not like this,
but instead /signup because that is the specific route
we registered here for getting that signup page.
So if I enter /signup, indeed here, I see my form
and I'll zoom in a bit here, but that is my form.
Of course, ugly, without any styling, but it is my form.
And it would theoretically work.
At least if we configured the form attributes to tell it
where to send a request to
and if we then add the backend logic
for handling the request.
But it works no matter if it's ugly or not.
Nonetheless, of course, the goal is not to keep it ugly
and therefore in the next step,
we're going to work on some styling here
and we're already going to work on it,
such that we also can then use this styling for other forms,
like the login form, which we'll add in the future.