Infinite Scroll Loading with Laravel Livewire!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome back to another video this video is going to be on building an infinite scroll livewire data table setup it's not really going to be a data table it's just going to be a regular html table because if i were to try to build everything this video would be way too long the difference between this video and the other data table videos is that in this one i'm going to try to really start from scratch so i'm going to install tailwind live wire and kind of configure the whole project from from start to finish to give you an idea of what i'm trying to build because i'm kind of winging it i've built this before but i don't have a copy or or any record of what i've built so here's kind of what i want to achieve maybe not as polished but every time you scroll more records or in this case colors are queried and show up so this is actually not that difficult to get working within livewire i actually tried to get this to work with some event firing weird stuff in javascript and a co-worker of mine actually pointed out that i should use observers that's definitely the best way to go so i'm going to show you how to do that and i hope you enjoy this video if you do like it please do consider subscribing it really helps out i think this channel is growing much quicker than i've expected so i'm glad to see everyone here and i hope that you enjoy this video also one more thing i'd like to mention is that the timestamps will probably be below in the comments somewhere so if you want to skip ahead through this video because it's going to be quite long then you can go ahead and use that okay so let's get started first thing i want to do is open up my my console here my item and i'm going to create a new layerable project first i'm going to cd into where i want to actually create it and i'm going to use the command layer bell new and then project name in my case it's live wire infinite scroll i'd like to quickly mention that on a vanilla layerable project there's no auth scaffolding so we're going to have to create a couple files here and there on our own and the tailwind setup we're going to get from the tailwind instructions on the website they've actually posted a new page for laravel specifically for version 2.0 which is really really cool because there's some issues with post css eight so that really clears up the the confusion there so i'm going to show you how to do that let me just cd into the project here all right so the first thing i want to do is open it up in my editor look at the env the environment file and make sure that everything makes sense so in the case of this project i've already created a a database called livewire infinite scroll the only difference is that these are underscores they need to be just regular dashes or hyphens the rest of it should be fine so layerable by default actually comes with a user's table migration and we're going to use that because it's just the easiest way to to get data that we can test the table with so i'm just going to run php artisan migrate and if we go back to our database or sql pro we can see that we have a users table in the migrations table password resets and failed jobs now that we have this we can actually see the database so first thing we want to do is go back to our editor open the database seeder and just uncomment this line now 10 records is not enough that's what by default is is being set here and i'm going to set this to 500 users right and that'll give us enough to kind of scroll through forever actually let's make it let's make it a hundred so that we can see the bottom of it when it comes time to test the the scroll now i can run php artisan db seed go back into our sql pro you can see we have 100 records which is exactly what we need and that's pretty much it from the database side which is amazing but it's really that simple so the next thing we're going to do is actually install tailwind like i mentioned before tailwind actually has its own layer of a specific page now because laravel has mix it makes it really easy to install but mix is not compatible with posts post css eight yet and so there's some there's some specific installation instructions for version two and higher here and we're going to follow these so the first thing i need to do is run npm install apparently so we can do that and this might take a little while okay so that's now finished we can move on to the next step which will probably be this npm command here to install everything we need okay and that's installed we can look into our package.json here and see what happened so we have tailwind css and it's the post css 7 version which is exactly what we need and now we can continue on to this command npx tailwind init which is going to create the tailwind.config.js file in the root of our project and that's basically where you use some like you can extend styles and create styles and add plugins add configuration for layer for tailwind purge in this case we're just going to generate it and leave it for now so it looks like it's generated we could actually check tailwind.config.js and there it is so perfect and let's move on to the next so configure tailwind to remove unused styles in production well if it's already here we might as well use it right so so what this is going to do is it's going to look in the resources and then any directory within resources and any file that's dotblade.php dot js or dot view and it's going to look for those the classes within those files and not eliminate them in the production css file so i'm just going to copy this even though we're not going to have any view files and just put that in here save that and we can move on to the next step so we need to actually require tailwind css within the webpack.mix file so the way this is done is just copying this require line and going into your webpack.mix file and just putting that there which is really really easy and then you'll need to copy and paste this into your app.css which is the like the root css file that's going to be i guess compiled i'm not sure if that's the right word but it's in the resources css app.css directory and that's good and then the last thing we need is actually to add these tags here to the top of the main page the app.blade.php if you're going to follow laravel convention which we'll do afterwards because that file currently does not actually exist within our project so for now i believe that if we run npm run watch it should actually build and if it builds correctly that means that everything's installed and we can continue on to actually installing livewire and looks like it compiled successfully so we could actually move on i'm just gonna stop that clearly the command line and we can move on to installing livewire so livewire is installed with a composer command because it's a php package and not a javascript one like tailwind and the the basics is you install it and then you include this in whatever your root template file is again if you're following level standards or like conventions it's app.blade.php which again doesn't exist so we're going to get that figured out in a second let's just install this first and uh livewire actually supports php8 now which is great uh otherwise i wouldn't be able to run it because i'm actually on php8 right now so i'm very excited to see what the future holds for a lot of these packages it's the the laravel ecosystem has been growing very quickly and it's been really exciting to watch it and i'm just really excited to see where things go in any case we can now create our app.blade.php so let's go back to our editor go into the resources directory views and we're just going to create a directory called layouts and call it app.blade.php and within here we can start creating our root template like our base template for all pages and in our case it's just going to be one page so it's not really anything too crazy but the reason i wanted to create an app.blade.php this is a file this is something i actually mentioned in a previous video is because livewire by default will actually expect a resources slash views slash layout slash app.blade.php file when it's trying to render out its components and doing it this way actually allows us to skip creating an entire controller for this we can just create a route and direct it directly into our component and it'll kind of like figure itself out which is really cool so i'm gonna fast forward through the boring bits of this and then maybe pause and explain if i find something interesting to talk about okay we can include our tailwind stuff right below that title tag something to note is that this is not perfect html you're going to want to create some like dynamic titling of the pages or something but for the purpose of this tutorial i feel like this will be enough so what this is going to do is it's going to set the all the meta stuff we need and a tailwind recommends and it's also going to pull in that app.css that we you know added our tailwind styles to this right here is actually built into level i believe there's a mix helper that's built into layerable mix but this will work it's going to pull in that app.css that's compiled within the not the resources but the public directory which is right here so we have an app.css right here and it's going to pull that in and we're going to have tailwind so that's one thing the other thing to note is that when we're getting live wire we need to include an at live wire styles right here and that's best done at the bottom of the head tag or the head section and this is going to pull in the styles needed for live wire that are included with the package we also need to include at livewire scripts and that's done at the bottom of the body section so we can do that there and now i'll continue on building the rest it's only a little bit left and we could move on okay so i just want to explain what's happening here i've created a container here and it's going to be centered horizontally with mx auto and container all that does within tailwind if you're not aware of of how tailwind works is it's going to limit the width of the container to a predetermined size and within here i just add created an h1 tag with text 3xl text center and a margin top and bottom of 10. that's going to space out the title a little bit and within here down here i actually created another container and also centered horizontally so mx x is actually left and right whereas y like here is top and bottom and that just contains the slot so what the slot is is just basically where the livewire component will be slotted into this template also it's worth mentioning that this template should be dynamically titled so this should be passed in from the the child component that's being slotted in and this should be replaced but for the purpose of this tutorial i'm going to skip that okay now here comes the fun part we're going to actually create the livewire component that we're going to use to show the users table or that that will become the users table that will actually be slotted into this template so the way we do this is by just running a like artisan command php artisan make livewire let's call it userstable and as you can see this generates a userstable.class and a usersdashtable.blade.php template file and so now in our project if we go in and look up users table we can see we have the class let me just show you what the template looks like it's empty and nothing will come up so for the purpose of just this part of the tutorial i'm going to create the first the route and then i'm going to create what i need to within the component class and then we can get working on the template so to create a route we go into the web.php file and we're going to default this route to show the you the the users table so how this is done in uh level eight is now it's within if you have a controller and then a specific method it's done within an array but since our we're just directing it straight to a component class we can just input the class here so it's going to be users table make sure that's imported and class and what this does calling just class on the end it will actually just return the string and that should be enough if we go and now use valet link to link this so we can actually see the project within my browser and and then valet secured we can see that that's finished up so if i copy this now go into the browser and look at that there's our app.blade.php header there and our component will be somewhere here and as you can see it's centered everything seems to be working and we can move on to the actual component class what we need to do here is create all the public properties we'll need create a couple methods or actions as they're called within live wire and make sure that we're querying for the users correctly so that the table comes up with the correct data so the first thing i'm going to do is actually create those public properties i need within livewire if you create a public property you just create a looks like a variable we'll call this one total records and we won't assign anything to it and we'll create another one called public load amount and we'll default this to 10. so for those of you who are not familiar with livewire these will both be available within the template file that this is going to render which is this one right here so live livewire.users dash table there they will also be available within this component obviously and we're going to set total records within a mounted method but i just want to make sure everyone understands total records is total number of user records within the database and this one's going to be the number of records to load per scroll uh per scroll event i guess we can call and so this is the number that's going to be loaded by default and then loaded again once we scroll and again once we scroll so the first load is going to be 10 records then 20 then 30 and then 40 and so on total number of user records within the database is going to basically just hold the count of total number of users that we have stored and you'll see later on why we'll need this within the template and now we need to actually set the total records and we can do this using a public function and actually i've got a handy shortcut for this call this amount and within here we just call or set this total records total records equal to user which we need to import and count once this component mounts it's going to query the total number of user records within the database and it's going to store this within here which will be available within our template and we also need another method called we can call it load more i guess what this method is going to do is actually increment this count right here so that we know how many to load with the query that we're going to put right in here in the render method this is going to make a lot more sense in a second so i'm going to call this load more which makes sense in the context of when we scroll we want to load more so it's just going to increment that value and we're going to write this load amount plus equals 10 so it's going to be whatever it is plus 10. and so the first time this is going to be called it's actually going to turn this into 20. that makes sense and in here we're going to include user's data and the key is going to be users so call it users and we're going to make a query for all users limit this load amount get and so this is going to get this many records and put that into our template which we'll be able to hopefully see for example let's see if we could just output the first user so users first name if i go and load this up in the browser now we should see just one name and we do so that's complete and we can now move on to actually creating the template file which like i said is going to be probably the most complicated part because it not only deals with tailwind but also observers just to start off we're going to define class here and i'm going to fast forward over any of the boring parts so it doesn't take too long keep in mind that i'm just kind of i don't know how this is going to look so it might look very ugly but i think for the purpose of demonstrating how it works it'll work it'll be just fine so so far i've just created a table table auto full width within the container and i see i've misspelled container and this is going to be centered i actually don't even need if don't even know if we need this to be honest but we'll see when we load the page each each table head row is going to be i have a padding left right of four padding top bottom of two it's just going to look like a rectangle and now i'm going to continue on to the t body and my goal for this first iteration is just to get all the user records showing without any of the fancy stuff so just bear with me okay and so now technically if we reload we should be able to see a table and i hope it's not too too ugly oh it's actually not that bad at all so this will actually work fine and we're going to work with this i don't think i need to make any changes i'm actually quite pleased with how it turned out so the next thing i want to do is actually make sure i can add an id to the last item in in the for loop to show that it is the last item because i will need to track when this hits a certain point of the page right as of right now this table row has nothing on it but we can change this because blade templates or what's being used in here actually is allows you to check if the current loop is the last one and so the easiest way to do this is there's like this there's a loop variable and if you check if it's the last one you can then do something so in this case i'm just going to add an id of last record and we can end if if i reload the page now we can see that the last record has the last record id which is exactly what we need so now we can track whether that's on the screen or not and know that we need to scroll more so we can continue on this is pretty much it for the live wire specific stuff what i do want to add though is a little section here and now you'll see why those public properties will be very useful i want to add a section that shows that we're out of records to render right and so the way we can do this is by comparing the load amount which is what we're incrementing if that's greater or equal to the total records we want to display a message so the way we do this is by using a p tag giving it a class classes text gray 800 font bold text to excel text center my 10 so margin top bottom of 10 just to give it some space oh it should be margin and within here we can just write no remaining records cool so now that we have that we should see that it's not actually on the page right if i flip this though just temporarily you can see that it looks like this oops it should be centered and that's exactly what it should look like so that's that's great we can now flip this back and continue on so one more thing i wanted to include is that i wanted there to be a loading state when the records are being loaded livewire includes something really really handy just out of the box it's called wire loading dot delay dot class so when livewire is going to be loading something or querying in some sort of query state i guess we can set the table to be with an opacity of fifty percent or any class we want really and that will show that it's actually loading the trouble is i will only be able to show you this once i have the observer set up for query and i will have to slow down the actual requests within the network tab because uh local development's relatively fast so there's no way to see actual delays but in any case we can now move on to the observer part so the first thing i want to do is just before this closing div tag i want to create a script block and within the script block i'll be writing some javascript just to just to basically call or trigger the event that will load more and so i want to define a constant called last record and we could just use like old school javascript document.getelementbyid um i believe that this is a decent way to go about doing this const options we need to define options for our observer uh which i'll explain in a second let me just scroll up and we need to define a root we don't actually need to but i will just for the purpose of this a threshold so set this to 1 and we need a root margin and we could set this to 0 pixels and now we can actually define our observer so const observer equals new inter section observer and within here we create a callback so uh entries we pass entries and the observer and create our function and within our actual function we just type observe entries dot for each and loop over them entry so for every entry we need to check so if this entry and of course entries what entries are going to be is the last record and there should only ever be one last record on the page because we're only checking within the loop here if it's the last one add this id right and so it's going to loop over these entries and there should only ever be one and it's going to check if this entry is intersecting and what that means is it considers is intersecting if this element is on the page based on these options and again i'll explain these options in a moment i just want to make sure that i have this working correctly and then i'll jump in and explain what each of these means so entry dot is intersecting oops enter and within here if is intersecting we could call a live wire action or method so at this this is something that livewire provides load more and so like i said before this will make sense once i'm once once i finish this up this dot load more will trigger this action within here load more so i hope that makes more sense now and the last piece of the puzzle here is we need to actually call it so observer.observe and we pass in last record so i know this is really difficult maybe to understand so let's let's uh run through it from the top first we get our last record using a document.getelementbyid this is the last record this there will only be one of these on the page and because we're we're only adding this id to the last record within the loop right here and there can only be one last one right then we define our options and our options are root so the element that is used as the viewport for checking visibility of the target must be the answer ancestor of the target defaults to browser viewport if not specified or if null so in our case because it's null it's going to be the whole viewport which means that if the last element comes into our viewport this observer will be triggered the threshold is uh either a single number or an array of numbers which indicate at what percentage of the target's visibility the observer's callback should be executed right so in our case a threshold of 1.0 or 1 means that 100 percent of the target is visible within the element specified by the the root option the callback will be invoked so when 100 of this is shown within our viewport the last element this uh this load more will be triggered right because it will check and it will technically be intersecting and the root margin is a margin around the root and can have values similar to the css margin property and you can you know you can define top right bottom left the values can be percentages this set of values serves to grow or shrink each side of the root element's bounding box before computing intersections defaults to all zeros which means that we can basically just define a margin around the edges where uh we want there to be some sort of limit so like if we defined 100 pixels on the bottom it would this wouldn't be considered it is intersecting until it's 100 pixels above the the bottom of our viewport from from what i understand that's how it works so in any case we've set it to basically zero root margin threshold of one which means that the last record has to be 100 visible on the viewport and root of null which means that our viewport is basically what we consider as intersecting and so now if we reload the page we should see that it's working it's working perfectly actually which is really exciting the one thing you'll notice is that the initial load only has 10 records and when you refresh and it notices that you know the last record number 10 is on the page usually it'll just instantly create that second query it'll automatically increment another 10 just to get 20 on the page if we change this to 20 the initial one of 20 and reload you can see that there's 20 right away so it only queries more once i scroll down and you can see that none of that opacity stuff is showing up you can see that we're loading more and the fun thing is if you look in the network tab so once i scroll down you can see requests being made here which is really cool so every time i scroll and we we get before we get to the bottom and no remaining records are found it's actually making requests which is awesome so so within here uh once i reload the page we have 20 records i haven't queried anything else because i haven't i haven't scrolled yet i can opt to use slow 3g and when i scroll you can see that the opacity goes to 50 before the load is completed which is pretty cool now you can use this to trigger like a spinner a loading icon something like that or maybe just do something more drastic because this isn't immediately obvious what's happening but it is a pretty cool feature that livewire has built you know just right out of the box you can just define wireloading.delay.class and i thought it was really cool in any case this tutorial is now complete if you do enjoy this content please like i said do consider subscribing there's also a link to cloudways below if you need somewhere to deploy level apps easily for you or your clients please do consider using that link below that really does help i actually have a video on my channel of me deploying a level app to cloudways it's very very easy so if you are interested in that i recommend checking that out and once again thank you and i hope to see you in the next one
Info
Channel: David Grzyb
Views: 3,984
Rating: undefined out of 5
Keywords:
Id: CYdgV49EVCQ
Channel Id: undefined
Length: 27min 33sec (1653 seconds)
Published: Sun Jan 03 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.