We'll start off at the basic level and then we'll build it as we go through the workshop into more complicated features to, I guess, both servers. This is how you use AG Grid, but then also if you're looking to do something more complicated, I'll show you how you can do that and work with the grid. And then if you're planning on following along with the workshop, I've put a link in the chat to the repo which has the instructions in. So if you go to the main branch, it tells you you can switch through the different stages of the workshop. So for example, we'll start with the quick start and these will be the steps that we're working through. So you can either start from scratch like I'm going to do with the
angular CLI or you can follow along these instructions and switch branches. If you check out this repo, then in case you get stuck on one step, you can always get to the next starting point and carry on the workshop. And then also hopefully this will serve as a good reference for you. You'll definitely get to see what AG Grid is about. And I guess just before I actually start following the steps and creating the app. So this is our... I should probably introduce myself, you may be wondering who I am, but yeah, my name is Stephen Cooper and I work at AG Grid on the core team. So I'm one of the developers, I guess now, maintaining the grid, adding features, making sure our
documentation site is the best it can be so people have good success with our grid. But yeah, AG Grid is a
javascript grid, so anything to do with tables and features that you might associate with that, sorting, filtering, these are all the kind of features you can expect from AG Grid and much, much more. So we're definitely highly used in financial settings, but that's definitely not the only place we're used. So we can have got really good
performance, live streaming updates, some charting. So maybe touch on these things at the end of the workshop, but we'll start from the beginning and show you how you might be able to start using AG Grid in your own applications. So I think we'll get started from here. Just so you know, feel free to ask, stop me, ask any questions as we're going. If there's something which doesn't make sense or you want more information about it, because then I can go into it in more detail and make sure it's clear. So to get started, we're going to use the
angular CLI just to spin up a new workshop, or not a new workshop, a new application for us. So we're going to do that with ng new. Let's call it my app. And then we're going to set some defaults for us here. We'll set the style to SXS. We don't need routing for this app. And we're going to default the styles and templates to be in line. So that makes it easier to see during this workshop. But that's completely up to you how you would prefer to set up your own application or how it is done in your current project. So once this app has been created, I'll show you the steps that we need to add AG Grid into it. And this is using
angular 14, seeing as that is now the newest version. But in terms of AG Grid features, we're going to be supporting it back to A at the moment. And, you know, and definitely from nine, you'll still have support. So if your project has already been created on an older version, you know, we're going to help and maintain that compatibility. So if we come into our app and start, we should be able to see that we'll have the template app. We do. This is interesting that when you do it with inline styles or template, you get the old application thing instead of the new the new one. But we'll stop that. And now we're going to add AG Grid. So there's two packages that you're going to want to use for AG Grid. We've got our AG Grid
community. And this is all the free features of the grid. And then also, we've got AG Grid
angular, which is an
angular wrapper, which provides the type, which provides the
angular component, which enables you to interact with it in a
angular specific way. OK, so if we say we've got our
angular code and then also we've got AG Grid
angular and AG Grid
community. So those are the two packages that we'll need to get started with AG Grid. Now before we can get any further, we'll need to add the AG Grid module into our module code to import all the features. So that's AG Grid module. So with that, that brings in the component. Now let's start our app. I'm going to go into our app component and let's change this. So we'll get rid of the generator code. Now we wonder why it's not working. OK, so the component that we're going to be using is AG Grid
angular. So we'll add that in. And the main thing you need for a grid is, of course,
data and column definitions. So I'm just going to copy in some
data and also the column definitions to save me typing them out. So I've copied them from the GitHub repo that I posted in the chat. Let's go through this. So what we've got here is for our row
data, we're going to be looking at some Olympic medal winners. So we've got athletes, their names, age, countries where they're from, and then also how many medals they won at each of these competitions. And you'll see that our column definitions for the grid match the properties of our row
data. So you've got field athlete, that will be pointing at this field, age is that property and so on. So we need to pass these to our component. So we've got inputs of row
data. So pass out the row
data and column definitions. Now at this point, you're thinking, you know, is AG Grid completely broken, but we're just missing another setup stage, which is to give it all the following
css. So what we've got here, AG Grid dot
css, so this is the core grid
css. So you're always going to need to import import that, because that actually governs how the grid is structured. And then the second file here is a theme. So AG Grid comes with a few different themes. And this is the theme file for AG theme Alpine. And if we come back to our
angular grid here, we're going to tie the theme in with AG Grid. And also, we're going to set the style on this so that it takes up the height of our demo application. Let's just say 100%. And there we go. We've got our first grid. So you can see now our row
data, the three rows we've got are displayed and using the column definitions that we provided. So that's the basics of all the bare minimum that you need to do to get AG Grid started. And as I said, there are different themes, so we could change the class of that to be dark. And if we update the
css file as well to be the dark theme, you'll see you can have the grid in dark mode as well. So you could make that dynamic, because I know that's very popular for people to do to be able to elect users, change the styling. But yeah, there's a few different themes which you can see on our website, depending on what you're looking for. So that is that's the initial step. I don't know if there's any questions about that before I carry on to the next step and start adding in more
data and more features. OK, seems not. So let's go on to step two, which will be adding in some grid properties. So I'll be following through these steps now. So in most applications, your
data is going to be coming, I guess, from a
backend server. So we're going to do we're going to mimic that now with a local JSON file. So I've got this raw
data here, and I'm going to put this into a file in our application under assets. So let me just create a new file, raw
data JSON, and I'm going to copy this in. OK, so we've got a big file now with all of that
data in. So now we need to update our application to be able to use that
data. So the first thing we need to do is use the
angular HTTP client. And so we need to import that module first, remembering to do it from
angular. Here's the client module. And now in our app component, we can now inject that in our constructor. So we've got our HTTP client. And I think we'll do this. We'll load the
data in ng on a net. So let's implement that. So there's two ways, I guess, of how we can get this raw
data. So the initial approach that you might want to do is simply say this HTTP. We're going to get the
data. It's going to be in the shape of an array. So I'm not typing our raw
data at the moment, but that's something which will probably become more important in the next release. Because then we'll be able to type the raw
data and give you auto completion throughout every place that you use it. And we're just going to say, get it from our assets. OK, and then we'll subscribe to that. And then this. And then you can see we're now getting lots and lots of
data. But we might not want to do it this way and where we're subscribing within our application is it's probably better for us to have
angular manage the subscription. So what we can do instead is we could make this a observable and we'll use the async pipe. So get rid of the hardcoded
data. And then we're going to we are going to assign that. And then at least we don't have to write this subscription and we don't have to remember to unsubscribe from it. And then just to show how a grid handles it, because we're not here. We don't have a big network delay, but we could mimic that and see what would happen. And also, I'm not going to spend too much time, you know, dealing with the error cases. But let's say we have a delay there so you can see we see a loading and that's default. You can you can override that as well with your own component. But then we've got our
data loaded and we'll be ready to add some more features to the grid. Let's remove the delay for now. OK. So the next thing you might want to do. With. With this is to be able to sort the
data. So currently, you know that there's no sorting functionality and that's because we haven't enabled it. So to enable sorting, you can come on the column definitions here. And for the columns that you want, you can say sortable and set that to be true. So now we set that on athlete column. So if we click on the header, you see, we can now sort by the athlete column. So before we then think, oh, I have to copy and paste this onto every single column. You don't have to do that. There's something called the default column def. So we can add a property here called default. And that has the same interface as column definition. And this enables us to say we'll set sortable on here to be true. Can remove it from there. And then pass that to our grid as the default column def. What we should see is that all the columns now share this default column definition. So we should be able to sort by age, country, year. And see who won the most gold medals. So the default column definition is a great way of reducing, I guess, what you could call boilerplate and having consistency. Features across all the columns. So, like, we could also say filter, set that to true to get the default filters working. And then you'll get this drop down and we can say, well, let's have a look for block. And then you can see that's working. And then for age, you can see by default, it's just a text filter. But you can see these things. OK. So next, there's more ways that we can configure the grid. And one of these things that we might want to do is we can say there's an animate, animate rows option. Set that to true. Which now means, you know, when you filter, sorry, when you sort them, you'll get a nice animation while you're sorting. So we tried to make a grid as configurable. So if your users like
animations, you can have that on. Or if you want them to have reduced motion, then again, you can have that switched off. But it says within your control. So these are all inputs. But now there's a lot of ways that users might interact with the grid and that you want to then be able to do that. But now there's a lot of ways that users might interact with the grid and that you want to then be able to respond to in your application. So maybe we want the user to be able to select a row. So we can enable row selection. And for this, we're going to say multiple. There's a single or multiple. So with that enabled, users can now select rows by clicking on them and say we want to get the the row that they've that they have selected. This is where we need to start listening to grid events. So now there's there's a lot of outputs and so we can see selection changed. Let's create a handler for that. Which will take the event. Add a selection changed. And now the event, the format for this will be in terms of the interfaces is whatever the name is, there's an interface for that. So we will know that it will be a selection changed event. And then that will give us the properties that are available to us on that event. So on this one is actually any following ones. But what we can do with that is log those out. Use the
api from the event. We can get the selected rows from the
api and see how that changes. So I don't know if that might be a bit small. So you can see now when I'm changing the selection and we're getting the selected rows. So then that way you can use the grid to be a bit more of an interactive interface if you want. Where users would select something and then perhaps they'd say either save or send these. So there's lots of different events that you can do. Now you might be thinking, why do we have so much space for these columns? So can we improve the display there? So there's different ways of doing this. So, you know, you could set a width explicitly and say, I want that column to be 100 pixels and bring these bring these in so that you can use the full screen space that you've got. Or another way of doing that is to hook into grid events and also the APIs. There's an event called first
data rendered. And so with this, we can. Let's create a handler for that. Again, it would be first
data rendered event. And here. We're going to use the column
api and auto size all the columns. So if we do that, you'll now see once the
data is loaded, it's auto size the columns. That way also has the columns that are displayed in the grid currently. Which gives you a slightly more compact notion. So if I uncomment that can see the difference. So it's it's kind of up to you as a user, as a developer, how you want the grid to behave. Do you want users to change the widths? So we haven't enabled that at the moment, but we could come to our default column definition, say resizable. So that's true. And then that will enable users to change the column widths themselves. Or you can use APIs to to do it for you. Do you have any questions on that so far? OK, so another thing that I'll demonstrate here before we add more features to the grid is how you can get access to the grid
api, which enables you to say, let's let's add a button above the grid. And we're going to use that to clear the current selection. So. Selection. So at this point, we don't have access to the grid
api. So we're doing of getting that is via a view child. So if we do. Use the view child. And pass it the component AG grid.
angular. Type that as the grid. Typing happy. And then down here, we can say AG grid.
api. Deselect. So now if we. Add a selection, we can say clear the selection and you can see we've now. Use the grid
api that we've got via this view child and to be able to access the grid and interact with the grid virus
api. So there's an
api api and column
api. And just to give you a quick idea of the things that are available to you on that on our
documentation. These are listed under this interface. So. You've got the full list of all the grid options. As well as all the methods that you can call on the grid
api and column
api. So we are
documentation is, you know, has the exhaustive list of the things that you can call. Okay. Alright, so then if we go on to. The next step. I don't think there's. Any more questions at this point. And that will be to add some styling to the grid. And so now I'm going to show how you can style these columns, maybe to have their gold, silver and bronze colors. To make those a bit more interesting. And just to make this easier on this smaller screen. I'm going to change the order. Of the column definitions to bring them. In line. So as you see, by default, the order in which you provide the column definitions is the order in which. The grid displays them, although it is possible for users to drag the rows around. Again, that's configurable and you could you could suppress that if you want. Right. So the first way. And is be able to. Add a cell class. So we could say metal. Gold. And then let's do the same for silver and bronze. Silver. Right. So as you can see, nothing has changed yet, and that's because we haven't specified these
css classes. So I'm just. Getting those so I can copy them. Now you might think. Your default response might be to put them in here. In the application styles. Like this. And then you might be confused about why this isn't working. So we've set our style here with the background colors and referred to it in our cell class. But the problem with this is due to style encapsulation. So by default, styles that you define here are only available to
html elements that you define within your template. And because the cells themselves are being rendered as part of a grid
angular component, the styles you apply here don't get picked up by them. They're encapsulated here. So if you do want to define your styles here. On this component, you can change the encapsulation to be. View encapsulation none. And that means those styles will be applied globally and you can see we're now getting the styles applied. But then if you don't want to change the encapsulation of your component and then these styles will need to be defined. Externally to component. So I'm going to put them in here. And then you can see because they're defined globally, a grid is correctly or they're being picked up and we're now displaying the styles. So again, that's that's going to be up to you and how your application is set up about how you want to manage where your styles are defined and whether you want to turn off encapsulation or not. Yeah. But then say we've got another request where we only want to apply the colors where they've actually won some medals. So, say, for example, here where silver and bronze is zero, we don't actually want to apply the color. So we can update our cell class to be conditional and the cell class and actually take a function as well. Let's start with the gold one. Let's take some parameters. Cell class params. And so in this parameters, if the value of the column is greater than zero, then we'll we want medal gold. Otherwise, we don't want anything. And so now you can see where zero that the class isn't applied where there are more than zero. It does apply. And there's a few different ways of applying these styles. And so you can also have something called cell class rules, which does it in a slightly different approach. So for this one, it takes an object where you give it the name of the class and then a boolean value as to whether to apply that class or not. So this would be medal silver. And then once again, we can give this a function. Cell class params and say if the params value is greater than zero, then apply that class. So you can see for silver now zeros don't have the style. And you can go one step further as well in terms of if you want the code to be even more concise as we support some expression syntax. Which works like this. Replace this with X greater than zero. And that's because our AG grid knows how to interpret this expression. And the details of that, I guess, are on our
documentation. Coming to styling, styling cells. You can see this is the expression syntax that we have available to us. So X is the value. You can also have
data if you want to apply styles based on multiple columns or that
data row and so on. But yes, now we've got our grid and we've added some styling to it. Hopefully that's making sense. Or does anyone have any questions about that? Or do they want me to show any other ways you can update styles? Okay. So, so far with this AG grid and this grid, we're using pretty much all the default ways of displaying
data in the grid. But a very powerful feature that you might want to use, depending on your project, is to be able to replace the individual cell renderers that we've got here with your own
angular component. So, so far this is just using a string representation, but we can put our own component in here. And to demonstrate that, let's stop the application and we're going to use the CLI to generate a new component for us, and then we'll use that as a cell renderer. So, let's do ng generate cell. So, that's created us our component. Now the first thing to do before we can use it as a cell renderer is to implement the AG grid interface. I so renderer
angular. And this has two methods that we need to implement. You've got refresh and also AG in it. So AG in it is common across all of our components. And it's the method which is called by AG grid to initialize your component, and it will be called before engine it is called and so slightly different to the
angular lifecycle. So it's our way of interacting with your component after we've created it for you. And so let me just clear these out for now. Start up the app again. Okay. And then if we come back to our app component, we're going to say for our age, instead of using the default renderer, let's use our component to render it. So we use cell renderer, and we'll pass it our cell component. And now, if you look closely, you can see we're now seeing cell works and that is because that's what we have in our template here. So that's not particularly useful, because you don't want you probably don't want the same thing appearing in every single cell. So how do we go about actually then updating this. So this is where this agent comes in. So first of all, let's add a value here, value property. And we can say number, because we're using in the age column. And then we'll get that from the prams. So we either have a method say get value or you can get it directly from the
data and that will be the row
data. So let's do that for now. It can sometimes be null if you're doing row grouping, which I'll touch on later on in the workshop. And then we'll say age. And then we can update our template. To use that value. And then you can say, let's just add. So you can see we're now displaying the value as it's coming from the row
data. Okay. Hopefully. It's all making sense. Now, there's one thing which you might say, okay, well, we've hard coded a lot into this component. What if we want to create a shareable cell component that we can use across multiple columns? And that is something which is very possible to do. So, for example, maybe we had this as age. Now, if we're going to use that for the athlete column, that wouldn't make sense. So we could add to come in here and add the cell renderer. Cell component. And you can see we've now broken our grid, which isn't ideal. And so that's where we might want to come in here instead of using
data. And we might want to use the get value function. So if it's got that then. Get the value. Otherwise, we'll just leave it undefined. And now at least we're getting the right value. But as you can see, this this label is still hard coded, so we need a way of parameterizing that. So the way to do this is as well as having a cell renderer. You can also pass in parameters to your cell renderers. And that goes in this format. So you have cell renderer params. And let's say we're going to give it a label. And call it well. We'll just say label and give that say this would be that name. And then we can do the same thing for. The age. Say age. And to use these parameters will come back to our cell component. And then we'll add a label. Defined. So that's a string. And then here. So this label equals. Params label. But as you can see, label that I sell render params doesn't have a label property because that's our own custom one. And so what we can do is define an interface. For our cell component. Which then tells people actually this component understands the following interface. And then we can use that here. And the compilation now works. Label and then actually use that in our template. And then now you can see we've got name and age, which are the parameters we've provided here. So we could have added code on there. And we can see that. Then. Let's see. Has anyone got any questions or thoughts or can they see how that might be useful in their project? Do you want to drop me a comment? Let me know you're still there. So quiet. No comments. All right, I will carry on. So then another way which you can use these components in a more dynamic way is you might have components that you want to display based on the the row
data itself. So let's take age column, for example. You might want to have two different components, one for, say, if they're above a certain age or one if they're below a certain age. And we can do that with a cell renderer selector instead. But before we have that, we'll need two different components to switch between. I'm going to do some copying and pasting to save me typing things out. To give me an over and under component. Let me correct that interface name. Okay, so. I've now added an over component here and also an under one. So if they're under, we're going to highlight it red and green over. And we're going to decide which one to use in our component itself. So now, instead of having a cell render and cell renderer params, we can have a cell renderer selector. And this takes, again, a parameters object. And so inside this method, we're going to check the age column. So we can say if params
data. So first, we're going to check if it's
data, because if we're doing row grouping, then there won't actually be
data on this row. And we'll see that later in the in the workshop. And then we can say if params
data age, let's say if it's greater than or equal to 25, then we're going to return our over component. And so we do that with this format. So the component is going to be over component. And we can pass params to that as well if we want. And so I think that had label on it. Let's say over 25. And if they're not, then we're going to return. And then if they're not over 25. Instead, we're going to return the under component. So it's a component. It's empty for now. And here we go. So we haven't provided a label here. Let's put a label into this value. I just muted you. So getting feedback. Okay. And so now we have, what do you want? Did you want to ask a question? Okay, I'll carry on. So now you can see we have different components. So we've got the over component and the under one. So they're both in the same column definition. But we're dynamically selecting which component you want to use. So, I mean, these are all, you know, potentially, this isn't exactly what you want to do. But I hope it gives you the idea of the power that you have using azGrid to customize it and work within, you know, in
angular. Hopefully, that's the framework that you're understanding and that you're confident in. And so this is just showing that you can use
angular components within azGrid itself, which is a really nice, nice and quite powerful feature. So we've got that. Can you give me a thumbs up if that feature is potentially useful? Yes, thank you. Cool. So there's one potential downside of, well, not downside, I guess one limitation of this approach of passing in components directly to column definitions. Is that sometimes you might want to store your column definitions on a server, for example, or you might want to dynamically retrieve them and say, if it's this user, they can see these columns. Or maybe if they're a power user, you can also have all these other columns. And to do that, you might want your columns to be JSON serializable. But if you try and put these actual real components in, then it's going to have a problem with that. And so there's a way around this, which I guess just involves a little bit extra code and you apply a mapping so you can provide a components object. So let's say we've got a cell com and that will be our cell component. We could say over represent our over component and under. And then in the cell renderer property, instead of giving it the actual component itself, you could give it a string cell com. And likewise, in this dynamic selector, instead of that, you could have over and so that you can have under. Oh, yes, it says AG grid looking for component, but it wasn't found. And that's because I haven't passed the component map to the component, the AG grid component. There we go. So now we can see we're still getting the same behavior. But now if we go to serialize this, you'll get the property cell render and cell cell comp. So it's a nice way of separating your components from the column definitions themselves. But if you don't need that feature, then it's very convenient just to be able to pass in the components themselves. OK, so I think that's cell rendering done. The next bit I'm going to go talk about is filtering. And also, it's worth remembering that everything I've demonstrated so far is all completely free to use as part of our
community edition. So you can just start using AG grid
community, include it in your project, run it in a production application, and it's all under the MIT license. So there's there's nothing to pay. And so you can get all of this completely for free. Yes, it is. Right, filtering. So, so far, we've seen that the default filter is just a text filter. But that's not so great for for these numbers here. So what we're going to do is look at the different filters that we have available to us. And that's done in a similar way, you know, by saying what filter we want it to use. So if I come over to our
documentation, come to filtering. We look at our provided column filters. We've got text, number, date, they're all part of the
community edition and set filter will look at when we enable the
enterprise features. And so for our medals, we're going to be wanting to use the number filter. So we'll come in here and the name is AG number column filter. So now then, if we look at the gold column, you can see we've got equals, less than, greater than. So this this gives us a better way of controlling and working with numbers so you can say more than five. And that's now correct. So let's tell me we could add that to silver and also to bronze. And those will all be now filtering as if they're numbers. Now, the one I want to have a next look at is the date one. Because, you know, working with a string, they can be a bit tricky. So we can enable the date filter there. So the filter AG date column filter. And now you can see we've got our date. So if I enter the date 2408, 2008, it's not actually working. I'll give bonus points for guessing why. But if we have a look in our network tab and look at the
data that we're actually getting, we'll see that date is coming in as a string. And so that's quite common. You know, when you're getting
data back from an
api, your date values have come back as strings. They're not actually
javascript date objects. So there's different ways that you could handle that. You might have parsing logic in your, I guess, your service, which is returning the dates, which maybe has converted them into
javascript objects. But if you find that your grid has string dates, then it's possible to provide a comparator function to the filter in the following way. Let's do that here. So as before, when we had cell renderers, we could pass cell renderer params. There's a filter params object. And so we've got filter and then we have filter params. And then one of the options on there is a comparator, which is saying the date from the filter, which comes in as a date, and then the cell value, which is a string. So then this code is specific to the format of the date that our
data is set in, which is, if we have a look in our row
data, you can see our dates are in this format. Double digit with slashes. So that's what this comparator is splitting on and then enabling us to create a date and say whether it's greater or less than it. So now with that comparator added, let's try and do the same thing. Let's try and do the same thing. 2408, 2008. And you can see now our date filter is correctly working. You can say after that day or before. And it's working. So the reason why the date filter doesn't automatically just get that right is because date formats can be so different. And that's kind of like application domain knowledge. But you can override the comparator to be able to get the functionality that you need. Right. But as we might want to make our lives or not our users lives easier than having to toggle out this this filter icon, there's something called a floating filter. And so if I go ahead and add that to our default column definition so it goes everywhere on all our columns. What you'll see now is this adds a new header part to the header, which we can filter on. So we can now just type in here and it will do a string match on that. And this is quite a nice way of just making it easier for users. So they can open the filter here and maybe they can change it to less than. And then it will remember that behavior for the value you're putting in. So that's the floating filter. But then you might be wondering about this age column, because it looks like the way we've set up our application is to be able to have either they're over or they're under. So maybe we want to be able to toggle the filter as opposed to say, well, are they. We haven't set the number filter there anyway. So it's what I'm saying is we can provide a custom filter implementation to this column and use that to control things. So once again, let's use the CLI to generate the component for us. The NGG component age filter. So then like before, we're now going to be implementing the filter interface. And I guess just to give you an idea of the components that are available. These are. So we've done so render and we're now going to look at filter component and but you can see there's a lot of other rooms, I guess, or places where you can customize the grid. You can either have a custom floating filter, header components, tall panels, tall tips, or even editors. So there's a lot of hooks or a lot of ways for you to provide custom implementations to a grid. But we're going to do the filter component. And so that is going to implement. I filter. So there's more, more properties here to implement than on the cell renderer, and because it's doing a bit more. So the logic that we're trying to achieve here is have. Is have like a radio button so that we can say it's either under 25 or over 25. And so we'll have a start implementing this so we can say is over limit. That's either going to be a Boolean or undefined if we don't want the filter to be active. So that's so we need to say when the filter is active. So that's going to be when is over the limit is either explicitly true or explicitly false. True. And then for whether the filter passes. So this is the logic that will be executed for every row item that we've got. And so this will be well if. If this is true is over the limit. Then I guess we're going to judge it on whether the params.
data.age is greater than or equal to 25. And then. Otherwise, if. Is over the limit is explicitly set to false. Then we'll do. Params.
data.age is less than 25. And then otherwise we're going to return true. So just so that we don't filter things. When it's not active. Right. And then for get model. Get model is it returns the model for the current state of the filter. Null if it's not active. And so the grid is going to be calling this. And so what we'll do here is we're going to return. Is over the limit as our. It's an object for that to be our model. And then in the set model. We then this method can be used to initiate and or initialize the filter. So it's going to be. Well, we need to be careful here that we do get it right. So. Here we're going to type this as. Is over. It's a boolean. So I guess if the model. If that is true, then we can say this is over limit equals true. And if it's explicitly set to false, then again, we can say. That we set it to false. Otherwise, we're going to set is over the limit to be undefined, which says that our filter is selecting everything. So the link again. Okay. And that's well, that's the specific link to where I'm up to at the moment. Now else. If the model is over the limit. False. Otherwise, we're going to set is over the limit to be undefined. Okay. And then here where we're getting our age unit. Bring this up to the top. So that's going to be called first. It's passing us this parameters object, and that has a number of callbacks on it, which we all need to use once we implement our filter. So we'll take a load call. Let's store it locally. Okay. And now let's take our age filter component. And where is our column definition for our age column. Here it is. So we'll say filter. And we can pass it that component. So now, when we open up the filter, we're getting age filter works. So now we need to actually hook our filter up a bit more. And I think to save you watching me time, I'm going to copy it in. And then I can talk through. So what we've got here is some radio buttons. So one for all one for under one for over. And when you click on that, we're going to call this method on filter changed. So let's implement that in our filter. And this is going to be Boolean or undefined. And we're going to set that to be our model. Okay. So now you can see we've got our custom filter here, all under or over. So the toll is working, but you can see our filter isn't doing anything. So this is where the prams come in. And you need to say filter changed callback. So this is a way for us to notify as you grid that, you know, my filter has been updated. You need to run your filter in logic again. So now, once we've added that in, open up our filter, see under and over. So it now looks like it is doing the right thing. And if we clear it, we're getting that right. So you can see the component is reused in both the filter floating filter and that part. Okay. So that's how you would have a custom filter as well. I mean, my styling isn't the most beautiful, but that's I guess that's not what we're trying to demonstrate here. It's more how can you hook this into AG grid? I guess another thing which I could demonstrate here is the way in which we can get filter models and also set filter models. So you might the use case for this is say a user might be updating filters and you want to be able to kind of save that state or save their preferences. So it's possible for you to to have a method which retrieves that filter state and then also can set it back. So instead, let's update this button here. Clear selection and let's reuse it to be you get the filter model. Okay. And then here, let's do let's just print it out for now. Get filter model. Okay. So if I call this now, you can see it's an empty object. Now let's say under and say get filter model and seeking this is based on. So you got column and then is over the limit. So this is what we return from our get model here. So then we can see if we set that to over and then get the filter model. This should now be true, which is. And of course, if we set these sets less than five medals and get our filter model. So now we've got age and we've also got gold to the gold. It has more information. So this is the age of grid filter, which is saying what filter type is type of the filtering and also the value. Right. So then let's pretend that we're going to save this. To local host that can be our server. Or local storage. Filter state. So let's say we want under and we're going to guess it's not really get is it save filter state now. And then let's have another method which will then restore the filter state. And so we will. Did the opposite. So it's this top grid, a degree
api. Set filter model and we'll just take that from local storage. Okay. Let's add a button for that. Restore the filter state. Okay, so if we do this right, we'll go under, let's say, gold has to be less than three. And we're going to get the filter filter model then say we refresh the page. Set filter model, no column found. So let's check what got stored in local storage. That's not what we wanted it. Okay. Okay, that's looking healthier. And let's say that we want it to be less than five. Okay, that's in there now for you reset this and then restore the filter model. Of course, we'll now need to pause it as well. There we go. Well, not quite, is it something not quite working. Let's have a look. Let's see what model we're getting back from the age is over the limit equals false. So that looks right. We're setting the filter model. It's not filtering. Would you like me to carry on debugging this or move on to the next features? Let me know in the comments. Move on. Okay. All right. So yeah, so there's something maybe just slightly off and how we're setting this model. Yes, debugging can take a while. Yeah, so I would check what was coming into here and then see how that was, why that wasn't updating as we were expecting. Yes. So is it does anyone have any questions about filtering or, or the other kind of things you might be able to do with 80 grid filters. No. Okay. So then, the next part, which I look at is seeing some of the
enterprise features. So to do this, it's now, we do need to add in a new package now, 80 grid
enterprise. And because we've separated what you can have with
community and also then, if you want to have these
enterprise features which adds in a lot more functionality to 80 grid. And then for the
enterprise features, you will need to purchase a license license. But I think it's worth seeing some of the features that, you know, will be available to you. So if we install 80 grid. Surprise. Okay. Application, we need to do is import 80 grid
enterprise, and that will enable all those features. So as you can see now we've got
enterprise but we haven't set up our license there is some console logging to say, please buy license. But now there's some of the things which you can do is now when we're right clicking you'll now get this method which can use to copy
data, or you can export to CSV or Excel. So there's a whole new set of features which I could actually show you from our
documentation. So there's a feature comparison. So as you can see most things you do get in
community, and this server side row
data which can get an
enterprise, and a few more things in
enterprise in terms of range selection are set filter which I can show. So now, editing and all the normal displaying that's that's available to everyone, grouping and pivoting, and of course, important export and then there's some other tool panels and sidebars and aggregations. And that again come with a grid
enterprise. So, if we come back to our component. So you can now see that when we open up athlete, we're now using this, the
enterprise set filter. So you get that set up as default to enable you to do things like this. Select them all. Interesting. So you got the set filter. And there's, there's different ways that you can configure that as well. Right. Another thing, which I think is quite popular is row grouping. So, to do that, and especially if you want the user to be able to do it. There's some properties which you need to set up. So, one of them is the row group panel show, and we're going to set that to always show. So you can see here that's now given us this area where we can drag rows into to be able to group them. I'm going to clear up some of this code to make it easier to see what we're doing. I'm going to just comment this out for now. Let me bring my country column. Yeah, let's bring those back to the top. Okay. So, so we wanted to group by year, so we can't currently do that. So you need to add some properties onto your row groups. So we've got enable row group. And if we set that to true on year, that will now enable us to group by the year. And what you might want to be able to see here is that, well, how many gold medals or silver medals did they win and have that aggregated up. And so that is something which we, we then need to set up on those columns to say actually yes, and aggregate the function using some. So if we do that, it's probably called aggregate function. And we're going to say use some for all of these ones, all the medal ones where it makes sense. And then if we group by year again, you can now see that we're having those columns have been summed up to show us what, what's there, we can expand these and drill into it. So that's kind of a quick grouping. And while we've got that group on actually. Let's enable. Let's say we're a group by true so I don't have to keep setting that myself. And then I'm going to enable charts. As well as range, range selection. Without setting anything gives them value true. Now if I come in here, select all, you now have an option to do some charting as well. So for example we can see here, just like that you get what gold silver runs in the total. And also, we can come in here and configure what we actually want to display. And then let's say we group those by, we can change the order and you can see how it is linked to to the grid, and which now has kind of instantly revealed some oddity in our in our
data that seems like every other year that number of medals one has changed. And so these are the kind of analysis tools which you might be able to then, you know, provide to your users and give them this flexibility. Not only do we have the grid but the grid comes with integrated charting features as well. So this is the same person I used before I worked at azgrid, which went down very well with my users so I just said enable charts and suddenly you had all this functionality available to them. So all pie charts. And there's quite a lot of different things you can do that. So, I'm thinking at this point, to make this as useful as possible for you, like to get. If you'd want to give me some feedback in terms of what specific features you might be interested in and then maybe I can focus on those areas, as opposed to maybe demonstrating features which might not be applicable to you. So now's your opportunity to ask what ask any questions or point me in the right direction otherwise I'll carry on and demonstrate some more features. Okay. Okay. Would you like me to focus on what you can do as a
community, or are you interested in seeing the more
advanced enterprise features that we've got available. Okay. Let's do some more
enterprise features. Okay. So, I think that's some space here. So, I mean, I think, before I do this what this is something which is kind of like specific to
angular. As you can see our
angular component here is getting quite large and, and it's getting difficult to see, you know, exactly what's going on here. And so this is where I think, as a, as users we can take advantage of the grid options property, which contains, you know, exactly the same interface as the component itself. So we can actually create a grid options here and say, grid options. And it will enable us to clean up our template. So let's say, see if they enable the charts. So that's true. So instead of having these defined on there, we can bring things into our component and pass these all together as one. Say like the road group panel. Always. And another benefit that this gives you over defining on the template itself is that it will enable you to reuse. I guess your grid options as a
javascript object, like you could, you can have a base object that is shared and you could, you know, spread, spread that into these grid options and straight away you're reusing a lot of these settings, without having to then copy them onto the template itself. So, when I was working with a degree and I definitely like to have this mixture approach, where you can define pretty much all your static options, you know that aren't really going to change on this grid options and just pass that. Whereas it's very useful to be able to take advantage of
angular, you know, the async pipe for something like the road
data where that is, is, is changing. And you can do the same for column definitions as well, you know, you can have a toggle there and have your column definitions come through a pipe and the grid would, you know, automatically respond and rerender those columns based on the column definitions that you're providing to it. Okay. So another
enterprise feature is a, we can have a sidebar here. And if we look at this, so you can be a string or array of strings so I know that we can have either columns and filter. So now we have this sidebar, which has appeared here. So we've got the columns one and so now you can see we've got the ability to be able to move columns in here, and they will be reflected in the grid, you can hide. So, for, it gives you another way of doing row grouping as well. Well, you can group that by year. So it's another way of interacting with the grid, and also you've got the values there. As you see, we can also do pivoting. And so if you know how to do pivoting and want and use that as a feature. You can do that. So now we've pivoted, we can see we've got we have kind of pivoted. And there's a few more options you might need to set up to do pivoting on the column definitions which I'd refer to the
documentation to do. And also then on this filters panel that you get. You could, again, work with the filters on this panel instead of having maybe floating filters here so it's giving you another option of how you want to, I guess, your users to work with the grid. And then there's nothing to stop you providing your own custom components into these areas as well, which I can show for you now. Let's go in here. And so if you kind of come under components, we can see we've got this tool panel component, which I think is actually ready for our example. So yeah, so we let's copy this one the custom stats. And so if you haven't been on our
documentation site, this is probably something worth going over we have all these live examples. So you've got the rendered output. And then also there's the code here. And you can also go and open it in Plunker. So this is where I'm going to take this code from. And we can incorporate it into our app. So let's come in and let's add a new file. Custom stats. Seems to have compiled. Let's see. Then we can have a look in here and see how you know how is it that I would use this in my own application. So you can see it's coming in here as part of the sidebar definition under tool panels. So this is a sidebar. Let's give it its full definition instead of using the shortcut. This is an array. So I believe we can do this. Let's have a look. Yeah, it's either a string or it's a full definition. So we've got our columns or filters. Rachel, are you trying to ask a question? Let me know in the chat if you are trying to ask something. So I'm going to copy this code off here and let's see. Let's go back to our application. Custom stats. Can't find the gold. More debugging. So it looked like we had the same shape
data as this example. Gold, silver and bronze. Let's see what's going on. Oh, it's because we've got grouping on. There we go. So take the grouping off and we're now getting the total medals displayed in the grid. And I think this works with, let's say, if we do some filtering. It doesn't. But you could, there's nothing to stop you listening to these kind of events and saying when the filters have changed, update my custom stats panel. And go from there. So that's, that's the sidebar. Another element that you can add with
enterprise is this is a status bar down at the bottom, which is quite useful for quick aggregations and counts. So status bar. Let's have a look at this definition status bar here. I'm going to look under accessories because this comes with some default options for you. For example, like this. So then, you can see we now got the number of rows. And so this is to do with filtering as well. With that, let's filter this to the 2000. So it's now saying this many rows of however many and say we want to do some kind of aggregation there. Well, then, there is the aggregation component. Which if we just have a quick look at the code to make sure we get it right. So let's bring all these in. So we've got the total rows and many are filtered. If we start selecting the range, we've got averages, counts, min, max. So again, these are just, I guess, tools that you can use to advance your grid and make it even more powerful for your users. So that they don't have to maybe copy it and export it to Excel or do other functionality. There's a lot that you can do with the grid built in, especially when you've updated to use the
enterprise versions. OK. I'm wondering now whether Does anyone have any specific projects or ideas that they are working on or issues they currently have with AG Grid that I could help with? Or you are enjoying the demonstrating different features. OK. So maybe another area which we could have a look at is. Well, let's think. Maybe we want to be able to add new rows into our
data set. So that's something which grids are often used for. Yeah, so. How about we say, well, you know, this context menu, can we customize this and add an option here? Which when we click it, you know, we'll add in, we'll duplicate a row of
data, perhaps next. I think that would be quite a good way of showing how you might be able to use the grid and interact with the grid in its different ways. So. The way that I do this, that is, so this is the context menu. So you can come in here and look at how we might configure it to add a new item into the. And so it's this callback get context menu, get context menu items. So in our grid options, I'm going to get context menu items. I know this is a callback which takes some params. Get context menu params. And I know that this has a property, I think default items on it. So we could just. Provide that saying. Not a time to string the mod. So I think this. Let's just cast that for now and we can see that this is still still working. That's good. But then also let's add in our own. Our own custom item. So you can see this example has a custom one so you can come in here and say. Let's have a look at this one. We're going to return an array now with this in it as well as those. They come back to our app. So we've now got our alert. Let me take that row grouping off. It's saying United States, we can say. So we've got that same functionality. Now, what if instead of just saying that we want to say duplicate this row. So here in the action for when it's clicked. There's there's two. There's I guess a couple of steps here. First of all, we need to be able to get the row
data. And so we can get that from the parameters. Let's first of all just check that we've got that. So it will be coming from the node and we can say the
data from here. Right click here. Okay, yeah. So we've got the row
data there from our row node. And then we know at this point we've got we've still got access to the grid
api. So what we could do here is set the. This isn't exactly what we want to do. But it shows that you could actually set the row
data. Okay, so we've updated the row
data. But we actually want to do is just duplicate it. So here is what we probably want to do is take use of the transaction
api. And so this is something I'll show you here. And we're working with client side
data, where it's got updating, you can use these transactions to update the current state of the grid. So we're going to use this apply transaction, and we'll say, these are the roads that I want to add. So we've got our row item. Use the
api. Apply transaction. And we know that we need to give it an object which has. Add. Give it an array. Our row item. Come back to our app. So let's take this this row duplicate. We'll see where is it gone. So you can see our very count is going up, but it's probably appearing at the bottom. Yes, it is. And so we probably want it to appear. At the right index. And so we need to get the row index from this current node. No. Row index. And then let's say, add index. Let's use that row index. Okay, so now it is being added. And we've duplicated it and use our apply transaction to do that. So that's another, I guess, kind of way that you can, you can get access to
data off the row node. So you got row index where it's being displayed. And also the
data and then use the
api to then update the grid itself. So it's quite a lot of power that you can do via these context menus and also external methods. So let's show some more features which are quite quick and easy to add on. For example, I know in the description of this workshop, it talked about pagination. So I better show you how to do that. And that's pagination done. So you can see we've got one to a hundred on this page. And you can flick through the pages or go to the last page using pagination. Maybe I will demonstrate another of my favorite ways of filtering when you have lots of
data like this. So there's a feature called the quick filter. So we come back to filtering and there's this quick filter. So the quick filter is a very powerful way of giving your users just a single place where they can write their text and search, search every column. So it works this way. So you add in here and let's say Missy Franklin or you can search by the ages or you could say where they've got gold medal eight. And maybe actually they've also got a silver doesn't exist. But we can show how we might be able to set this up. So if we come to our component here and at the top, let's add a text box. And input. And that's changing. Let's say filter changed possibly event. Come in here and let's add in this filter changed handler. Just check off the top of my head what the event is that you get from here. So I think using the browser event. Any I'm going to take a quick look at this example. It's using the input event. This is why we put so many examples on our
documentation. Because it gives us a way of, I guess, you know, adding features and you've got working examples, and that you can copy from, and it gets you gets you going much quicker. Okay, it's actually getting the element ID and passing that through. I think we can probably use
angular to do this, can't we, with a form model. What's it called engine change. Let me just shut my window. My mind's gone blank in terms of what the Change around here is when you're using ngModel. Let me just use the dots again. Seems that's what they're there for. So it is hooked up. So we've got we're getting the values now. Let's say 2008. So the quick filter enables you to filter across all the columns at the at the same time. So you can say 2008 and let's say. Okay. So that's, that's a feature that I like quite a lot. I'm thinking that if there's nothing else in particular that people want to do, it might be worth us wrapping it up because I'm sure there's, you know, there's other ways that you can, you can view our
documentation yourself. As opposed to me copying from examples. I do hope that this has been useful in terms of how you know showing you what's possible with a grid and how you might get started and ways to configure it and, you know, do using the different cell renderers. And then there's all these other features that come with a grid
enterprise.