در حال بارگذاری ...

Goal: Login Modal0:00

Now, today, I need to add a login modal to this open-source form we're building at Laracast called Council. Now, it's actually part of this series at Laracast called How to Manage an Open Source Project, but this specific thing is small enough, it doesn't quite fit into the spectrum of this series, so we'll handle it here. So let me go ahead and log out our User. And now here you'll see we have a button to sign in to participate. So ideally, when I click on this, a nice modal should pop up, we fill in our credentials, we click sign in, it handles validation errors, and then finally it submits the form. Now here's what I use for modals in Vue.

Vue Modal Plugin0:30

we click sign in, it handles validation errors, and then finally it submits the form. Now here's what I use for modals in Vue. It's a package called Vue.js modal. Works great. So here's how you would pull it in, and then you import it, and then you use it as a Vue plugin, and now anywhere in your code, you can declare a modal, you give it a name, and then anywhere, once again, anywhere in the app, you can show that modal or hide it. It's as simple as that. So if we switch over to Sublime Text, here's my sidebar. This is the only section you really need to pay attention to.

Create Login Modal View1:23

And I already have another use case right up here. Let's do another one. When I click on this sign in modal, I'm going to show a modal that doesn't exist yet, but we'll call it login. All right. So now, in my main layout file, here's how I usually do it. You'll see this section at the bottom, include all of my modals. If we take a look at this file, at the moment we're only including one, but I'm going to pull in another one. So modals.login, and I need to create that, login.blade.php, and we'll set up our modal.

pull in another one. So modals.login, and I need to create that, login.blade.php, and we'll set up our modal here. So the name is login, and to start, let's just say login. Okay. So now, here I import all modals, and then this is just a partial, it's just a middleman that individually includes each of the partials we need. So now, if we come back to Chrome, we give this a refresh, I click sign in, and instantly I have a modal. Pretty neat, right?

That wheel has been created over and over, so there's no need to do it yourself if you don't want to. Okay. So anyways, again, just quick recap. The name of your modal is what you will trigger. So if we go back to the sidebar, you'll see modal show login, and that's what reveals the modal. If I then wanted to hide it, I would say modal.hide. So for example, let me show you this. We sign in.

Build Login Form UI2:55

So for example, let me show you this. We sign in. You can now see the modal. It's blank at the moment. Let's say on my root here, vm0.modal.hide login, and that will get rid of it dynamically. Okay. Anyways, we're ready to implement this. So I'm going to add a form here. And let's say, well, first, I'm going to need a label for the user's email address, right? Next we'll need an input.

And let's say, well, first, I'm going to need a label for the user's email address, right? Next we'll need an input. We could even make that a type of email. Name is email. We'll give it an ID as well. Then a placeholder for John Doe at example.com, and that is required. All right. That'll get us started. But if I click on this, now, of course, it looks horrible. So let's add some basic padding in place.

Next for the label, at the moment, it doesn't look very good. Let's make it a block. So we'll say for class, we want it to be block level, in uppercase, and with wider tracking. Okay. So take a look at that. Now it's in uppercase. We've increased the letter spacing a little bit. It's right on top of that input though. So let's push it down, margin-bottom-2. This is one of the nice things about Tailwind is you can just rapidly build up these things.

Yeah, that helps a little bit, adding a bit more padding. But let's make it stretch as far as it can. So the width should be full width, 100%. So we click on that, you'll see width 100%. Next, in addition to the email, we would need a section for your password as well, right? So let's select all these occurrences, update it to password. See what we got there. Sign in. Yeah, but we need some space below this control here. So let's just say mb-6, margin bottom level six.

Yeah, but we need some space below this control here. So let's just say mb-6, margin bottom level six. There we go. Looking fairly good. A placeholder. We don't really need a placeholder there. Yeah, that's fine. And then finally, let's do one more for the sign in button. So this will be Log In. Let's see how that looks.

So this will be log in. Let's see how that looks. Sign in. Obviously, it looks horrible, but let's make sure we give it a class of button, which is a component that I have. This will be a submit level button. And let's see what we got. Sign in. Yeah, looking a little better. I prefer that to be green.

Create Login Vue Component8:24

So maybe we could do that here. And maybe we'll say something like, well, if we have feedback for the User. So I will need to create that. If we had feedback, then within a span, and we'll make it extra small text, and it should be red, well, then we will echo out, so to speak, the feedback itself. So now at this point, I already know we're going to need to make an AJAX request. Ultimately, when we sign in, we'll do a full POST spec, since this isn't an SPA, it's easy to do that. But at least for the initial login click, we will do an AJAX request to see if there are errors, and if so, we'll dynamically show that on the form without reloading the page.

But at least for the initial login click, we will do an AJAX request to see if there are errors, and if so, we'll dynamically show that on the form without reloading the page itself, which can be annoying. But anyways, if we're going to do all that, and then we have some data properties here, and then we probably need a method to call that actually performs that AJAX request, maybe we should make a dedicated component here. So maybe something like login. Now we could throw this whole modal within the component, or at the moment, I'm okay with it being an inline template. But yeah, we can extract that really easy if we need to.

with it being an inline template. But yeah, we can extract that really easy if we need to. So now, sorry about that, we have our login modal, but it doesn't exist yet. So let's say resources/assets/js/components/login/view. And here, you know, I could just get away with login.js, actually, but maybe we'll add style information here later, or templates, so I'll keep it as it is. So anyways, we said here that we have feedback. And by default, that's nothing. But right here, if there is feedback at some point, we'll spit out whatever that text, whatever that string happens to be, in small red text.

