Livewire Datatable with Selectable Columns 👨‍💻 [BEGINNER TUTORIAL]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome back to another video this video is going to be on me building a data table with live wire this time around it's going to be with selectable check boxes in each row that you can use to edit selected rows or delete them whatever this is actually something that was a request from a viewer on the last data table uh video which i thought was really interesting and i wanted to just jump in and get that get this uh created because i was just curious myself on how hard it would be um i just a quick note before i start i wanted to thank you all for subscribing i'm now into month three three and a half i think of recording videos and i'm at 280 something subscribers which is crazy to me subscribing is the best way to support this channel and i really appreciate you all doing that so thank you to get started we just need to generate a new layer of all project so layerville new livewire selectable data table next i'm just going to cd into that and install livewire which is done with composer require livewire livewire okay i'm on a mac and i use valet to serve my my level projects php projects rather so i'm going to use valet link and ballet secure and now theoretically i go into my browser i should see a fresh level project with livewire installed which i do so just to be clear i'm using uh laravel version 8 and php8 i'm going to try to stick to like php 7.4 syntax whatever just to keep it comparable to watching if you're not using php8 yet but i don't really see anything that would change drastically because i'm using php8 so this should be pretty useful for everyone just to get started let's open up this project and kind of see what's going on in here a laravel project by default comes with a user model which we see here the new level version the latest release has a has factory trait which uses the which means the user model can now use user factory the new style factories which we're going to use to see the database so we have data to actually show within our data table but before we do all that we need to see our environment file make sure that the values are correct and our database name value by default as this i've actually gone ahead and actually created this beforehand here so livewire underscore selectable underscore data table and as you can see there's nothing in here so i'm good to get going on this we can get started let's open up the database seeder as you can see laravel's already provided some basic factory that was commented out but we're going to write it a little bit differently so we need to import user factory times 50 because i want 50 records and i want each record to have specific values in a certain column and that column is created at i want created that to be random for each user so that it's easy to see that sorting actually works inside the data table correctly if they all have the same value then it's really difficult to do that and the way we do this within the the state array is we use the column we want to edit or set as the key and then the value we want to set as obviously the value so the way i want to do this is now sub minutes and then a random amount of minutes between 0 and 59. and you'd think this would work and it technically will but the problem is that this will actually generate one random time and then set that one random time for each record and that kind of defeats the whole purpose of uh setting this in the first place the way i get around this is just by setting this like so this is a shorthand php function i think that was introduced in php 7.4 and basically this wraps the the random generation i think in what's called a closure but this closure will now run be evaluated every time a user record is being created therefore it will be random and we'll see that that's the case in a second so if i just clear this we can run php artisan migrate so if we go back to here refresh go into users you can see that our tables are created now we can run php artisan db seed and this will seat our database and you can see that we have a 50 user records 50 rows in table and they all have random timestamps that works fine pro tip if you want to migrate fresh so rerun migrations and seed at the same time you can run php artisan migrate fresh seed and that was recede so if we refresh the data as fresh the migrations are fresh but it's all seeded i try to alias as much as i can in you know commands that i find myself running frequently so i i use mfs to to alias to this within my dish file and that speeds up my development time a lot because i run this many times within a day i usually at work so that's pro tip that's what i would do i would alias everything you're running many times just to speed up your development process moving on i think that we can actually get to creating a component and the way we do this is by running php artisan make live wire and we can call this component users table and that creates the users table class and the users dash table.bla.php template file and if we want to go back in our editor now we can actually see that this is the case so that's what a typical live wire component looks like when you're just starting up and this is what the template file looks like which is has just a quote in it commented out so what we're going to do just to start is make sure that we include a trait that you have to use with live wire if you're going to use pagination and that is called use with pagination and make sure that that is actually imported my editor does that for me and then in here we're going to be defining a bunch of public properties to use within our template that i will get to in a second first we want to see that we can actually render this out onto the into the browser so in our web file which is where our main routes are are kept right now for the root route which is the only one defined we're outputting the welcome view and we can reuse this route and instead just output the users table component and this also has to be imported my my editor just did that as well so keep in mind this has to be imported as well here for it to work if we go back to the browser and refresh we're going to get an error and that's because view layouts.app does not exist if we're outputting components from here livewire will try to slot the component template into a app.blade.php file within the resources views layouts directory and that's really confusing i'm sure if you're listening to me right now but basically what's happening is livewire is trying to find a file within resources views and layouts this does not exist in our project because we did not install any authentication scaffolding or anything like that for for authentication ui and that's typically where laravel would any layerable package would put that that main layoutsapp.blade.php file so we can create our own app.blade.php and lucky me i'm just going to copy it over from the last project because this has nothing to do with livewire basically but if we look here i'm basically just including some basic html it's got a head and a body and i've included tailwind font awesome which i doubt i'll use and the nunito font which i happen to like and most importantly at the bottom of the head i'm including at livewire styles and at the bottom of the body i'm including at livewire scripts so this is where livewire actually injects its resources i'm not sure if that's the right term but that's where the livewire stuff gets loaded in and that is absolutely necessary if you are using livewire and your components just they render but they don't seem to work it's not reactive that's probably one of the reasons why you might not be loading the scripts or the styles correctly now i've also included a user's header in here not the best place for it if you're going to be reusing this file this should be within the component but for the purpose of this tutorial that's going to be left in here and the only thing left to do is to use a slot for to allow live wire to actually inject that component into here so i'm going to use a class container which will limit the width and mx auto which will center this div horizontally and within here we just use a blade slot if i reload the browser now there should be no error you can see users comes up but how do we know that that actual template file from the component is being loaded well we can go ahead and just put some text in here and there we go so the text is coming up and that's being loaded from the users-table.blade.php component template file and that means that our component is being actually rendered which is great so the next step will actually be to make the page look like the last tutorials data data table page and i'm just going to copy over that as well and i'm going to remove these because this will break the page and i'm also going to go up here and remove wire model per page so if i reload now you see that we have a search a drop down four columns that we want to sort by the sort direction and the per page value for pagination and we have the table with no values in it and there's no values in it because we're not actually passing in any users and we're not looping over those users within the template file so we can actually start by defining a search method well actually let's start in the component what we want to do is uh edit the render render method within the render method we're just returning a view livewire.users dash table right here that's the one right here how we pass in data within livewire is just by including an array of data as a second parameter in the view here and we want to use the key users and we want the user model which was just imported you have to import that and we want to search we want to order by a certain column for now we can order by let's say created at which exists on the table in descending order and we want to simple paginate let's say for you know a default 10 records per page so that's why we included with pagination the only thing that's going to break here is that the search doesn't actually exist this method does not exist on a user and that's probably that's exactly what this error is it just doesn't exist and i got this method from a caleb porzio screencast the creator of livewire and i'm not sure if this is the best way to go about this maybe a scope would be better i'm not entirely sure but this is the way he does it so this is the way i've been kind of doing it since i watched that so we want to make a public static function search method and we want to pass in a search value and within here we want to return a this is basically scoping down the query to only include records that match our search criteria we want to first check if the search value passed in as a parameter is empty if it is a if it is empty we're going to return it using a ternary we're going to return static query if this value is not empty though we want to return a static where id like search and we want to copy this because we also want to search on the name and we also want to search on the email oh looks like we're missing a colon here and there we go so what's going to happen here is if the search is empty meaning like an empty string value it's going to return just an empty query so nothing will change there's going to be no limiting or constraints on the user query if however there is a value in here it's going to include records that only match three constraints here so if the search is within the id the name or the email we want to include those records something to note here where actually escapes values so there's no risk for sql injection as far as i know here and so it's totally fine to to search this way using like so that works and now if we refresh our browser we should see that nothing's changed but at least there's no error we can go back to here and implement some of the public properties we need to actually track for this component to work however the first thing we could do is get users to actually be outputted because right now we have 50 users in the in the table but none of them are coming up because we're not actually rendering them on the front end and the so the way i'm going to do this is by first wrapping this table with an if and we're going to check if users is not empty if user is not empty we want to output a table with with the user data else we want to only output this whoops no users or found message and within the table here we want to put a four each users as user and for each and within here we can put user id name email and created at now the created ad date is going to be pretty ugly as you can see our records do come up which which is great but the created at date time is pretty ugly so i typically just for demos use diff for humans to make it obvious what's happening and what this will do is create it to something really easy and readable so this does actually work the only thing missing is pagination and i'm sure you might have noticed that so the easy fix for this is to just include the pagination links level allows you to basically do the collection of models you are trying to output arrow links and it will render the buttons you need for you which is amazing so the next step will be getting these this search and the sorting and pagination stuff to work and this is actually very simple but we just need to define some public properties if you're familiar with javascript like view react style development you'll know that you have to store some sort of data properties within your components and the way this is done here is by basically defining public properties like so so public search is equal to empty by default public per page is equal to 10 for pagination by default public sort call it sort field we can let this be id by default and public sort ascending we can make this true by default so we will be sorting in ascending order by default and we can now replace these empty values here with these public properties so the way this is done is user search and pass in this search which will now reference the value in here and once these are changed we will have to wire up the we'll have to bind the values within the the template to actually change the values within our component here and we can change this out for this sort field and here because we are storing a sort ascending boolean we actually need to check so if sort ascending we want to output ascending if not we want to output descending and in here we will use this per page which was by default 10. if we reload you'll see that not much has changed these still don't work because they're not actually binded to those public properties but at least we didn't break anything so we can now go ahead and actually bind these values this search input that you see here is actually this input right here and the way we do this is bind is basically by using wire colon model is equal to search and this search here is going to be referencing this public property here and now if we refresh and let's say i search orville or val only that record comes up because there's only one record that matches in either the id name or email this search term if i type something really random you'll see that our if statement if condition there of only showing table if there are users is working so if users is not empty show table else show whoops no users were found you can see that it's actually working because no users exist with this search term we need to also make sure that these work right and these are just as easy to do so right here is the selector for which field to sort by and we can use wire model equals to sort field and also down here we have sort ascending and the way this works is we can use wire model equal to sort ascending and you'll notice that the sort ascending value within the component here this public property i've actually hard coded in one or zero for ascending and descending one will evaluate the true zero will evaluate to false and we will respect the boolean type here so it will work and lastly we can actually set wire model per page and now we can search let's say a okay which will bring up a ton of records let's say a n so it's finding a n in every record we can sort by name which is done in alphabetical order we can reverse alphabetical order so it'll start from from backwards and we can change how many records show up on a page so right now i've set to 25 there's less than 25 records so there's no pagination links but if i go back to 10 and click next it'll show the next 10 which is great and there's no more records to show so this button doesn't work so that actually is perfect so we have a working data table this is exactly what we wanted now the next step is actually getting these when i select them to do something my decision on what to do here is basically i just want to have a button when i select this to be able to delete these records and so what i want to do is repurpose the per page thing here i'm not really interested in having this here just for this tutorial because it's pretty simple and i'd rather just have a delete button here so i'm just going to remove this and in its place paste in a button that i i've pre-built because detailing how the tailwind css part of this tutorial came together would take way too long but this button is styled in a way to replicate the style of all the other form elements all i've changed basically is just change background to red 500 and the text to white if i refresh here we get a delete button which is awesome so we have something to delete with as soon as i wire that up and make a method for it that will delete selected records but before i do that i need to be able to select the records i want to delete in the first place and i think for the purpose of this tutorial i'm going to try to increase the per page to 25 so maybe we have some more data to test with and i also want to create a new public property called selected which will be set to an empty array the cool thing about the way livewire's wire model works is that you can set the same wired model binding on multiple check boxes and what will happen is if you have multiple check boxes selected it'll add the value of the check box into the property as array elements it's going to be very difficult to demonstrate this maybe i can show you as we work through it so i have the check boxes here and within the within the users table and it's just a basic check box nothing else has changed what i want to do is i add a wire model and bind it to selected the public property i just created and i also want to add a value and now this value has to identify the record that is being selected so that i can then find that value and remove it if delete is clicked and now what better way to do that than to basically identify this record by the user id so user id so the way we make this work now that we have the wire model selected uh binded here and we're passing in the user id as a value which is the best way to track which record this is the way we want to output this and i think this would be the best way outside of maybe dumping it inside the render method is to just set up the method that we'll we'll need for deleting records anyways inside of the component class so i'm going to call this remove users maybe delete users would be better now we don't need to pass anything in but what we could do is just dd which is die and dump selected and this will just output the selected values stored in here and then we'll see exactly how this works we'll just need to bind this button to the component action there so this would be wire i believe click is equal to remo delete users so when this button is clicked it should fire off this action here and we should potentially see it work let's see if we check a bunch of random ones here and click delete and that's perfect we get the the ids of the records we're selecting and just to make sure one two five six this would be one two five and six it works exactly as expected now it's just a matter of looping over these users which we don't actually even need to do because laravel includes a way to delete multiple records at a time if we just use user delete and pass in this arrow selected or maybe destroy i believe destroys equivalent destroy so if we destroy if we look into the source here allows allows us to pass in multiple ids and since we have an array of ids here we might as well do exactly that if we go back to this page here refresh and select one and two and click delete one and two is now gone if we look inside of our database here you can see that one and two records are gone i'm going to delete records with id 11 12 13 and 14 delete let's see so 10 11 12 13 and 14 are missing because we only have 10 and 15. so it's doing exactly what we thought it would and i think this works pretty well so that's it for this tutorial i believe once again i'd like to thank all of you for subscribing it's a huge help and i hope this was helpful please do let me know if you have any ideas for future videos and i hope to see you in the next video thanks for watching
Info
Channel: David Grzyb
Views: 7,689
Rating: undefined out of 5
Keywords: livewire, laravel, building a datatable, livewire datatable, tutorial
Id: 9Q9wzm_8Dlg
Channel Id: undefined
Length: 23min 39sec (1419 seconds)
Published: Sun Dec 13 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.