Creating An EdgeJS Form Input Component
In this lesson, we'll create a form input component with EdgeJS to simplify adding inputs throughout our application and to extract away old value and validation error logic.
- Author
- Tom Gobich
- Published
- Apr 12
- Duration
- 5m 28s
Developer, dog lover, and burrito eater. Currently teaching AdonisJS, a fully featured NodeJS framework, and running Adocasts where I post new lessons weekly. Professionally, I work with JavaScript, .Net C#, and SQL Server.
Adocasts
Burlington, KY
Transcript
Creating An EdgeJS Form Input Component
-
(upbeat music)
-
So we have a reusable portion of code here
-
that's forming within our register page.
-
We have our label span input input error,
-
displaying our error messages,
-
as well as our old value population
-
within that input happening,
-
not just with the full name, but with our email,
-
but our password field as well.
-
And whenever we're building out our applications,
-
whenever we sense that reusability happening,
-
it would be great to extract that out
-
into a reusable portion of code.
-
Since we're in Edge, that's gonna be a component.
-
So within our resources, views components,
-
let's right click on our component directory, new file.
-
We'll put this inside of a folder called form
-
and we'll do slash and call our file input.edge.
-
Let's jump back into our register page
-
and give one of our inputs here a copy from label to label
-
and dump that inside of our input.edge file.
-
So there's a few things within here
-
that we need to make dynamic.
-
First, our label, and we can make this optional as well.
-
Our input type, the name of the input,
-
and the name of the input gets reused in a couple of places,
-
not just with the name attribute,
-
but we can also use it when grabbing our old value
-
in our input error here as well.
-
So up at the top of this file,
-
let's normalize all of the things that could be nullable,
-
like our old value, because if we don't provide in a name,
-
we should be able to gracefully handle that.
-
So let's at let value old.
-
This will be our old value that was submitted
-
with the previous form submission if we have one.
-
So this is going to replace our old password right here.
-
We'll have this equal.
-
Now we wanna check whether or not we've provided in a name.
-
If we have, then we'll wanna check our old method.
-
And if we haven't, we'll bypass that old method
-
and just set the default value to an empty string.
-
So we can do a ternary check directly on our name.
-
And if that comes back truthy,
-
we'll do old, whatever that name is.
-
Otherwise, we'll just default to an empty string.
-
Now we wanna do something similar for just our value.
-
We're going to want to allow ourselves to provide in
-
a manual value from outside of this component.
-
And since we're assigning value here,
-
we'll want to check that directly on the props object
-
to see whether or not we're providing a value
-
in as the props.
-
If we are, we'll go ahead and use that value.
-
Otherwise, we'll default to our value old.
-
Then we can go ahead and replace our old check down here
-
with just our value.
-
So if we provide a value from outside of this component,
-
that will get used.
-
Otherwise, it will use our old value,
-
which checks whether or not we have a name.
-
And if we have a name,
-
then it will attempt to use the old value if there is one.
-
Otherwise, it will just set it to an empty string.
-
And then to protect ourselves from potential undefined
-
values from either outside of this component
-
or via our old check,
-
we'll leave the default value of an empty string
-
within the value attribute as well.
-
Now we just wanna do something
-
relatively similar for the name.
-
So if we have a name, we'll go ahead and use it.
-
Otherwise, we'll just set that to an empty string
-
so that we don't provide undefined into the name here.
-
Same thing for our type.
-
If we have a type, we'll use it.
-
Otherwise, we'll default to a type of text.
-
So that's our input out of the way.
-
Next, let's take care of our input error.
-
So if we don't provide a name into this input component,
-
we'll just bypass this input error altogether.
-
So we can cut this out, do an @if name,
-
and then end our if and paste the contents within the if.
-
So if we have a name,
-
then we'll attempt to check our input error.
-
And if we have an input error,
-
then our paragraph with text red will get applied.
-
All right, awesome.
-
So next up is our label.
-
So first we're gonna want the value here
-
to print out whatever label value is
-
we provide into this component.
-
Now, it would be great to also offer slots.
-
So we could do an @if slots label @else,
-
and then end our if.
-
For the else, we'll paste our label back in.
-
And then for the if, we'll do our three curly braces,
-
await, and then render out our slots.label.
-
And then for the span as a whole,
-
we'll do an @if slots.label or label.
-
And then down at the end of our span, we'll end that if.
-
So let's pause here and see what we got.
-
So let's go back into our register page
-
and let's scroll up to our full name.
-
Above our full name,
-
we'll keep everything as is for right now.
-
Let's do @form input and then provide in our props.
-
So for our label, we'll do full name.
-
For the input name, we'll do full name in camel case.
-
And since we're not providing in a slot,
-
we'll go ahead and make this a self-closing component
-
by adding in an exclamation point after the @ symbol.
-
Okay, cool.
-
So now if we did everything correctly,
-
we should see two full name inputs,
-
one for the one that we've manually defined
-
and one for our form input component.
-
So let's give that a save
-
and let's jump back into our browser.
-
And look at that, there's our full name there
-
and our full name there.
-
Cool, so let's hide that back away
-
and let's get rid of our manual input
-
and let's fill out the rest of them here as well.
-
So @!form input label email, name email.
-
And for this one, we also want the input type to be email.
-
Okay, we have one more.
-
So @form input label password, name password,
-
and then lastly, we want that input type to be password
-
so that it doesn't register out as plain text
-
on the input field.
-
Then we can go ahead and get rid of our manual inputs here.
-
So now we've simplified and replaced that duplicate logic
-
that we had going on to render out our registered input
-
fields and this paves way for us to be able to easily
-
add inputs anywhere throughout our application.
-
So let's dive back into our browser.
-
Everything still looks okay here.
-
Let's attempt to do john [email protected]
-
with some invalid password again.
-
And okay, looks like they're all using
-
the password validation.
-
So I bet within our component, I forgot to update.
-
Yep, sure enough right here, our input error
-
should definitely be using the name that we provided
-
to check for the applicable error here.
-
So we'll save that, jump back into our browser
-
and let's give that one more round of john [email protected]
-
some invalid password, run that.
-
There we go, okay, cool.
-
So our full name was valid, our email was invalid
-
due to it being already taken and our password field
-
must have at least eight characters.
-
In addition to our inputs being invalid,
-
we've also repopulated the email and full name
-
just as it was whenever we were manually handling
-
all of this, except now it's being done automatically
-
by our input component.
-
Introduction
-
Fundamentals
-
2.0Routes and How To Create Them5m 23s
-
2.1Rendering a View for a Route6m 29s
-
2.2Linking Between Routes7m 51s
-
2.3Loading A Movie Using Route Parameters9m 17s
-
2.4Validating Route Parameters6m 6s
-
2.5Vite and Our Assets6m 38s
-
2.6Setting Up Tailwind CSS9m 5s
-
2.7Reading and Supporting Markdown Content4m 32s
-
2.8Listing Movies from their Markdown Files8m 51s
-
2.9Extracting Reusable Code with Services7m 4s
-
2.10Cleaning Up Routes with Controllers4m 52s
-
2.11Defining A Structure for our Movie using Models9m 38s
-
2.12Singleton Services and the Idea of Caching6m 11s
-
2.13Environment Variables and their Validation4m 16s
-
2.14Improved Caching with Redis10m 44s
-
2.15Deleting Items and Flushing our Redis Cache6m 46s
-
2.16Quick Start Apps with Custom Starter Kits6m 28s
-
2.17Easy Imports with NodeJS Subpath Imports8m 40s
-
-
Building Views with EdgeJS
-
3.0EdgeJS Templating Basics8m 49s
-
3.1HTML Attribute and Class Utilities6m 9s
-
3.2Making A Reusable Movie Card Component10m 24s
-
3.3Component Tags, State, and Props4m 53s
-
3.4Use Slots To Make A Button Component6m 56s
-
3.5Extracting A Layout Component5m 13s
-
3.6State vs Share Data Flow2m 59s
-
3.7Share vs Global Data Flow6m 7s
-
3.8Form Basics and CSRF Protection6m 13s
-
3.9HTTP Method Spoofing HTML Forms3m 3s
-
3.10Easy SVG Icons with Edge Iconify7m 57s
-
-
Database and Lucid ORM Basics
-
4.0Configuring Lucid and our Database Connection4m 3s
-
4.1Understanding our Database Schema9m 35s
-
4.2Introducing and Defining Database Migrations18m 35s
-
4.3The Flow of Migrations8m 28s
-
4.4Introducing Lucid Models5m 43s
-
4.5Defining Our Models6m 49s
-
4.6The Basics of CRUD11m 56s
-
4.7Defining Required Data with Seeders11m 11s
-
4.8Stubbing Fake Data with Model Factories13m 48s
-
4.9Querying Our Movies with the Query Builder15m 30s
-
4.10Unmapped and Computed Model Properties3m 24s
-
4.11Altering Tables with Migrations7m 6s
-
4.12Adding A Profile Model, Migration, Factory, and Controller2m 57s
-
4.13SQL Parameters and Injection Protection9m 19s
-
4.14Reusable Query Statements with Model Query Scopes8m 11s
-
4.15Tapping into Model Factory States9m 15s
-
4.16Querying Recently Released and Coming Soon Movies4m 59s
-
4.17Generating A Unique Movie Slug With Model Hooks7m 59s
-
-
Lucid ORM Relationships
-
5.0Defining One to One Relationships Within Lucid Models5m 49s
-
5.1Model Factory Relationships2m 54s
-
5.2Querying Relationships and Eager Vs Lazy Loading5m 17s
-
5.3Cascading and Deleting Model Relationships5m 16s
-
5.4Defining One to Many Relationships with Lucid Models6m 56s
-
5.5Seeding Movies with One to Many Model Factory Relationships5m 24s
-
5.6Listing A Director's Movies with Relationship Existence Queries8m 41s
-
5.7Listing and Counting a Writer's Movies8m 41s
-
5.8Using Eager and Lazy Loading to Load A Movie's Writer and Director5m 18s
-
5.9Defining Many-To-Many Relationships and Pivot Columns9m 48s
-
5.10Many-To-Many Model Factory Relationships4m 50s
-
5.11A Deep Dive Into Relationship CRUD with Models18m 5s
-
5.12How To Create Factory Relationships from a Pool of Data13m 55s
-
5.13How To Query, Sort, and Filter by Pivot Table Data9m 47s
-
-
Working With Forms
-
6.0Accepting Form Data12m 15s
-
6.1Validating Form Data with VineJS9m 29s
-
6.2Displaying Validation Errors and Validating from our Request7m 16s
-
6.3Reusing Old Form Values After A Validation Error2m 3s
-
6.4Creating An EdgeJS Form Input Component5m 28s
-
6.5Creating A Login Form and Validator5m 1s
-
6.6How To Create A Custom VineJS Validation Rule9m 7s
-
-
Authentication & Middleware
-
The Flow of Middleware7m 49s
-
Authenticating A Newly Registered User4m 14s
-
Checking For and Populating an Authenticated User2m 10s
-
Logging Out An Authenticated User2m 24s
-
Logging In An Existing User6m 54s
-
Remembering A User's Authenticated Session6m 55s
-
Protecting Routes with Auth, Guest, and Admin Middleware5m 36s
-
-
Filtering and Paginating Queries
Join The Discussion! (0 Comments)
Please sign in or sign up for free to join in on the dicussion.
Be the first to Comment!