But right here, if there is feedback at some point, we'll spit out whatever that text, whatever that string happens to be, in small red text. So let's see. Now, you know what? Right now, it's going to fail, isn't it? Refresh. Yeah, unknown custom element. And that's because I created login.vue, but I haven't imported it anywhere. So here in my root app.js file, we'll just do it right here. We'll say login, and then here.

Bind Inputs and Submit12:34

So one of them is called autocomplete, and this just gives a hint that we are autocompleting the user's email. And the same one here, that we are autocompleting the user's current password. You could also have one for new password, and that's like your indication to the password manager. This isn't for their existing password. This is for them to type in a new one altogether. Anyways, because we'll take what the user types into the inputs and submit an AJAX request, I do need to store them. So let's say v-model will be form.email.

I do need to store them. So let's say vModel will be form.email. We'll store it in a form object, and then another one here, form.password. And then on login.view, we need to save that. So we need your email as well as your password. And then we'll take that object and submit it as an AJAX request to the server. So it sounds like we need a method here called login. And we'll say axios.post to login. We'll send through our form credentials. So that will pass through the email and the password as the request.

We'll send through our form credentials. So that will pass through the email and the password as the request. And then, well actually, let's handle the catch condition. So if something goes wrong, there's failed validation, in that case, let's catch an error. And what we'll do here is say this.feedback will be error. And off that error, we can get the response and specifically the data message in this case. All right, so let's give that a shot. I'll open up the console here so we can try it out. Sign in.

I'll open up the console here so we can try it out. Sign in. Login. Ah, in that case, you see it did a full postback, didn't it? And it sounds like that's because here, well, actually two things. Yes, we added this login method, but at no point do we actually call that. All right, so let's say on the form, when you submit it, we'll prevent the default action so that we don't get a postback, a page refresh, but then call the login method for me. Okay, so let's give that a refresh again and that should fix it. So sign in some person that doesn't exist.

Okay, so let's give that a refresh again and that should fix it. So sign in some person that doesn't exist. And there you go. Because our app, our Laravel app, couldn't find this User, it, of course, returns a 422. So that means on that case, we hit the catch here. And if you want to take a look at that, actually, there's the data from the response. So once we got that, we assigned it to feedback. And then, of course, once again here, this div's display is dependent upon that value not being null. This is great.

not being null. This is great. So now, what about the case where the User does exist? All right, well, in that case, we'll say, and once again, if this were an SPA, you would handle it fairly differently. But in our case, let's just do a full postback. It's a nice, easy way to handle this. And that way, once the page reloads, it does reflect all of the changes to the session. So we'll say then, we can even do this inline, location.reload, reload the page. All right, refresh, sign in, foo at bar.

So we'll say then, we can even do this inline, location.reload, reload the page. All right, refresh, sign in, foo at bar. So one more time, somebody who doesn't exist, validation failed, john at example, log in, the page reloads, and we're signed in. As easy as that. Now, what about one other thing, though? Let's sign out. Often, when you click on these buttons, because there's a bit of a delay, a bit of lag, you'll see a little spinner to give an indication that we're doing some work right now. Why don't we try to add that, and then we'll call it a day.

Add Loading Spinner16:06

see a little spinner to give an indication that we're doing some work right now. Why don't we try to add that, and then we'll call it a day. All right, I'm going to go to my app.scss file, and you'll see that here, I pull in a button component. At the moment, basic stuff here. But I'm going to paste in this bit of CSS. This is the CSS for a basic loading spinner. And I got this from Bulma. It works great. All right, nothing special here.

It works great. All right, nothing special here. It's just kind of annoying CSS you have to write. The key thing to know, though, is if you add a class of loader, we'll then, in the center, we'll have this block level element that's about 1em wide and high, and that will then spin around over and over, and any text that is currently part of the loader will now be transparent so that you can't see it. All right? So now that has compiled down behind the scenes, so let's take a look at this. Do a quick refresh, and right here, I'm going to add this new class loader.

So now that has compiled down behind the scenes, so let's take a look at this. Do a quick refresh, and right here, I'm going to add this new class loader. So easy. Works great. So the only remaining step is to display that dynamically. Here's how I might do that. Let's say login.view. So when you submit the form, maybe the first thing I will do is set this loading to true. I'm just going to toggle a Boolean here so that I understand what's going on. So loading by default is not false, but when you click on that button, OK, we're going

I'm just going to toggle a Boolean here so that I understand what's going on. So loading by default is not false, but when you click on that button, OK, we're going to get started loading the results for you. Now if everything goes according to plan, we instantly reload the page, so we don't have to reset the loading indicator in that case. However, if there's an error, then we do. Otherwise, you see the error, and in fact, let me just show you that. Let's say login.blade.php, and here's the button. So we'll say class, well, are we currently loading? If so, add that loader CSS class that I just showed you.

So we'll say class, well, are we currently loading? If so, add that loader CSS class that I just showed you. Otherwise, you can ignore it. OK, so let's take a look at that. Refresh, sign in. It's going to fail, but notice that the spinner remains. It never goes off. So let's fix that. If there is an error and we catch it, then let's turn off loading. Notice we set that to false.

This is just a simple explanation with no code.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