Getting Started with AG Grid and React – The Best Javascript Grid in the World

Rate this content
Bookmark

Does your React app need to efficiently display lots (and lots) of data in a grid? Do your users want to be able to search, sort, filter, and edit data? AG Grid is the best JavaScript grid in the world and is packed with features, highly performant, and extensible. In this workshop, you’ll learn how to get started with AG Grid, how we can enable sorting and filtering of data in the grid, cell rendering, and more. You will walk away from this free 3-hour workshop equipped with the knowledge for implementing AG Grid into your React application.


We all know that rolling our own grid solution is not easy, and let's be honest, is not something that we should be working on. We are focused on building a product and driving forward innovation. In this workshop, you'll see just how easy it is to get started with AG Grid.


Prerequisites: 

Basic React and JavaScript


Workshop level:

Beginner

140 min
11 Oct, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

This workshop is about AG Grid, a JavaScript grid with great performance and an ergonomic API. It covers installation, column definitions, row data, sorting, filtering, cell rendering, editing, and styling. The workshop includes exercises to practice hands-on coding. It also explores advanced topics such as value getters, formatters, cell renderers, and custom cell editors. Additionally, it covers persisting data, handling cell value changes, and styling cells and rows using cell classes, styles, and themes.

Available in Español

1. Introduction to Workshop

Short description:

Welcome to the workshop! Today we're learning about HP Grid as part of the React Advanced Conference. I'm Bryan Love, co-founder of Live Love App, and I'm joined by Mike Ryan. We're both Google Developer Experts and Cypress Ambassadors. We'll be taking breaks every hour during this three-hour workshop. Feel free to ask any questions you may have.

All right, like I said, welcome to the workshop. Today we're going to be learning about HP Grid as part of the React Advanced Conference. My name is Bryan Love and Mike and I are co-founders of a consultancy called Live Love App. We're both Google Developer Experts and Cypress Ambassadors and we like to contribute to open source. So anything you want to add there, Mike? I know I kind of introduced you as well.

Nope, just I'm Mike Ryan, also from Portland. Both heavily involved in open source, though mostly in the Angular space, an A-G grid space. We're gonna do just a quick housekeeping, just make sure everybody's in the same page here. We are all abiding by and under the code of conduct. If you haven't looked at that, that's on the React Advanced website. Scroll all the way down to the bottom in the footer and you'll see a link to code of conduct. So just please be aware of that and let's all be nice to each other for the next couple of hours and have a good time. We are gonna take a break every hour. So this is a three-hour workshop. We've got plenty of content, lots of hands-on exercises for everybody but we do want to make sure that we just take a break, give you an opportunity to step away, get something to drink, stretch. Kind of helps in the learning process, too, rather than just sitting in front of a computer for three hours straight. And then if you have any questions, Mike and I are here to answer any questions you may have. So go ahead and put those questions in the chat or you can just kind of raise your hand and let us know that you have a question.

2. Introduction to AG Grid Workshop

Short description:

The prereqs for this workshop are JavaScript and TypeScript, and basic React. AG Grid is the best JavaScript grid with great performance, extensibility, and an ergonomic API. We'll be using the AG Grid with React course on our website. All course content and exercises are available online using StackBlitz. We'll cover installation, column definitions, row data, sorting, filtering, cell rendering, editing, and styling of AG Grid.

The prereqs for this workshop are pretty easy. We just need to make sure that we all know and have a little bit of understanding about JavaScript and TypeScript, and then also some basic React.

As I already mentioned, AG Grid is the best JavaScript grid in the world. That's kind of their tagline. You can check out their website at ag-grid.com and kind of find out more information about AG Grid. They have some great documentation there, lots of great examples, et cetera. And so you might be wondering what makes AG Grid so great. And in my opinion, I think it really comes down to three things.

First of all, it's the performance of AG Grid. AG Grid is really fast and it's very well optimized for handling loads of data that you want to put inside of a grid in the DOM. It does all kinds of virtualization of columns and rows to make sure that it doesn't, you know, slow down the frame rate of your application. Make sure you get some really good performance out of your web app.

The next thing that I really like about AG Grid is the extensibility of it. Well, AG Grid comes with a ton of features out of the box. What's nice about AG Grid is that through using components, we can extend AG Grid to make it kind of customized to whatever app we're building. So if we need a particular cell to display something really interesting or really interactive, we can do that. And so the extensibility of AG Grid is fantastic. And so they've built the product with a large feature set, but also with the extensibility, knowing that you're going to want to kind of customize it as necessary.

And then finally, I really think that there's a nice ergonomic API to AG Grid. It is a very large API. The surface is very large, but once you kind of get used to it, the naming conventions are fairly easy to kind of understand and almost kind of guess. So the ergonomic API makes it a great product as well.

So today we're going to be using our website, lidloveapp.com, courses. So if you go ahead and pull that up on your browser, you should see that we have a couple of courses listed there. This is technically like a private page, but we kind of believe in security through obscurity. So feel free to pull that up and choose the AG Grid with React course that's in the middle, and that's what we're going to be using this morning or this evening, whatever time it is for you. And that's what we're going to be using today to kind of go through the course content. So all the course content is online and freely available, and will be available to you after this workshop. And then all of our exercises we're going to be doing online as well. So we'll be using StackBlitz in order to do that. So you don't need to have anything installed, or you don't need to download AG Grid or anything like that. We're just going to be doing it all on the browser. So with that said, go ahead. I'm going to stop sharing this screen, and I'm going to switch over to Chrome. Pull up little app.com slash courses. And when you do so you should see this website and then go ahead and scroll down and click on the Getting Started with AG Grid and React. And here's our table of contents for today. Like I said, this is going to be a three-hour workshop, we're going to take a break every hour to get started with. We're going to go over kind of how you install AG Grid with React. So real simple, we're not going to do that because we're going to be using StackWisps today, but just to kind of make you familiar with how simple it is to get started with AG Grid. Then we're going to be talking about column definitions. And we'll look at row data, row sorting, the default column definition and filtering. We'll then look at cell rendering and how that works. We'll kind of talk about the cell rendering pipeline. We'll be looking at using custom value getters value formatters and a cell renderer function. And then we'll get into cell editing. We'll talk about the provided cell editors that kind of come out of the box with AG Grid. Then we'll look at how you can create your own custom cell editor using a component and how we can persist data. And then finally, we'll get into the styling of AG Grid. So AG Grid comes out of the box with a couple of different themes, and you can customize those themes. But we can also take that a step further, and we can do things like cell styling and row styling. And we'll take a look at those themes and how we can customize them.

3. Installing AG Grid and Defining Columns

Short description:

To get started, install the aggrid-community and aggrid-react packages. Import the necessary base and theme CSS files from the aggrid-community module. Define columns in AG Grid using the ColumnDef object. Specify the header name and the fields of the row object to get the data from. You can also use deep references within the row data object using dot notation. AG Grid supports TypeScript with improved support in version 28.

So, did everybody get into the website? If you have any problems, my co-presenter, Mike, is also in the chat. We also are using Discord. So feel free, if you have any questions, you can also drop them in Discord. We'll kind of be monitoring both. Sometimes it's easier just while we're in the workshop together, just to use the chat.

Okay, great. You guys are missing sleep. So, will we create our own CMS? No, not today. We're going to just be using AG Grid with StackBlitz. And we'll be looking at examples of using AG Grid. So, let's go ahead and dive right in with installing AG Grid with React. Okay, so, to get started, you're going to install two packages. There's the aggrid-community package and the aggrid-react package or module, I guess. So, you can use npm to install those and save those into your package file. You can also, once you install AG Grid, you also have to kind of set up some of the styling initially. So, you need to import the necessary base and theme CSS files. So, in this example, we're going to import those from the aggrid-community module. Inside, there's a directory called styles and then we'll bring in the aggrid CSS file. And in this example, I'm bringing in the Alpine theme. So, you can see that I'm importing the agthemealpine.css file. Of course, as I just mentioned, we're going to be talking about custom styling and themes. So, we'll look at that later in the course. We'll kind of talk about how you can import different themes and customize those. So, installing AG Grid is super simple.

The next thing we need to do is we need to start kind of defining, telling AG Grid how we want to display our data. So, in this section in the course, we're going to learn how to define columns in AG Grid. We're going to learn how to kind of define a column's sorting behavior, the filtering behavior, and the dragging, pinning, and spanning. I'm not sure if we'll get into those, but those are also possible where you can actually drag a column, pin a column, and have columns that span multiple, kind of multiple columns as well. So, let's talk right off the bat. Let's talk about the column definition. So, each column is defined by a Caldef object. So, that's the interface inside of TypeScript. And by default, the columns are positioned in the order that matches the column definition specified. You will see this in a second. When we use a AGGrid, we're going to pass it an array of column definitions. And whatever the order is in that array, that's going to be the order of the columns by default that is going to be displayed inside of AGGrid. So, let's take a look at how we do that. So, in this example, I've got a grid component, and I'm going to return this block of JSX. I'm going to wrap up the grid inside of a div, and I'm going to give this div the class name of AGThemeAlpine. So, that way I get the theme display of AGGrid. And then here's my AGGridReactComponent, and I'm going to provide it with the ColumnDefs prop, and I'm going to set that equal to the column defs that I have in my component. So, let's expand that out a little bit. You can see here that I've defined my column defs using the UseState hook. And I've specified that this is going to be an array of ColumnDef objects. And then there's a generic on that ColumnDef object called rowData. And I've defined that generic up above, I've defined that type. And I'm saying each row in my object is going to have a name and a color, and those are going to be strings. And then, I'm going to go ahead and set that initial value, and I'm going to provide it with two ColumnDef objects. Here, I'm going to say that in the first column the header name is going to be literally name, and then this field property is going to bind or tell a AG Grid that in this row data. I've got a property called name and I want you to pluck the value from that property and I want you to put that in this column. So I can see that in my row data. I've got a name property and I'm going to kind of bind that up and tell AG Grid to use that field or that property within my row data to display in that column whatever value is in that object or that you know, the array of objects that I'm going to be using for my data. And then next I'm going to have an additional column and I'm going to use color in this instance. And just like we showed before we're going to go ahead and create our AG Grid react component. And here's our column defs prop and we're going to provide a reference to my column def state. So like I said, in the simplest form, a column definition specifies two things. First the header name to be displayed as the column header and then the fields of the row object to get the data from. This can also accept kind of a deep reference if you will within the row data object by using dot notation. So let's say my row data is an object and I have a user and then inside user. I have a property called account. That's an object inside of account. I have a property called first name that contains a user's first name. So in that field prop I can I can say hey for field rather than just saying like name or color like we did in the example before I can also use kind of a deep reference using dot notation inside of the row data. I can say let's display the user dot account that first name value. I want to make a quick note here that we are going to be kind of using TypeScript and you don't have to necessarily use TypeScript but recently AG grid released version 28 and they really improve their TypeScript support in this version. So that's where we're going to get things like generic types. And so if you're not used to TypeScript don't worry too much about this. It's still just kind of like JavaScript and you can definitely follow along with us throughout the workshop, but I do want to know that we did specify row data that interface for the tdata generic type when using the call def interface. So this call def interface has a generic that says hey, I'll take you tell me what the row data is going to look like because I don't know what it's going to look like. And so that's where we specified row data when you used our you state hook and this was recently introduced.

4. Row Data and Grid Display

Short description:

In AG Grid, there are different models of row data, including client-side, infinite, and server-side row models. We will primarily focus on the client-side row model. We define the row data using the row data property and initialize it with data from a JSON file. The AG Grid React component is used to display the grid, with the column definitions and row data props set up.

I can set in version 28 and enables some better type checking which can help you catch some potential regressions, build time and things like that. Okay, so that's the column definition. So far. We have created a grid. We have to call two columns in our grid, a name column and a color column. We binded that to these field properties inside of our row data and we're displaying that grid with the theme of alpine.

So now let's kind of start keep bringing that element that mental model together and let's talk a bit about row data. So broadly speaking, there's a there's several different models of row data in AG grid. There's a client-side row data where all the data is in the client and you you provide it to AG grid and it displays all that data via client side data. They also have a row model that is an infinite row model something similar to like Facebook or Instagram where as you as you scroll down on the data grid. It'll chunk in blocks and then infinitely scroll the grid so that can be very useful if you have large large data sets and you want to allow the user to just kind of scroll those in with that row model. You're going to define kind of how to fetch that data the chunking size all of that and you'll get that data from a back end or something like that. They also have a server side row model that's provided by Ajigar. This is an enterprise feature. All of the stuff that we're going to be looking at today is mostly within their community Edition, which is MIT licensed and free to use, but they also do have an Enterprise Edition that you have to pay for of course, and the server side row model is part of that. Service like row model, just like it sounds we're going to be kind of paging and fetching data from the server and piping that down into a Jigrid and then they also have this additional road model called viewport which is kind of deprecated at this point. So we won't talk too much about that. But just note that it does exist today. We're going to be using predominantly the entirely the client-side row model. So again, this is the free version or the MIT license version of Jigrid support the client-side row model.

So here's an example of our row model or excuse me of our data. So you can see here before we had our column definitions. Now what we've added is we've added a row data property here use state and we've said that we're going to expect this to be an array of row data objects and we're going to initialize that with some data that we're going to be just kind of fetching from a JSON file just for the purpose to make it easy in this course. I'm going to say, hey, go ahead and set that row data to our Products List. Now that we have row data inside the Jigrid React component, we can specify the row data prop and set that up to use our row data state. Let's go ahead and if you're following along go ahead and click that link to see example on StackBlitz. I am using, you'll notice, you might be wondering, I'm kind of toggling between the website version and the kind of the slides. If you want to follow along on the slides, if you just hit the period key on your keyboard, that'll bring up the kind of the slide model, the slide view and you can use the left and right arrows to go between slides and then the escape key to exit out of that view. So, with that said, go ahead and open up that StackBlitz and let's take a look at it. They've got their right comp coming up, here we go. Alright, so we can see... Let me go ahead and just kind of hide that, give us a little bit more view here. Here is a AgGrid displayed inside of StackBlitz using the Alpine theme, so it's kind of a nice theme. Not super dense, kind of very pleasant. And then here is all of my products and the kind of color of the product. If you're wondering where the names of these products came from, this was all generated using Faker. So I don't know what Awesome Frozen Pants are, but they come in the color white, if you'd like them. So feel free to check those out. There's no buy button, so you'll have to Google search to try to find those Awesome Frozen Pants from some other website. Mike, we need to have a referral link in Amazon. We should be making money here. We are missing out. There should be a buy now right here, add me to your cart. Sonji would be buying lime colored gorgeous cotton soap. You know, it probably exists. Okay, like I mentioned, let's kind of peel back the layers a little bit here. So here I am going to be importing the call def from AG grid community. I'm also importing the AG grid react component from AG grid react. And then we've also got this data Json file again. This is just for the purpose of this course. You can be pulling data from anywhere, right? And you're going to you're going to bind that down as a prop into your component. So that could come in from a parent component or you could fetch that data or whatever you want to do. So in this instance, we're just bringing that in from this data Json file. And if you're curious, you can open that up and you'll see here that it's got a whole bunch of data, basically like a shopping, you know, e-commerce website. So there's kind of customers and customers have accounts and then there's products and then an order that you might place with multiple order items or line items within that order. So, let me get back to grid. There we go. So that's our data and then we're going to describe what our row data looks like. We're going to say, hey, our row data has a property name and a property color. Both are type string. Here, I'm going to specify the column definition state and we're going to bind that to the AG grid React component. And then here's our row data that we bring in and we're going to use the products data out of that JSON file. So we're going to that's why we're displaying our products over here on the right. And then finally we're going to return our JSX with our div that wraps up our AG grid React component where we have our column desks prop and row data prop binded and set up. Okay. I haven't been monitoring any questions in the chat. Go ahead and throw any questions and I know we just kind of threw a lot at you and then we're going to do an exercise here in a minute, but we just want you to kind of get started with this mental model. So we've got a grid. A grid has columns. We have to specify kind of tell AG grid what those columns are and how to display them.

5. Column Definition and Exercise

Short description:

We're talking about the header name property and the field property. The header name just tells AG grid what to display in that header and the field is how we're going to tell AG grid kind of to where to get the data inside of our row data object. If you have any questions, feel free to drop them in the chat and we're happy to answer those questions. Now we're going to get right in and do an exercise. We want you guys to be hands-on. So if you click on the link to open up the stack blitz exercise, that's going to pull up basically what we just did, right? We're going to start real basic here. And what I want you to do is specify the column definition, state and bind that to the ag grid react component and then set the row data state. And then we're going to set that initial value to the data products, just like we did. And then bind that to the ag grid react component with those props. Give it a try and let us know if you have any questions. We'll be here to answer. Mike also dropped into the chat a link to this StackBlitz directly. If you run into any issues or have any questions, let us know. We don't work for AGS. We're here to share what we've learned about AGGred with the community.

There's a ton of properties inside that column definition object. We're just looking at two of them for right now. We're talking about the header name property and the field property. The header name just tells AG grid what to display in that header and the field is how we're going to tell AG grid kind of to where to get the data inside of our row data object. And then we use our row data state and we bind all that down into the age you could react component that then nicely displays all the data that we've given it in the columns that we've specified.

Any questions so far? Throw those in, let me get the chat open here. So any questions Mike that we have here? No doesn't look like we have any questions in the chat or in Discord. Again, if you have any questions feel free to drop them in either those places. I do see one question here. Let me back up a little bit. I think Charles asks, is the dot notation type safe? For the field I don't believe it is. I don't think so. So if I were to do like account.name, I think it will still build, so it's not type-safe. Though it could be. They just need to improve their typescript, which is a pain. Can you customize how it chunks? I answered that, perfect. Andre says, does it handle array as the value of the field? Does everyone map the array or join values of an array? It looks like Tomas answered your questions. With the formatters, value getters. So we'll take a look at those and we will be getting into that. Cool. If you have any other questions, just raise your hand or throw those in the chat and we're happy to answer those questions.

All right. Now we're going to get right in and do an exercise. So we want you guys to be hands-on. We definitely encourage you to do the exercises. This is how you're going to kind of reinforce that learning. So if you click on the link to open up the stack blitz exercise. That's going to pull up basically what we just did, right? So we're going to start real basic here. And what I want you to do is I want you to specify the column definition, state and bind that to the ag grid react component and then set the row data state. And then we're going to set that initial value to the data products, just like we did. And then bind that to the ag grid react component with those props. So why don't we give you a couple minutes to work through that. I've got 29 after, so we'll give you like four or five minutes. Once you go ahead and get started with this exercise and let us know if you have any questions. We'll be here to answer. Mike also dropped into the chat a link to this StackBlitz directly. Be sure not following along with the course website. And if you run into any issues... I am on muted. If you run into any issues or have any questions, let us know. I don't think I mentioned this. Let me also just clarify. Mike and I, we don't work for AGS. We like AGS. We're friends with them. We hang out with them at conferences and stuff. But we don't... I'm not an AGS employee or anything like this. So you can... You know, we're all in a safe space here. You can have opinions about AGS. Like I'm not here to tell you that you have to use AGS. I don't make any money if you buy AGS. But, you know, they asked us to do this workshop. And so we're here to kind of share what we've learned about AGGred with the community. Mike, do you have the ability to do a thumbs up in your Zoom? Let me see. Yeah, the import is fine, Muzzah, yeah, for sure. Get the error, import data from....../.JSON, that should work. Yeah, you're going to get some errors like that in Stackblitz today. Oh, that's right. Yeah. It should still compile or should still run fine, but Stackblitz is a little finicky with some of the TypeScript compiler options. Yes. Yeah. I don't know if you can see it in the Stackblitz URL there, but all these challenges are actually hosted on GitHub using a full React app. So I'll be happy to drop a link to that if you want to pull that down and follow along that way. Yeah, that'd be great. You won't have any type errors if you want to do it that way, but that'll require some setup. Yeah, you can clone it, install it, run it locally if you'd like rather than using Stackblitz. It's funny, it gives you this error that says blah blah blah and it's like, oh, you can't go to the docs, blah blah blah, consider using your resolved JSON module.

6. Enabling Row Sorting

Short description:

We'll give you two more minutes to finish up the exercise. Set up column definitions using the useState hook and specify the name and field for each column. Bind the column definitions to the AgGridReact component. Set up the row data using the useState hook and bind it to the row data prop of the AgGridReact component. Enable sorting for a column by setting the sortable property to true. You can also specify the sorting order by providing an array of ascending and descending. Multi-column sorting is also possible.

Then guess what? Resolved JSON modules right here, set to true. You know, we've known about this for a while, Mike. We haven't submitted an issue or a PR have we? No. Waiting for GitHub code space to be public and available so we can use that. Yeah, maybe we're not good open source contributors if we haven't told them that it's broken or helped them fix it. Yeah. It's just, yeah. So ignore that, I guess. We'll give you two more minutes to kind of finish up this exercise. Mike, do you want to do the solutions? I'd be happy to do the solutions. Okay, so let's go ahead and take a look at what you need to do to get this working. So the first thing we need to do is we need to specify our call. Our column definitions. And to do that, I'm going to go ahead and set up here some column deaths and I'm going to use the use state hook. Um, we're not actually changing the column definitions in this component. So using the use day hook as a little overkill this case, but we're just kind of doing that so that you would know that, Hey, in a react application where you might want to change those column definitions, wrapping up in the use state, the way to go. We are using TypeScript for this, so I'm going to specify some types here. So the state of column definitions is going to be this call deaf interface that I've imported from ag grid. And it specifies a generic data or a generic type, which is the type of data we're displaying in our grid. I have an interface here called row data that I'm going to use for that. Once I have my type set up, I can go ahead and set up my column definitions. So each one needs at a minimum I had a name and then the field that I want to display it to that. So I'm gonna set up some column definitions for both the name field and the color field in my data. Once I have my column definitions, I'm ready to go ahead and find that my Ag grid react component. So here I'm going to set the column deaths prop to be the column deaths state that I've set up. With the columns defined, you can see in the right that I'm seeing the name and color headers, but it also says that it's loading. And that's because I've not supplied any row data yet to the grid. So I'm going to set up my row data. And to do that, I'm also going to use the use state hook here to set up data dot products as the data that I want to display here. And then once I have my state configured, I can go ahead and bind that to the row data prop of the ag grid react component. With that done, all the data appears for showing the name and the color columns along with those particular fields from the data. Mustard's heading is not required. We want the same name as field. That's right. So if I didn't want how to name and I just wanted to show this as the field, it will also work. But again, recommend doing that just that you are not relying on the automatic casing coming from ag grid and you get to choose a friendly name there for your fields. That's right. Yeah. It'll do like a. Does it split it on every, does it like split it on a camel upper camel case? I forget. Cases that like title cases. Yeah. So if you just use field, you can do that. I always just put in the header name just to explicitly say, Hey, this is what I want for my header name. So I'm kind of keep it simple. Cool. Thanks, Mike. Appreciate it, man. Yep. All right, next we're going to go and we're gonna start talking about rose sorting. Let me share out my screen. Nice. All right, so let's talk about how we can enable rose sorting. So we can enable or disable the ability to sort a row by using the sortable property in the Caldef object. By default, sortable is set to false, and we can also have custom sorting that could be performed using the comparator property. And you provided a sorting function similar to a row difference and we'll be using that a little bit more in this video. We provided a sorting function similar to array.prototype.sort. So by default, the sortable, if you set that to true, it'll allow sorting the user to change the sorting order of a column. And by default, it'll just do kind of a alphanumeric sort. But if you have some sort of custom sorting that you need to do, whether the sorting should be based on some other value, maybe that's not in the field or something like that, you can also provide a comparator property in the column definition and you give that a function that basically be invoked just like array.prototype.sort. And you'll return kind of a negative number, 0 or 1, based on how you want it to be sorted. So let's take a look at that. In this example here, what we're going to do is in the name column, we're going to go ahead and just add sortable, and we're going to set that to true. So that's all we have to do and that will enable sorting for that column. By default, the sorting order is set to first ascending, then descending and then none. And none is whatever the order is of the row data inside that we bind to the AggridReact component. So we can also specify that sorting order if we want, and we can override the default behavior. So in this example, what I'm going to do is I'm going to set sortable to true, and then I'm going to set the sorting order, and we provide it with an array, and we could tell Aggrid that we want to have the sorting order be first ascending, and then descending. And we're not going to have kind of a default of null, where the sorting order is based on the order of the objects in the row data that we're binding to. We can also have multi-column sorting.

7. Multi-Column Sorting and Override

Short description:

Aggrid comes with multi-column sorting. You can override the default behavior by specifying the multisortkey table option. Set it to CTRL to use the command or control key instead of the shift key. This can be done by setting the multisortkey prop on the Aggrid React component.

So by... Right out of the box, Aggrid comes with multi-column sorting. So you could sort multiple columns by holding the shift key and clicking on the column headers, but we can also override that behavior, and we can specify the multisortkey table option to override that behavior. If we wanted it to be maybe the control key slash command key in Windows and Mac, we can do that. And here's how we might do that. We can say multisortkey, and then we can set that equal to CTRL, which will tell Aggrid that we want the multisorting key instead of being the shift to be the command or control key. And note that we're setting that as a table option, and that's kind of a term that Aggrid uses. And that table option is going to be right on the Aggrid React. We're going to have a prop called multisortkey, and we're going to set that value.

8. Adding Sortable Property and Customization

Short description:

Go to StackBlitz and add the sortable property to a column definition. Override the sorting order and multicolumn sorting key. Click on the column header to sort. To sort on load, use the sort prop. The initial sort only works the first time. Use the initialSort prop for customization. The initial width prop sets the column width on creation.

Okay, let's do another exercise. I want you to go ahead and open the challenge up on StackBlitz, and we're going to add the sortable property to a column definition. And then I want you to override the sorting order by specifying the sorting order property on the column definition. And then if you want, go ahead and override the multicolumn sorting key by specifying the multisortkey prop on the Aggrid React component. So you're going to come in here and inside of one of our fields, or, excuse me, one of our columns, go ahead and set that sortable property. And then when you click on the column header, you should be able to sort that. So if I do sortable, set it to true, I can now click, and you can see that it goes between ascending, descending, and when I click again, it resets back to kind of the default default. And it works. Resets back to kind of the default behavior of that null value. Where the sorting order is based on the order of the row data. So go ahead and open up that on StackBlitz, and why don't you take two minutes And go ahead and just add those properties into your column definition. If you have any questions, throw those in the chat. Is there a way to tell it to sort Is there a way to tell it to sort on load? There is a way to do that I'm trying to think. Let's say we want to do an initial sort. Is it just called initial sort? It might be. Let's see. Where would this be? Column prompts maybe? Yeah, initial sort. That's when creating a new column. I'm trying to think if there is sort or a comparator. I guess you can just sort your data out you know. I'd have to check if the initial sort. Actually if it'll run that initially. I feel like there's a way to do this. I'm kind of blanking on it. Let's see. I'll keep looking at it up here. Row sorting. Enable sort. Maybe I send it. Post sort. Custom sort enable. I can also send it to Sent. Custom sort enable multicolumn. There's an API. We could probably just call a function to tell it to sort as soon as we know we have our data. There's apply Column State. Yeah, that's a good question. It might just be initial sort. I don't know if that will actually, if you just set sort to a sending, yeah. Jason figured it out for us. There you go. It's just the sort prop. That makes sense. Ah, so that's right. That's the difference now I'm remembering. So there's the sort prop and then initial sort, I think, only works like the first time or something like that. I forget. So in the API, there's a couple different properties that would be like width and initial width. And the initial width will be applied when the column's first created. And then the user can change the width of a column. But if you just set width, it'll hard code it to 200 pixels. So there's a couple different behavior differences between, they'll have some props kind of be initialSort, an initialSort, width, initialWidth, that kind of give you some customization of that behavior. Yeah, so initialSort is working. Yep. And you can use sort.

9. Default Column Definition and Exercise

Short description:

In this section, we learn how to add the sortable property to a column definition, override the default sorting order, and change the multi-sort column sorting key. We can change the sorting icon by swapping out the default icon pack or creating a custom header component. The Sort icon appears once you click on the header, and you can use sorting order ascending, descending, null to disable sorting. Aggrid provides a default column definition that can be inherited by all columns, with specific columns being able to override the default values. An exercise on this topic is available on StackBlitz.

Okay, great. Mike, you want to do the exercise?

Mike Bordetti: Yep, I look.

Robert Antione: Great questions. I love it. Make sure I get the right one here. Okay. So the challenge here is to add the sortable property to a column definition, and then override the default sorting order by specifying the sorting order property and then change the multi-sort column sorting key by updating that multi-sort key. So this is a fairly straightforward exercise. What I'm gonna do here is I'm actually gonna go ahead and make these changes to the name column. So I'm gonna set this up here to sort or make this column sortable. So just by doing that right off the bat by changing it to be sortable, I get these sorting controls here. From there I can set the sorting order. So this just lets me control what order this column would sort in. So I'm gonna say let's sort ascending first and descending second. Again, not a lot of change here, but you can kind of see that it controlled that sorting order. And then finally, what I'm gonna do is I'm going to set that multi sort key on the React component here to be the control key instead. So, again, not a lot of things are changing here. Just kind of want to demonstrate some of the flexibility that you have in controlling how columns are sorted, and how you can interact with the grid, with AG grid.

Let's see if there are any questions here. Can we change the sorting icon? That's a question for Brian. That's a great question. So, there's two ways to change the sorting icon if you don't like it. So, by default, they use an icon pack. I don't remember if it's material or font awesome. You can check the docs. They basically have like an icon pack that they use, right? And so, you can actually swap out that icon pack and provide your own icons. The other way you can do this, and I have done in the past, is if you have kind of a header that you really want to change, maybe you want to have custom icons or multiple different icons describing the state or you want to highlight it for whatever reason or all kinds of things. One of the things that I mentioned in the very beginning was the extensibility of Agt grid, and you could create a custom component for that header. So, where it says name in Mike's example, you can create a component that renders inside of there, right? You can do whatever you want. You can, you know, it will know, it will get past like for a params object that will tell you the sorting order and all kinds of stuff, and you will be able to use that to display either custom icons or all kinds of things of what you need to do. So, you can create a custom header component that then gets rendered in for that header and you could change the icon that way. So, there's kind of two different ways that I would approach that. Depends on kind of your use case and which one's easier, if you want to have custom icons.

Yeah. I just says I can't even find the Sort icon where is it? The Sort icon is once you click on the header, once you've enabled sorting like Mike did by sending sortable to true, once you click on that header, the name, or the color, the header for the column, once you start changing the sorting, you'll see an icon like an up arrow or down arrow. Can we use sorting order ascending, descending, null to disable sorting by clicking these, by clicking three times on a header? Correct. So, by default, the sorting order is exactly what you have here. Ascending, then descending, then null. And null is that kind of default state. Whatever order is in your row data, or to disable sorting, if you will. Yes, that is the correct way. Yep. Alright, cool. Any other questions, go ahead and feel free to drop those in our chat, happy to answer those. We're gonna go over this next section and then we're going to take a 10-minute break, get everybody an opportunity to kind of step away and do whatever you need to do. So let me just share out my screen, give me one second. Share screen, Chrome. Alright. The next thing that we want to talk about is called the default column definition. So at this point you might have noticed that we have these column definition objects, and we're using the use date hook to set those to an initial value. And we could use that to override those column definitions and update the column definition at runtime. But you could also imagine that this becomes quite repetitive. If you're going to put sortable equals trues, let's say you have 20 columns and you want them all to be sortable, setting sortable to true in all 20 objects seems like a lot of extra work. And so aggrid has this concept of a default column definition. And the way that this works is we can set that default column definition and then every column inherits the default column definition. And then each specific column definition can override those default values on a per column basis. So let's say we wanted all of our columns to be sortable by default, we could set sortable to true in our default column definition. And then let's say in one particular column, we don't want to allow the user to sort that column. So we could set sortable to false and that column definition and it would override the default. So here's an example of that. I'm going to have my default called def. And I'm going to set sortable to true. And then I'm going to set that default called def prop down here in my aggrid react component. And that's going to tell aggrid that we want to use by default, all column definition should to inherit whatever we've put inside of this default column def. And the typing is the same, it's still a column def. So anything that you can put in an individual column definition, you can put inside of the default column definition. Anything like, you know, when we'll get into some of these, like value formatters and value getters and value setters and cell renderers and all kinds of any property that's in there, you can set inside the default called def. Okay. Let's go ahead and do a quick exercise on this. So open up the exercise on StackBlitz.

10. Making Columns Sortable in AADG Grid Component

Short description:

Create a new default column def const in the component function and set the sortable property to true. Bind it to the default column def prop in the AADG Grid React component. Override the sortable property to be false for one column. Any questions? Let's hear the solution from Mike.

And we want you to create a new default column def const in the component function. And it's going to be an object of type column def, and then the generic that TData generic is the row data. And we're going to set this sortable property to true. And then I want you to bind that down to the default column def prop in the AADG Grid React component. And then that should make all of your columns sortable. And then go ahead and override one, just so you kind of prove the model here. Override that sortable property to be false for one of your columns. So why don't we do a couple minutes on this one, and then we'll have Mike go through the solution, and then we'll take a quick break. And any questions, feel free to throw those in the chat. Charles has a fun question. Says, can we mess with our users by sending this order to ascending, descending, ascending, ascending, descending? That's a great question. I've never thought to do that. I've never opened up a user requirement story that said the sorting order for the column should be ascending, descending, ascending, ascending, descending. So, I've never tried that. So, maybe we can give that a whirl or why don't you try it and let us know what you find out. I think you'll find that your users won't be happy and your project manager might not be happy. But I wonder if it's possible. It might be. It's a great question. All right, Mike. Do you want to take us through the solution? I'd love to.

11. Default Column Definitions and Filtering

Short description:

To make all columns sortable, we can use default column definitions. By defining a const called default column def, we can set basic properties that apply to all columns. We can then bind the default column def prop on the A.G. Grid React component. If we want to disable sorting for specific columns, we can override the sortable property in their column definitions. Now let's move on to filtering.

Okay. So far what we've been doing is we've been changing these column definitions on kind of a column by column basis. Well, what if we wanted to make all of our columns sortable? Well, we could set a sortable to be true for every single column definition, that could become repetitive, especially if we have a lot of columns in our grid. So what we want to do here is we want to use the default column definitions to kind of set up some basic rules that are applied to all of our columns. So if I wanted to set this up, I'm going to just kind of define a const here called default column def. And again, this is going to be a column definition, too, just like the other column definitions, except this one's going to apply to all of our columns. So I'm going to set some basic properties here. I'm going to say that all of our columns should be sortable. Once I have that, I can then bind to the default call def prop on the A.G. Grid React component. Now, all of my columns are sortable. And this works great. I don't have to specify that sortable key to be true for all of my columns. But if I want to disable that now for, say, the color field, I can then go into the color fields column definition and override that to be false for that. So now the column color column is no longer sortable. So these defaults kind of apply first and then the column definitions can override those defaults. Perfect. Any questions? Let me check the chat. Awesome. Cool. Let's go ahead and we're gonna take a break. Alright, start back up. I didn't share my screen out. So we just wrapped up the default column definition and Mike did the exercise for us. So now we're going to be taking a look at filtering.

12. Filtering Column Values in AGGrid

Short description:

AGGrid provides several filters for column values, including text, number, and date. To enable filtering, set the filter column definition property to true. The text filter is the default, but you can also explicitly specify the filter type using AG text column filter, AG number column filter, or AG date column filter. In the exercise, open Stackblitz and apply the appropriate filters to each column. The row data is generated by summing up order items and calculating the product price. Add the filters to the column definitions and ask any questions in the chat. Mike will then explain the solution.

Alright so, AGGrid ships with several provided filters. So filtering is when I want to filter values in a column. It's kind of like maybe you would do something like this in Excel or Google Sheets, and you only want certain values to show up, you're trying to search basically for values in that column. So the provided filters are text, number, date, and set, and the set is an enterprise-only filter feature.

So by default, you can just do simple text-based searching or filtering for column values. You can search for, you can have filters for numbers. In the number filter, you could do things like greater than or less than, kind of add like and and or statements together. And then the same thing was date. You could say, hey, give me, you know, orders that are greater than such and such a date, or orders that were placed on a particular date. The text filter is the default, so if you just put filter true, that will default to the text filter.

To enable filtering, we're going to set the filter column definition property to true, and it defaults to false. So out of the box, like we've shown already, there is no filtering. So once you set that filter column definition to true, then you'll get the ability to filter. So let's take a look at the text filter. So, here we have our column definitions, and we set filter to true, and the default is the text filter. So that will enable the text filter on the name column. I can also explicitly provide the text filter. And so, AG-Grid, all of their filters start with AG and then the name of the filter. So this, I could say, hey, for the filter, I want you to use the AG text column filter. So again, the same thing is set into true. That's just kind of a more explicit way of setting that filter. Same behavior, though. I can also use the provided number filter. So in this case, I do have to actually specify the full filter name. And so here, I'm going to say for the price column, I want you to allow number filtering. And so for the filter property in the column definition object, we're going to set that to AG number column filter. A little bit long, maybe verbose, but that's kind of how it works. And if you create your own filters, you can kind of use your own, just to avoid, so you don't have any naming conflicts, you can use your own kind of naming convention just like they have here. And then, here is how we can do the provided date filter. So just like you probably guessed, we're going to set filter to AG date column filter, and that will enable a date filter for that column. And we're going to set that on the date of order column, which kind of makes sense. Okay.

We're going to get right into an exercise. So, again, just to recap, we've got this filter prop on the column definition object, set it to true, defaults to the text filter, and then we can use the text number or date filters. And so, in this example, what I want you to, or exercise, I want you to open that up on Stackblitz, and then for each of these columns, let's use a kind of a provided filter. So, for the customer name, you can just set that to true and use the default text filter. For the account number, it probably makes sense to use the number filter. For the date of order, again, it makes sense to use the date filter. And then set the total column to use the text filter as well. So, go ahead and open up that Stackblitz, should see now our files. Start this up. Now we've got our grid, looks a little bit more realistic. We've got actual, these are our orders for our customers. I guess these are accounts. So, we've got our customer name, an account number, a date of order, and the total or sum of their order. And we can see down here, again, this kind of should look familiar. We've got our headers and our fields. For the row data, we did have to do some calculations here. So, rather than just setting it to be a kind of the product, or products array, if you will. Now, we're kind of, we have to bring together a lot of those different pieces of the data inside of that JSON file. So, remember on the JSON file, we had things like customers and accounts and order items and orders. And so, this is a little bit complicated. But what we're doing here is we are kind of summing up the total of all the order items and getting the product price. Because our database is kind of laid out like a relational, you know, SQL-style database, if you will. So, this is almost like a query where we're kind of bringing all that data together to be able to display all of this. But don't worry. That's all done for you. So, don't worry about that. What we want to do is in our column definitions, we're going to add those filters. So, why don't we take three or four minutes. Go ahead and add those in. If you have any questions, put those in the chat. And then Mike will go through the solution all together. And just one minor correction on this challenge, Brian, if you don't mind going back to the challenge text for a second, it says to use the provided text filter for the total column, but instead please use the number filter instead. Yeah, that does make sense. Good call out. Thank you, Charles, for pointing that out. Yep. All right, Mike, you want to run us through the solution? Yep. Yep.

13. Adding Filters to Columns

Short description:

To add filters to columns in AG Grid, specify the filter property on each column definition. Use the filter property with the value true for text-based filters. For number and date columns, use the AG Number column filter and AG Date column filter, respectively. AG Grid provides built-in filters, including a clear filter option. You can customize filters using the filter params object, which allows you to add buttons and configure debounce. The browser's built-in date picker is used for date filtering, but you can customize it using extensibility features. If you need to change the date format, you can write your own filter. The date filtering in AG Grid works out of the box with JavaScript date objects. If your API returns a different format, you can use the comparator function to customize the filtering. The comparator function compares the filter date with the cell value and returns a result based on the comparison. To recap, if your row data uses JavaScript date objects, the date filtering will work without any modifications. Otherwise, you can use the comparator function to handle custom date formats.

OK, so what we want to do is we want to add filters to these columns here. And the way to do that is we're actually going to specify the filter property on each of these column definitions. So the column definition accepts a filter property, and the easiest way to get a filter set up is just to set this to be true. And what this will do is this will set up a text-based filter for this column. So now if I go to customer name, you'll see I've got this little drop down here, and I can now search for a very specific customer by name using this text-based filter. If I want, I can add multiple things. There's a lot of advanced features in this text-based filter. But not all of our columns are going to want a text-based filter. Our count number and our total are numbers, and our date of order is a date. And Aging Grid ships with different filters for those types of data. So if the account number, for example, if I wanted to, I can set up a filter to use the Aging Number column filter. So this is the same as setting filters would be true, but in addition to setting it to true, we're also telling it how to let us filter this. So now if I go to the account number and try and filter it, you can see that's giving me an equals control here where I can put in an actual number. So I'll put in a number here. I think I got that partially wrong. And that would let us control that account number. Similarly, for the date, I can do Aging Date column filter. And then now for the date of order, I have a date control here. So I could pick a specific date out and it will filter down to all of the orders that match that date. And then finally for the total, again, I'm going to use a number column filter. So AG Grid ships with these built in. So the clear filter, and you clear all inputs and pop up, right? Yes, that's correct. So if you start typing into it to clear the filter, you're gonna wanna clear those inputs out. And there is, you can customize the filters. There is a filter params, object or property on the column definition, where you can do things like adding a reset button, an apply button so it doesn't apply till the user clicks that button and these kinds of things. And then the other thing that I'll quickly add up is you'll notice in that date of order, when Mike used that filter, that uses the browser's date picker. So whatever browser you're using, that's what the UI will look like. And so if you want to have like a material date picker or something like that, or some sort of fancy date picker, again that's where you can get into the extensibility side of Age of Grid and you could build your own filter components that will be rendered either as a floating filter underneath the header or as the filter that Mike showed when you hit the little menu and it kind of has that pop up. So you could customize that and you could create a, again, a material date picker if you wanted to have a better UI or something like that. Yeah, another question Alex asks, can I change the date format? eG German does day first, followed by month and then year. Since this is just using the browser's built in date picker it will actually already be localized to whatever the locale is of the browser. But like Brian said, if you wanted to customize that you could write your own filter. Correct. And then you got to take that into account. Yep, yeah. Go ahead. To show what Brian's talking about filter params. There is a filter params object here that lets you specify additional parameters for the filter. So for example, if we wanted to show a reset button that's built into a eG grid, so I can add a reset button here. So now if I filter this out or add some text here you can see I've got this reset button that clears the filter. So there's a bunch of different parameters that you can specify to customize the built in filters. You can add events to it. You can add apply, clear, reset, cancel buttons. You can configure the debounce. Lots of things you can do inside of this filter params. Awesome. Any other questions? Cool. Okay, so one of the things that we kind of glossed over a little bit was the date filtering. And you might have noticed if you looked at the code inside of our row data and that uses memo hook that for the date we were creating a JavaScript date so if I come back over here and I take the look at the date of order, you'd see that in here that I'm creating a JavaScript date object. And so out of the box, the date filtering works as is when the row data uses the JavaScript date object. But you're probably thinking, well, my API doesn't return JavaScript date objects, Brian, what am I supposed to do? Well, you can create date objects like I did or you can use the comparator function. And so the comparator function allows us to use kind of custom ability to do filtering. And so let's say like our API returned something like an ISO string, we could use that comparator function to do any sort of comparison that we need to. So in particular, like Mike mentioned, we've got this filtered params property inside of our Calm Definition. And then inside of there is where we can provide the comparator function. And the comparator function is kind of like a comparator function that you would expect and that it receives two values. So first it'll get the filter local date at midnight. So this is localized and this will be the filter whatever date is selected, it'll be that day at midnight, and then the cell value. And so that cell value might be a string an ISO string could be whatever it is that, you know, kind of you're binding in to that column. So in this instance, we've got an ISO string. And so what we're gonna do is we're just gonna new up a date object and we're gonna set the hours. So that way we're doing the comparison based on the time, and then we return zero if the values are the same, a negative number if it's less than a positive number if it's greater than. And so that's how we can do kind of custom filtering using the comparator function. So this is a good example because a lot of times, you know, you don't necessarily get, you know, depends on how your data is coming into your component, but you may need to kind of customize this. So again, to recap out of the box, if you've got date objects, it will work as is, if not, you need to specify this comparator. Alright, great. Let us know if there's any questions, otherwise we're going to keep moving along here and we're going to get into cell rendering. Mike, you want to do the cell rendering section? Sure. Can we stop sharing? Okay. Let's talk about cell rendering.

14. Customizing Data Display with Value Getter

Short description:

In AG Grid, we can customize how values get displayed using the cell rendering pipeline. We explore the value getter, value formatter, and cell renderer functions to customize data display. The value getter function is used to get row data for columns where the field property is not an option. It allows us to mutate data before providing it to the grid. The value getter params object provides information about the grid API, column API, context, data field, and more. The grid API is used for programmatically interacting with AG Grid, while the column API is used for interacting with specific columns. The row node represents a single row in the grid. To write a value getter function, we pass it inside the column definition and handle the data accordingly. An exercise is provided to practice using the value getter function to compute totals for each order.

So right now in our application, or in all the examples we've seen so far, we're kind of just letting AG Grid handle displaying the data that we're binding to it. By interacting with the cell rendering pipeline in AG Grid, we can customize how values get displayed. And there's a number of ways in which we can do this customization.

So in this section, we're gonna kind of explore the cell rendering pipeline. We're gonna talk about ways to use the value getter function to control how to produce values, the value formatter section to learn how to format values, and the cell renderer to do some really advanced things in terms of the way to display values. So cell rendering, without any customization, and in the simplest form, each cell in AG Grid is rendered as a string based on the data that you bind to it. So when we say we wanna show the name field from our data, it's just going to plug that out and show it as a string inside of the grid. However, oftentimes, this isn't sufficient. We wanna show data in richer ways or with more context or more meaning. And this is where we can leverage this pipeline for rendering data inside of these cells.

So we explore the value getter, value formatter, and cell renderer functions, in terms of ways to customize the way that our data is displayed. Let's talk first about the value getter function. So we can use the value getter function to get the row data for columns where the use of the field property is not an option. So right now we're showing columns like name or color, and that directly correlates to a field in the data that we are using to populate our grid. But sometimes we're gonna have like computed fields that are going to use different pieces of data to compute a value to show inside of our grid. So in that case, we don't really have a field name to point to because that field doesn't exist in the data that we're binding to it. And so we can use a value getter function to mutate data prior to providing the data to the grid. It's gonna be invoked by AG Grid for each cell. And so it's gonna let us do some of that computation. And it's gonna be invoked with a value getter params object that we'll explore.

The value getter params object looks a little bit like this. It's gonna provide us eight different things for us to inspect or interact with. Let's take a look at what each of these things are going to do for us. So, let's catch up here. The API is gonna be the grid API object. And we'll talk a little bit about what this does here in just a second. We also get the current column definition. So, we're rendering a cell. We're gonna get the column definition for that particular cell. Like, how is that defined? That's gonna give us a column API object. Something we'll talk about in a second here. We'll get the current column that we're trying to render. We'll get the context. This is kind of application specific and it's set via the grid options. This is for, this is really handy in like more vanilla JS implementations of HGRID that basically allows you to pass around or share context across different calls that HGRID is making to our application. There's gonna be the data field, which is the actual data that we wanna try and render for the current row. And then, there's a get value function. It's a utility method for getting column values. It accepts that same dot notation that the field name or that the field accepts that we've seen previously. And then, the node or the actual row that we're trying to render inside of.

Let's talk about the grid API, the column API and the row node in a little bit more detail. So, the grid API is basically a way for you to programmatically interact with HGRID. It's great for adding event listeners to the grid. We're gonna talk about some of the events that the grid exposes a little bit later on in this workshop, but it lets you programmatically listen for events coming off of the grid. It's also really handy for accessing clipboard features. So, if the user's interacting with kind of the entire grid and is copying, pasting, that kind of thing, the grid API is an excellent way to handle some of that interactivity. Because it's the programmatic way for interaction with HGRID, pretty much all these things that we're doing via like configuration objects can be done programmatically using the grid API. Similarly, we get this column API object and it's great for programmatically interacting with a specific column. And so, a specific column we're rendering in two. So, this is handy if you wanna change or adjust something about the specific column that we're rendering into. For example, we wanna move the column around, if we wanna pin it, if we wanna adjust the size of it dynamically, that's kind of how we could do that is via this column API object. And then finally, it gives us that road node object that I mentioned. And this represents a single row in the grid. Again, similarly to the previous two things we've discussed, it is another programmatic API for handling things like selecting an entire row or updating all of the data inside of a row or adding event listeners when something about that row is interacted with.

So now we have a basic idea of what gets passed to our ValueGetter function. Let's talk about how to actually write a ValueGetter function. So you can see here that we're gonna pass the ValueGetter function inside of the column definition. So here we have a header with a name of price. And inside of this ValueGetter, we're gonna get those value getter params. And the first thing we need to check and see is if params.data is undefined. So params.data could be undefined in cases where we're using, say, some of the grouping features in AG-grid. So we always wanna test to see if data is defined or not. And if it isn't, we're just gonna return zero as the price. And then if it is defined, what we're gonna do is we're gonna use the math.round function here to round that price down. So here we're using the ValueGetter to kind of compute or massage the data before we actually render it inside of our AG-grid. Our raw data has unrounded prices and now with this ValueGetter function, we're gonna be rounding those prices up.

Let's go ahead and do an exercise. This one's gonna be a fairly complex one, so there's a couple of hints and don't feel afraid to look ahead at the solution if you need some help because there's some data calculation going on here. So the goal of this exercise is to learn how to use that ValueGetter function. And what we're gonna do is we're gonna be using a ValueGetter to compute a total for each of these orders.

15. Calculating Total Price with Value Getter

Short description:

To calculate the total price of order items in the total column, use a value getter. The value getter should use the reduce method to iterate over the order items array, look up each product by its ID, multiply the product's value by the quantity, and sum them together. If you have any questions, feel free to ask.

So I'm gonna open this up just to kind of walk through what this is going to look like here. So you can see here our raw data has all the information needed for an order and it has a number of items or a set of items that exist in the order. And that's gonna tell you the quantity and the product that the user purchased. So what we wanna do is we wanna kind of reduce these order items down into a price. So to do that you're gonna be writing a value getter for the total column, which at first starts blank. And what I'd recommend doing is using the reduce method on this array of order items. Look up each product by its product ID. Multiply the product's value by the quantity and kind of sum all those together to calculate a total for it. I know it's really complicated. So again, feel free to look at the solution if you kind of wanna see how we did this already. The important part is to learn how to use value getter to compute values inside of Aggrid. This one's a little bit more complicated, we'll give you a few more minutes than usual for this one. Again, if you have any questions, feel free to raise your hand in the chat, drop a question in the chat, or drop a question at Discord.

16. Value Getters and Reusability

Short description:

Value getters in AG Grid allow you to compute cell values based on custom logic. You can perform calculations, reference data from other sources, or customize the data provided to the grid. The value getter function receives a params object containing the data associated with the row. Using this data, you can calculate the desired value for the cell. Reusable value getters can be created as higher-order functions, allowing for code reuse across multiple grids in your application. By using a higher-order function, you can customize the logic of the value getter based on the specific requirements of each grid. Check out the example on StackBlitz for a demonstration of a multiplier value getter. This approach eliminates the need to write the same value getter code repeatedly and promotes code reusability.

There's a question, value getter adds two fields together am I right? In this example, that is kind of what we're doing, but really you can do anything you really want to inside of getter in terms of computing a value. So maybe that's adding two fields together, maybe that's referencing the data from another source all together, kind of whatever you need to do to compute a value, that's what the value getter's gonna do. So, yeah, combining a first name and a last name is a great use case for using a value getter. What do you wanna do Mike want me to do? Go for it. Go for it. Let me go up. Chrome. All right. So Mike said we want to display, get this out of the way, bigger, we want to display our total column by number of columns and we wanna get a total column of that number. What we wanna do is for a total of five times, we wanna get the total to be six, we wanna display our total column. But in order to do so, we kind of need to calculate it. So what we're gonna do is we're gonna use the value getter. So see that I have a getter and this is gonna be a function it's gonna receive a params object and then I'm gonna return out of that, the value that I wanna AG grid to render inside of the cell. So the first thing I'm gonna do, I'm gonna say, hey, let's make sure that if we don't have some data, let's just get out of here, we'll return zero or we could return null or something like that. From there, if I look inside of my params object, this value getter params contains a property. Let's see can I get into the... Let's see if I click on here, I can do this. So it's a value getter function and that value getter function, see down here that it's invoked by AG grid with that params object and Mike went into that value getter params object and kind of talked about that. And inside of there, we have our data and that's the data that's associated with that node or with that row. So using that data, I can calculate my order total. So what I'm gonna do is I'm gonna go ahead and get the order items. So I'm gonna say order items and we're gonna get out of our data, we've got an order items property. And then I'm gonna take those order items and what I need to do is first I'm gonna filter those and I'm gonna say for each item, let's make sure that it's in this order. So we're gonna say item.orderId equals the params.data.ID. And then I'm gonna map these out and I'm gonna say for each item, let's go ahead and find the product. So I'm gonna for that item, I'm gonna do products.find and then for that product, I wanna grab it where it matches that order id. Excuse me, that product id. A dot there. You see, we've missing one opening parens right before find. And an arrow. Yes. You're better at typing these than I am. And products, should be not import, should be data dot products? Data dot products, yeah. Yeah, yep. And then now I wanna reduce these all down and I'm gonna say, let me give you the previous and the current and then I wanna sum these up. So I'm gonna take the previous and I'm gonna sum that up with the current items price. And reduce dot find, need another of trends, there we go. All right, cool. So, oops, I guess I just forked that, I hit save. So now I can see that I have my total column being displayed based on the order items and the products that are associated with that order. So this is certainly a little more like business specific, if you will, or implementation specific, but the takeaway here is that using the value getter, whatever I need to do, if I need to go look something up in like some sort of dictionary or lookup table, or I need to get data, I can do that. So I can use the value getter to kind of customize how the data is, the data that's provided for that particular cell as you could to render. All right. Next, let me just kind of keep going here. If there's any questions on that, put that in the chat, we'll take a look at that. So the next thing you might be wondering is, well, what if I have like lots of grids in my application and they all have this kind of need to get data somehow in some sort of similar fashion. So it's pretty easy to create reusable value getters because they're just functions. And so we can create something like this it's kind of a higher order function. So we'll create in this example I'm creating a multiplier value getter that will get the value as well as a multiplier. And let's say we want it to multiply, whatever that is in our application, in our column, we wanna do some sort of multiplication of that value. And so we don't wanna have to constantly code this up as a value getter and value getter params functions and all of that. And so what we can do is we could a higher order function that will provide to AG Grid and we'll be able to customize that. So it's a little there's a lot of typescript in here but the takeaway here is down here is in this, the function that's being returned, we can do whatever logic we wanna do inside of a value getter. So I've got some comments here. You can read through that kind of describes this value getter higher order function. The idea here is that I can use this value getter function. So now inside of my value getter, I can actually just invoke this multiplier value getter and this function, I'm gonna say, hey, I want you to get the price and I wanna, I want you to multiply that price by the tax rate inside of my row data. And so I might have the same use case in lots of grids, you know, throughout my application and I wanna be constantly be writing the same value getter over and over. And so this is an example where you could use like a higher order function to accomplish this. And feel free to take a look at that example on stack lists and run it if you'd like to. And again, there's a little bit more explanation in the course materials that you can review as well.

17. Value Formatters and Performance

Short description:

The value formatter allows us to format the computed value for a cell. It is an optional callback function that applies formatting to the value, such as localizing, showing as currency, or formatting the date. The value formatter is invoked by aggrid for each cell with a value formatter function defined. It receives the value formatter parameters object, which includes the computed value. The value formatter can customize the display or formatting of the value, and the formatted value is injected into the DOM as text. The value formatter can be used in combination with value getters and cell renderers. It is called every time a cell needs to be rendered, along with the value getter if present. The performance of the cell rendering pipeline is optimized by virtualizing the rendering of cells in large grids.

All right. Value formatters. Got it. Do you have any, any other questions that we had? Yeah, I think Alex had a note here about the data dot product. So we'll get that fixed up in the solution, so. Okay. Value formatters. So let's talk about what these do. So the value getter is kinda the way we compute the value for the cell. What the value formatter allows us to do is to then format that value. So this is an optional callback function that we can write that enables to format or apply formatting to the value. For example, we might want to localize the value or show it as currency or format the date, lots of different use case of where you might want to format data after you've computed or calculated that piece of data. Just like the value getter, the value formatter functions going to be invoked by aggrid for each cell that has a value formatter function defined for its call and definition. And the function will be invoked with the value formatter parameters object. Let's go ahead and dive in and take a look at what we're going to be getting in that value formatter parameters object. So we can see here that we're getting a lot of the same things we actually got before, including that grid API, the column API, the row node API, but we're also getting some additional pieces of information specifically around the value. So what are the differences here? Well, that get value utility method that we talked about previously is not available to us here because the value has already been computed for us by either the field property or the value getter property in the column definition. So instead, we're going to be provided with the value of the cell that's already been computed and calculated for these four matters. These four matters are running after that value has been retrieved. So inside this value formatter, we're gonna be really just interacting with the value here. Let's go ahead and take a look at an example. So here I've got a price column. And what I wanna do is I wanna format the price column to show these in essentially a nicely formatted currency format. So here we're gonna use the International API along with the number format class to format these numbers in the nus locale. I've got a minimum number of digits and a maximum number of digits. So that way we're kind of controlling how many spaces that we're showing in both for the minimum fraction and the maximum fraction. So for example, if we wanted to format this using kind of a standard currency, we just could put two there to control how many dishes we're gonna show. Again, just like the value getter, we're gonna need to test to see if we even have a value. Sometimes value will be undefined if we're using some of the grids grouping features, for example, so if it's undefined, we're just gonna format the number zero, but if it is defined, we're gonna go ahead and use that format we've created to format out the value that we've computed. Again, these are simple callback functions that we're gonna put inside these column definitions. Let's go ahead and pass it over to you to give it a try. What we're gonna do is we're gonna write a value getter function for the total column format to format the value using the number format class. You can use number format class in a lot of different ways. If you jump ahead, you'll see that we're using the currency format or the currency style to format that in the USD, but you can use it in whatever way you want to. And essentially what you do is you're gonna drop a number formatter inside the value formatter for the column filter. So let's take a look at where that's gonna go. So right here, for the total column, we're gonna drop a value formatter here that's gonna format those values using the number format class in the international API. Hopefully, this one's fairly straightforward. We'll give you a couple of minutes to work on this one. If you have any questions, feel free to ask them in chat, which there might be some questions. Looks like Brian already answered that question. Yeah, I think the filter in the previous exercise didn't need to be there. All right, unnecessary. I think one of the things that maybe we didn't specify and I was maybe thought, I was just thinking about it. I wanted to clarify. So there's obviously like, as Mike mentioned, it's a cell rendering kind of almost like a pipeline. And so you don't have to use value formatters with value getters, right? So a value getter comes first in that pipeline, and that's where we can say, hey, AG grid, let me give you the value. And again, you don't have to use a value formatter with that. AG grid, you could say, here's the value, just like we did in our previous exercise. And then it'll render that inside as the, like inner text or the text content within that development. With a value formatter, again, we don't have to use it with the value getter, we can, so whatever value after either the value getter or after the field binding will then come into the value formatter. And then we can use that value and then customize kind of the display or the formatting of that value. And that value is still injected into the DOM as the text, right? So it's still just shoved inside of that div element as pure text. So we're not doing anything real fancy in terms of display any sort of like HTML or like buttons or anything that's interactive inside of that cell. And we'll learn about the cell renderer next, which allows us to then customize the complete rendering inside of that div element. And we can use all three of these together, we can use just one of them kind of mix and match based on your use case in terms of how you get the data, how you wanna format the data and how you wanna render that. And that's it. Let's see, we got a question here, a couple of questions. Value former cell renderer are the same. Okay, I think I just covered that. And then another question, value getter is called a lot more often cause it's needed for sorting, right? Formatter is just for onscreen elements. That's a great question and I'd have to look into that to determine I would, I think the value formatter is gonna get called this. I mean, if you have a value getter and a value formatter, I think that's gonna call both of them every time it needs to get the value and format the value anytime that cell is being rendered, if you will. And that'll happen, it depends based on sorting, the value getter would be called more, that's right for the sorting cause it doesn't need to format the value. And then anytime it needs to render it, it's gonna call that value formatter. And remember that let's say you have like 10,000 rows in your grid, certainly it would be not performance to display 10,000, to inject 10,000 rows of div elements inside of the DOM. And so it's gonna kind of virtualize those and create a buffer, kind of ahead and before and after or whatever's being displayed in the grid and render those dev elements, that way as the user scrolling through the grid it can render those and display those as performance as possible. And so in those cases, you know, it's gonna kind of invoke each of these callback functions accordingly. Yes, I'm gonna add a little bit of context here in terms of agent grids performance. I think there's a lot of interest about overhead for the cell rendering pipeline.

18. Value Getters, Formatters, and Cell Renderers

Short description:

The value getter function can be called by default for sorting and rendering, which can have a performance impact with large datasets. AG Grid offers a value caching mechanism to optimize performance. The size and expiration of the cache can be customized. Additionally, column virtualization can be enabled or disabled based on the requirements. A value formatter can be added to format the total column with a specific currency. Reusable value formatters can be created as higher-order functions. The cell renderer allows for advanced customization of cell rendering, including complex controls and styling. It should be used sparingly due to potential performance impacts. The cell renderer can accept undefined, a registered cell renderer string, or a React component. The cell renderer params provide access to the calculated and formatted value, as well as programmatic APIs for grid control. An example of a cell renderer function is provided.

It's worth noting that the value getter function is gonna be called by default every time agent grid needs that value. So yeah, it's gonna be called for sorting. It's be called for rendering or display. And that can have a pretty big overhead with big dasets.

Agent grid does come with the ability to do something called value caching. You can kind of opt in to the value cache. So if you turn on the value cache, then each time a value getter is executed, it's gonna kind of cache that value and only call your value getter once. So this is for a fairly advanced use cases where you know, you're having performance problems or you know, you're doing time sensitive tasks inside of your value getter function. But I just I kinda want to point out that there is a value caching mechanism built into AG grid. If you have a concern about the performance of the subreg pipeline.

And Kate, can you customize the size of that cache? I know you can customize the size of it and how long it's going to take to like expire. Or how long, yeah. Yeah, just like a kind of a normal caching solution. Yeah, and you can also customize like the blocking and the virtualization and some of that as well. If you need to, if you want more or less in the DOM, you could turn on and turn off column virtualization as well. That's something that you need to do.

All right, Brian, you gonna walk through this exercise? Yes, yeah. Let me get my Chrome up here, we're in the value formatters, there's our exercise. Pull this up. All right, so what we wanna do is we want to add a value formatter to our total column. So I'm gonna come down here, we're gonna add our value formatter and we're gonna get a params object. And inside of here, what we wanna do is we wanna first just make sure that we have data. So we're gonna say, if we don't have any data, let's just return zero. Otherwise, what we wanna do is we're gonna use the international number format and we're gonna use the ENUS locale and then we're gonna customize this, we're gonna say the style is gonna be currency and the currency is gonna be USD. And then we're gonna call the format method on that and give it to the value. And so now when we come over, we should get a nicely formatted USD currency. And of course, you can use international number format to format this and other currencies in the styles. Just like I mentioned, with the valueGetter, you can also create higher order functions for value formatters. I'm not gonna dive into this one, kind of the details of the implementation of it. But I think the takeaway here is, I can create a reusable value formatter, high order function, that allows me to do maybe a decimal value formatter. And then I can use that down below and say, hey, use this decimal value formatter. I'm gonna do some TypeScript to kind of get some type safety here. And then I want you to have, you know, two as the number of digits. And then we could use, you know, it's just a function. So you could just reuse that anywhere you need in your application. Or if you're doing some kind of fancy monorepo, you could share that across applications and projects. All right, cool. Let's go on. Oh, should we take a break, Mike? What do you think? Yeah, it's like just a short break. Yeah, let's do seven minutes. So we'll start back up at five after. All right, let's dive back into it. Mike, you want to teach us about the cell render function and how we can customize the rendering of cells in the AG grid? Yes.

Okay, so as part of the cell rendering pipeline, we have so far learned about the ability to calculate values using the value getter and then format values using the value formatter. But what we might want to do is like really do something advanced in terms of the way we render the values, maybe show complex controls, complex elements or styling. In those cases, that's where you want to break into a cell renderer. So after the value for a cell is determined and we have format of the value, those two things have run. We can then use a cell renderer to have full control over how that cell gets rendered by AG grid.

It's important to know that we only wanna use these when absolutely necessary. Because what's really gonna happen here is that we're gonna be adding additional elements, event listeners, you know, things that might slow down your grid is what we're producing the cell renderers. And so we all wanna use them when absolutely necessarily, and when necessary because this is one of these areas in which you can start to really impact the performance of your grid when you're working with really large data sets.

So the cell renderer for a column definition accepts the following values. So it can accept undefined, which basically means, hey, just render the value that we've calculated and formatted for you as a string, as the text content in the cell. It can also accept a string that references a registered cell renderer. This would be handy if you wanted to make your column definitions serializable. Or it can be a React component, and that can be either a function component or a class component. We're gonna really just be looking at function components in this particular workshop.

Before we dive into it, again, let's talk about some of the pieces of information that we're gonna get inside of these cell renderer. So we're gonna be getting the cell renderer params, and these are very similar to what we're getting inside of the value formatter params. Except it's worth noting that when we're talking about the value at this point, we're really talking about the value after it's been calculated using the value getter and formatted using value formatter. Again, like the other functions we've looked at so far, these you can get access to some of the programmatic APIs for controlling the grid, the column or the node itself, along with some of the configuration that we've already set up for the grid.

So let's take a look at an example of a cell renderer function. And in this case, I'm gonna do something very similar to what we've already done, just to give you an idea of kind of where we're going with this. We're gonna look at some more complex examples, of course, as we get more into this. But, here in the cell renderer, what we're gonna be doing is, we're gonna be looking again at formatting some values. But it's important to note that we're doing this as a cell renderer rather than a cell formatter. And this, as we'll see in an upcoming example, is gonna let us do some interesting things in terms of controlling the template. So cell renderers will be a function or a react component class. So here, we're testing to see if we have a value. If we don't, we return null.

19. CellRenderers and Cell Editing

Short description:

In this section, we learn about CellRenderers and how they allow for full interactive display of content inside of cells in AG Grid. CellRenderers are React components that can be used to customize the rendering of cell content. They can utilize hooks, set up refs, add event listeners, and render other React components. We also go through an exercise that demonstrates the usage of the CellRenderer function to add a CellRenderer to the Date of Order column. The exercise involves checking if the value is not undefined, returning JSX that includes a material icon next to the formatted date string, and using styling and the DateTimeFormat class to format the date. We then move on to cell editing, where we enable the editable property on the column definition to make a column editable. AG Grid provides built-in cell editors for text, large text, date, select, and rich select. We can also enable cell editing programmatically using the grid API. The default editor used when editable is set to true is the text cell editor.

And if we do, we're gonna use the Number Formatter on it to kind of render out that format. Let's take a look at a more complex solution real quick. Let me copy this link here. We'll actually be implementing this ourselves in just a second here. But here, what I'm doing is, I've got a cell renderer for the date of order. And what I'm doing is, I'm gonna take the date and I'm gonna use the international datetimeformat class to format that value out. And then because these are actual React components, or kind of like an inline component here, what I can do is, I can return full JSX here to control the way that the cell gets rendered. So here, you can see that I'm returning a div. I've applied some styles to it. I'm showing an icon next to the date to denote to my users that this is a date, and I'm using the datetimeformatter to show that date, nicely formatted. So, CellRenderers are where you get to do full interactive display of content inside of cells. Since these are React components, you can use hooks inside of them. You can set up refs to make these things interactive and add event listeners to these things. You can render other React components inside of here. This is where you get to do a lot of the more advanced things in terms of rendering data inside of this grid. And I went through that fairly quickly, so I'll pause this for a second to see if there's any questions about the CellRenderer before we move on to the exercise.

Okay, well, I'm gonna hand it over to you. I'll give you an exercise to do. So, the goal of this exercise is to learn how to use the CellRenderer function. So, you're gonna open up the exercise. And you're gonna add a CellRenderer to the Date of Order column. First, check to see if value is not undefined in the programs object that you get passed to it. And then, you return some JSX that includes a material icon next to the formatted date string. So, if you need the particular bit of HTML to render that event icon, it's listed there as a hint. Again, keep in mind that this CellRenderer function is basically a React component, so you can return full JSX here. Give you a couple of minutes to write that. Again, if you have any questions, feel free to put something in chat or put something in Discord. We've got a question from Corrine. So, the value in params here will be the result of value getter if it's specified, right? That is correct, yeah. So, if you have a value getter, the value that's passed to both the formatter or the cell renderer will be that value that was retrieved from the value getter function. If you don't have a value getter, whatever that value would be based on the field binding that you've used. So, in the beginning of the course, we were just using the field prop and setting things like to the name and the color. Then that value to the cell renderer or to the value formatter would be, again, that value of whatever is kind of binded to your row data. Yep. That's a good question. All right, I'll go ahead and get us started. We wanna stop sharing real quick, Mike, and I'll run through the solution. All right, so if we open up the exercise, we've got the cell renderer, it's kind of already stepped out here from the previous demo that Mike had for us. So we're gonna just get rid of this here. We're still gonna check the value, but equals undefined, we're gonna return null. And then here, instead of returning just like a value that would be injected as the text content of the development, we're gonna return some, we've got, again, there's the full React component, so we could do whatever we want here. So I'm gonna do a style on this, and I'm gonna set the display to be flex, and I want align items to be center, and I'm gonna close that div, I don't know why I'm not getting that auto-complete, but whatever. And then here I'm gonna have my material icon. So I'm gonna do a class name, and this is gonna be material icons, and then this is gonna be an event icon, and that should give us now our little calendar, display flex align items center, why is it not aligned? Interesting. And then here I'm going to create a new daytime format, and I'm gonna use the unes format, and then I'm gonna format our value. And so now I should get my daytime format in there as well. Again, this is I could use refs here, I could use my hooks, kind of do whatever I want inside of this functional component Let us know if you have any questions, those in the chat, otherwise, we're gonna move on to cell editing. And we're getting close, I think we have two more exercises left. We got about 40 minutes left in the workshop so we've got two more exercises left, and we're gonna cover the content around cell editing and we'll talk a little bit about styling at the end.

Okay, so, so far we've talked mostly about how to render data inside of the grid. But AgGrid actually works both ways, it's both for rendering data, large sets of data, and also allowing users to edit the data to rendering with AgGrid. So we're gonna talk a little bit about cell editing or giving users the ability to edit data. And what we can do is we can actually enable the editable property on the column definition to make a column editable. There's a couple of different built-in editors we're gonna talk about but just by setting it to true, columns are immediately editable and we can also enable it programmatically via the grid API. So to enable cell editing, we're gonna go update the column definitions that we've written this far and we're gonna set the editable field on that column definition to be true. That's all we need to do to get basic text editing working inside of Aggrid. We can also do it programmatically. We've talked a little bit about the grid API and how you do things programmatically. So if you're showing you some of that more programmatic code, if we have access to the grid API, we can also programmatically start editing cells using that grid API. So, Aggrid comes with a number of built-in cell editors, you'll need to go implement your own editors if one of the built-in ones already suffices for your needs. So Aggrid provides the following cell editors out of the box, provides both a regular text editor, sort of like a short text input and a large text editor, a more spacious text editor. It gives you a date editor. Though I'll note that just kind of like the filters that we looked at an hour or two ago, it's gonna use the built-in browser date picker for that date editor. So if you wanted a fancier date editor, like one provided from a cheerleader or your favorite react component library, you might want to use your own, however, if you're okay with the built-in browser date picker, then the built-in date editor in Aggrid is a great option for you. And there's also a select editor. Again, this can use the browser's built-in select control, but that gives you the basic ability to do a select editor. There's a rich select editor. This is in the enterprise version. So if you needed the rich text editor or the rich select editor, you'd want to go ahead and switch over to the enterprise version, it's not built into Community One. Okay, so by default, when we set editable to be true, the default editor gets used and the default editor is the text cell editor.

20. Cell Editing and Built-in Cell Editors

Short description:

To enable cell editing, set the editable property to true. You can use built-in cell editors like the large text cell editor or the select cell editor. Double-clicking on a cell allows you to make changes and save the edited data. Editing is available for various types of data, including dates and account numbers.

So whenever we set editable to true, it's going to give us a text control to edit that cell. You can use the cell editor column definition property to specify a built-in text editor or a built-in cell editor or your own custom cell editor that you might implement with React. And we're look at both of these. But first, we'll look at some of the provided or built-in ones. So we can specify the provided large text cell editor like this. So here, we've got our account number. You can see that I've set the editable field to be true for this particular column. And then beneath that, I'm specifying the cell editor. And the cell editor here, I'm saying AG large text cell editor. That's letting AG grid know to use the built-in large text cell editor inside of here. We can also have it use these selects cell editor by specifying that as our cell editor. And there's the ability to specify like cell editor params where we could give that select editor the list of options to display inside of that select. And so once you've kind of got some of these configured, the way this ends up working is we'll have our grid here. Give us a minute to open up. And it looks the same, but now if we kind of double click on a cell, we can make changes to these and kind of save that data here by editing that cell. So I can make a change to this date. If this was using the date editor, I go in here, change some of these pieces of data, make some changes to the account number if I wanted to, all that's available to you once you make some of these editable.

21. Cell Editing and Custom Cell Editors

Short description:

To enable cell editing, set the editable property to true. You can use built-in cell editors like the large text cell editor or the select cell editor. Double-clicking on a cell allows you to make changes and save the edited data. The built-in cell editors are fairly basic, but you can build custom cell editors using React to let the user edit the data in the grid using more powerful controls. We're going to build a custom color cell editor component using React. A cell editor has a get value method that is invoked after editing is complete. To establish this communication, we use the use imperative handle hook to customize the ref that gets forwarded back to ag-grid and expose the callback functions that ag-grid expects.

So I'm going to give it to you. Again, this is like we have just one more exercise after this, so we're getting close to wrapping this up. But you're gonna go and open up this exercise on StackFlips. This is a really straightforward exercise, I hope. You're gonna enable cell editing for the customer name column just by setting editable to be true. That'll give you the built-in default text editor. And you're also gonna enable cell editing for the accounts number column and use the AG large text cell editor as the cell editor for that column just to export using one of the built-in ones. Once you've got that done, just kinda play around with the two of them. Feel free to play around with some of the other built-in cell editors. And then after a few minutes, we'll get to Brian to walk through the solution and then we'll talk about how to write your own cell editors using React. We did have a question I think we missed or came in after we started moving on to the cell editing section, said, what if you use a value formatter? Does it receive that or is using both not supported or encouraged? So that's a great question. So if you're using value formatter with a cell render, you can absolutely use both of those together. You will get to the value that it runs the value formatter first before the cell renderer, kind of in that sequence, value getter, value formatter, cell renderer. And so if you do use value formatter, the value that you return on the value formatter callback function will be the value that's provided to the cell renderer. I would say that both, in terms of like whether they're supported or encouraged to use both, you can use both. I usually find that if I'm using a cell renderer, I don't need a value formatter. Although, let's say if you've got like some great reusable functions that format it to a currency, or format it, or maybe not a currency, that's not a good example, but format it to like a decimal number, or do some sort of rounding, or maybe some sort of business logic, you know, that's kind of embedded into your ed grid, you might wanna use both together. Or you might wanna format that value first before you render it, so. There's a question here. Can you set any validation on the editor, or do you need to write your own? So there are some like built-in validations for some of the built-in providers, for example, large text Sol Editor, lets you kinda specify a max length. However, there's nothing more complex than that. So if you needed a more complex validator, that'd be a great use case for running your own Cell Editor, instead of using one of the built-in ones. Yeah, that's right. And there's also, I think a value parser function. So whatever value comes from the user, you kinda parse that value if you need to as well. So there's a hook there, but yeah, if there's a value that's entered that's kind of invalid or something, you would have to code up that validation. Grace asks, are the values are synchronized with the original data or do I need to update it manually? It's a great question. We're actually gonna cover this in persisting data here in a few chapters so just stay tuned and we'll get to that. So, if I change customer ID to one that doesn't show first when you're using ascending. So the reason for that is when we're making, we're just using the text editor right now, which is actually changing those account numbers into strings, and so the assorting is gonna try and do it numerically. Now that we've introduced strings, you're kind of breaking formatting. So I wouldn't expect it to quite work the right way for what we're doing right now. Again, you'd probably use actual number editor that we have to write ourselves to make that work the right way with sorting. But it should work correctly for the customer name field. You could use a value parser here, and you could just pass it to the number function or the number class, right? And just parse it, parse in to parse float or whatever, and do it that way before the data gets shoved back into the grid. All right, let me pull this up here. We're doing the cell render function, excuse me, cell editing. I gotta get to the right exercise. Share my screen. All right, cool. So in this instance what we wanna do is we want to add a large text cell editor to our account number. So if we come into account number, right now we've got our field wired up and our filter. So what we wanna do is first we wanna make it editable by setting that to true. And then I'm gonna say for the cell editor rather than using the default text cell editor, I wanna use the AG large text cell editor. And then I'm gonna also have this as a popup, so I'm gonna do cell editor popup and I'm gonna set that to true. And let's get this out of the way, move this over. Nope, I hit save. And now if I come into the account number and I double click on that, I get a large text cell editor and it's in this popup. All right, great. Let us know if you have any questions, otherwise let's keep moving along and we'll talk about the cell editor component next. Okay, so the built-in cell editors are fairly basic, but we've already hit a couple of use cases where we're talking about limitations, like validating the data we're putting into these things or making sure we're doing the right data types coming back out of these controls. And so those are great cases where you might wanna go ahead and write your own custom cell editor components. All right, if you're not familiar with cell editor yet, you can go to my blog, and I'll get into those a little bit more. So, the Provide ones are adequate, but we can build custom cell editors using React to let the user edit the data in our grid using more powerful controls. So, here's what we wanna do. We're gonna build a custom color cell editor component using React. So, we've talked about product color previously. This is gonna let us edit the color of some of the products or the orders. This is a collection of structured answers in color input that you could imagine maybe reaching out to your favorite React component library to pick any fancier color picker if your component library of choice happens to have one. There's gonna be something kind of interesting or different about these cell editors in that we're gonna have to interact with the ag-grid API in a different way. So, a cell editor has a couple of different methods and there's only really one that we need to concern ourselves with for this flavor of React and ag-grid and that's the get value method. So we're gonna either implement or provide ag-grid a get value method from within our cell editor component and it's gonna be invoked after editing is complete. So kind of when the user blurs controls or closes the pop-up to provide the value back to the grid that the user had entered. To establish this communication, we have to use some more advanced React hooks here to make this communication possible. So by, the way this is gonna work is we write a cell editor, React or sorry, ag-grid is going to render that cell editor as a React component. And what it's gonna do is it's going to try and get the ref of the component that it just rendered. And what we're gonna need to do is we're gonna be going to need to use the use imperative handle hook to customize the ref that gets forwarded back to ag-grid and expose the callback functions that ag-grid is expecting of us. So, as I mentioned, ag-grid is gonna need us to give us a get value function that tells ag-grid how to get the value out of this control. So we're gonna use the use imperative handle hook here to customize the ref that's being forwarded back to ag-grid to have a get value method on it for ag-grid to call. I know it's kind of a lot.

22. Custom Cell Editor with React

Short description:

In this example, we're building fancy inputs for ag-grid using React. We use the useImperativeHandle hook to expose the getValue method that reads the value from the input. The input is focused when the cell editor is opened using the useRef and useEffect hooks. The color picker is rendered as an input with the type set to color. The color value is updated in state when the user selects a new color. The getValue method is called by ag-grid to retrieve the final color value. To configure the custom cell editor, we specify the function as the cell editor in the column definition. The useState hook manages the cell editor's value, the useRef hook sets up a ref for the color input, and the useEffect hook focuses the input when the cell editor is opened.

I'd highly recommend reading some of the React documentation on the use imperative handle hook if you want some more information about what's kind of going on under the hood here of use imperative handle. It's honestly really great for anytime you're trying to build like fancy inputs using React. And that's essentially what we're doing here is we're building really fancy inputs for ag-grid to consume and we're just making sure that all the inputs that we developed for ag-grid kind of adhere to this interface of having this get value method out. There are a couple of other methods we could implement in this use imperative handle hook. There are kind of hooks for when they get called whenever the user starts editing or stops editing or cancels editing that we could use to customize some of the behavior of the editing experience. But for this workshop, we're just gonna be focusing on this get value hook.

So in this example, what's going on here? Well, I've got a piece of State that I'm gonna be using to control the value of a color input. So when the color input is interacted with, we're gonna be updating or changing the state. AGgrid's gonna call this with a set of cell edit props and we can use that, get the current value of the cell that's being edited. So we're gonna start off at whatever the current value is. These are gonna interact with the cell editor, update this piece of state. And then when they close the editor maybe by hitting the enter key or escape or blurring it away from the editor, AGgrid is then gonna call getValue to get the final value that was produced from this interaction. So using this, we could build out a full cell editor. So let's take a look at what a full example might look like. I'm just gonna open this up on Stacklits so you can see a running example. There we are. So let's see here. Oh, I think this like actually might be not quite right. Yep. There we go. So I have my full example here. And what am I doing? We've already talked about the state piece here. So this is what we're gonna be using to bind or capture the state of the value of our input. And then I'm using the use imperative handle hook to expose this get value method back to AgGrids that knows how to read the value out of my input. I'm gonna use an effect here specifically using this input ref that I have bound to the input control to focus this input whenever this component is first rendered. So whenever we open up the cell editor it should automatically focus those controls that the user can immediately begin interacting with it and picking a color. From there, we're just gonna render out an input. I've got the type set to color so that uses the browser's built in color picker. Whenever the user picks a new color we're gonna update this piece of state. Whenever we exit this color picker AgGrid is gonna call this get value method to read whatever color is set. So here I've got this color. I'm gonna double-click on the cell to get the editing experience. And now you can see here that we have the browser's built in color picker. I can use this to pick a different color out. We may wanna steal this color. And then when I hit escape you can see that the color was stored or changed here. To configure this once I've got my color editor class or function written what I can then do is in my grid in the column definition I'm just gonna specify that function as the cell editor. So instead of using one of the string based approaches that we did previously this drop in a reference to that React component right here as my cell editor and that tells AGGYbrid to use that React component for the editing experience. Are there any questions about the custom cell editor before I hand it over to you to try? All right. So let's just quickly review what's going on here, what each hook is doing inside of this example, use state is containing the value of our cell editor, I'm using the use ref hook to set up a ref for the color input itself so we can focus the input when the cell editor is opened. I'm using the use imperative handler hook to set up callback functions that allow us to communicate with AGGYbrid. We have to implement quality to send values back to AGGYgrid, but there are other methods we can implement here if we wanted to handle some of the life cycle of the editing experience. And then finally the use affect hook to focus the input when the cell editor is first opened. We're gonna talk about this, but registering components, we can then provide the component reference directly in the column definition. There's also the ability to register the component using a string constant. The benefit of this approach is that if we wanted to serialize our column definitions for whatever reason, we couldn't make that or we can do that. So finally we kind of drop in that color editor as the cell editor for the color field. So with that, I'm gonna give it over to you. Oh, it looks like the slides missing a little break there. Sorry about that. But you can open up the exercise on stack blitz. You're gonna do two things first in the color editor component. You're gonna use the use state hook to capture initial value from the props and you're gonna implement the get value method to return the current value back to NgGrid. Then finally, you're gonna update the column definition for the color field to be editable using the color editor as the column editor for that color field. So three things really to do here. A lot of this is already been done for you, but hopefully this gives you a taste of writing your own custom cell editor using React. Give y'all a couple of minutes to do this and I'll hand over to Bryan to walk through the solution.

23. Custom Cell Editing Solution

Short description:

To set the initial value of the input, use props.value. Return the current value in the get value function. Set the cell editor property to the color editor and the editable property to true. Now you can change the color using a custom component for cell editing.

All right. Shall we go ahead and get started with the solution? Go for it. All right, so we've already wired up the color editor and we've done a lot of the boilerplate, almost setting up the props and we've got our use imperative handle hook or use effect hook, Mike showed us in the example and our input. The first thing that we need to do is we need to use the props.value to set the initial value of the input. So instead of the empty string, we're gonna do props.value here. And then we need to return the value because once the editor is, the editing experience is kind of finished whether they hit enter on their keyboard or blur the field or whatnot, this get value function is gonna be invoked by aggrid and so we're gonna return our current value that's in our state. And then the last thing that we need to do is come over to the grid and we need to set the cell editor property to use the color editor and we need to set the editable property to true. So let's do editable, true. And then we don't wanna use the text editor, we wanna use our custom cell editor and we're gonna use the color editor. And we've imported that color editor up here above already so that way we can use that. So now we double click, we should be able to come in and change the color using a custom component for cell editing. And we've got the solution outlined here and you can also see the solution on StackBlitz as well. And it'll kind of provide you with some more details around the cell editing with a custom component.

24. Persisting Data with Value Setter

Short description:

We'll discuss how to persist data in AG Grid when using the cell editing experience. By using the value setter function, we can notify AG Grid of data updates and refresh the cell accordingly. The value setter function is invoked by AG Grid with the old and new values as parameters. If the values are the same, we return false to indicate that the cell does not need to be refreshed. If the values are different, we can notify a parent component and return true to trigger a cell re-render. This allows us to handle data mutations and avoid unnecessary cell rendering.

All right, let's keep moving forward and let's talk about persisting data. Okay, so up until this point, we're making changes using the cell editor experience, but we're not actually persisting this anywhere. And the reason it looks like it's persisting is because what aggrid is doing is actually just mutating the data that you're binding to the grid. And so we're gonna talk about how to handle some of these mutations or how to even avoid some of the mutability that's occurring.

So we have several options for persisting data. By default, as mentioned, the field bound in the row data is just updated, aggrid just straight up mutates the data that you are binding there. And so we can listen for these changes using the value setter function as a means of notifying, or persisting these maybe to back end or letting a parent component know that some of this data has been updated. The grid API also gives us some events that we can listen for, and these are exposed as props on the aggrid react component. And so I'm gonna talk about these at a high level. There's no exercises here, just kinda wanna walk through some general strategies for how to handle persisting data from the cell editing experience.

So first, let's talk about the value setter function. So this is when data is managed by the grid, and this is the inverse of the value getter function that we've already written. It's gonna be invoked by aggrid with the value set of params params object. And what we can let aggrid know is we can let aggrid know whether or not we've successfully updated the data. So we can return true by the value setter function to let aggrid know that the update was successful. We need to refresh the cell. We can return false to indicate the value is not updated. In which case the cell would not be refreshed. Let's take a look at an example. Like most things, you would specify a value setter in the column definitions. So here for the customer name, I've written a value setter. The params that get passed to it gives you the old value and the new value. So here we could kind of inspect to see, hey, was the old value the same as the new value? If so, no need to update or refresh the cell. Don't re-render it. Don't redraw it. Go ahead and return false. This is all good. If the values don't match, then something has changed here, and maybe we want to notify a parent component that this has happened. So maybe we'll kind of call a prop that was passed to us to let the parent know about it. And in which case we'll return true to aggrid to let aggrid know that it does need to be re-rendered this cell.

25. Handling Cell Value Changes

Short description:

We can listen for changes in two ways: by checking if the old value strictly equals the new value or by handling the onCellValueChanged event. The onCellValueChanged event is emitted whenever a cell value is updated after a user edit. By binding to the onCellValueChanged prop, we can inspect the old and new values. This allows us to get notifications of changes made by AGgrid, even if we want it to manage the data.

So a few things to know about this. First, we're checking to see if the old value strictly equals the new value, you can implement whatever comparison you wanted to here. We're just using strict equality. If so, we're returning false to indicate that the cell does not need to be refreshed. And to explain that in more detail, what we're talking about is kind of like almost performance optimization here. We've talked about this whole cell rendering pipeline. This is a way to kind of escape out of that cell rendering pipeline or say, hey, don't re-render this entire cell. Nothing's changed here. Next, we call an onNameChange callback function to notify the parent component, the value has changed. This maybe just passed in as a prop to our component. In which case, we're gonna return true to let AGgrid know that it needs to re-render the cell and kind of go through that entire cell re-rendering the pipeline one more time. There's another way to handle some of these changes. So again, assuming we want AGgrid to be in charge of managing the data and we're okay with mutability, then another way in which we can listen for changes is by handling the onCellValueChanged event. This is gonna be emitted whenever a cell value has been updated after a user edit. So this is exposed as a prop that we can bind to on the AGgrid React component. And this is gonna give us this cell value changed event that we can handle to do the same thing we just did before. So here in the template that I'm returning back from our grid component, I'm binding to the onCellValueChanged prop. And inside of here, I can also inspect the old value and the new value. And in this case, I'm just kind of logging them out. Again, this is still letting AGgrid manage the data, it's just mutating the data underneath the hood, but we can at least get notifications that something has changed if we needed to do some kind of notification or persistence to our API.

26. Handling Data Changes and Styling in AGGrid

Short description:

AGGrid provides an onCellEditRequest event that allows you to handle data changes yourself when the grid is in read-only mode. To use this event, you need to put the grid in read-only mode and provide stable references to each row using the getRowId prop. You can then handle the SellEditRequest event, which provides the previous and new values. It is recommended to use immutable data structures and the Grid API's setRowData method to update the cell value. AGGrid also allows you to customize the styling of cells and rows using cell styles, cell classes, and cell class rules. When overriding global CSS styles, be cautious not to change CSS positioning, overflow, or pointer events as it may cause issues with the grid. AGGrid provides several pre-built themes that can be customized to style the grid.

Okay. Okay. There's another method that I think is probably a little bit more friendly to me as someone who likes to handle data changes myself and wants to avoid mutability. There's an onCellEditRequest event. And this is emitted when the cell value has changed after editing, but this is only gonna be when the grid is in read-only mode. So when your grid is in read-only mode, AGgrid is no longer gonna be mutating the data you bind to it. Instead, it's gonna leave it up to you to handle the changes yourself in how to update the row data. And so to use the cell editRequest event, you have to put the grid in read-only mode. Once you've done that, we can use a similar prop, the onCellEditRequest prop, to handle any changes in our data. Let's take a look at an example of this. So there's a couple of things we have to do that are a little bit different. First, we have to tell AG Grid how to build IDs for each individual row. So because it's no longer managing the data internally to AG Grid, it's not going to be able to do some of the performance hashing that it's doing underneath the hood to build hashes out for the rows and keep track of which rows are which. And so you're going to need to tell AG Grid how to identify which row is which. This should be very familiar to you if you've ever done like how to specify a key when you're mapping out an array into a bunch of JSX elements. You need to give AG Grid a way to have a stable reference to each of your rows. From there, we're going to put our grid in read-only mode. So we're gonna say read-only edit is true. This means that from this point forward, AG Grid is not managing the data itself. It's going to rely on you. So we're kind of in immutability land here. And then we get this on-cell edit request callback that lets us handle whenever a piece of data changes. It's gonna give us the old value before is edited, the new value that is being requested that we changed to. So in this case, we're only logging out the data, but this is where you would want to actually apply the changes immutably to your row data yourself, instead of relying on AG Grid to mutate the row data yourself. So let's review what's going on here. So whenever we're in read only mode, which is the one that I recommend you use, it gives me the most familiar for React developers. First, you're gonna use the get row ID prop binding to provide stable references to each unique row. So you kinda have to build like an ID or a key that lets AG Grid know which rows are which. And again, that's for performance reasons so they can optimize the rendering experience for each row. Next, we have enabled read only mode by setting the read only edit prop to be true. And then finally, we're binding to this onSellEditRequest prop to handle the SellEditRequest event. We get this SellEditRequest event object that contains the previous value and the new value that's being requested. In this example, we're just logging it out. So how do we actually update it? Well, right now we're only logging out the data, but because we're in read only mode, since we're only logging it out, the value is not actually being updated. We would need to use a strategy for updating the cell value. So using the getRowId function, I'd highly recommend using some immutable data structures here. Maybe you're using Redux and you want to use the Redux pattern to manage your data immutably, or maybe you're using EmberJS and you wanna go update the data that way, or whatever your kind of immutable data strategy is, you would kind of use that in conjunction with the getRowId method to save that value out. Then use the Grid API's setRowData method to actually set the data again and apply that, or you could apply that transaction via the Grid API to let the update know that it needs to take place if you're in read only mode. Brian, is there anything you wanted to add there? No, I think you covered it all. So again, that was pretty high level. There's no exercises for persisting, so feel free to take a look and go through the slides. It kind of covers, again, all these different strategies that you might want to invoke in your AGGrid applications for persisting these values out. In these examples, we're just gonna stick kind of with the mutation approach where AGGrid is responsible for managing its own data, then a production application, I would highly recommend kind of putting it in that read only mode and handling those updates yourself using immutable data structures. Absolutely. I'm gonna pass it over to Brian to talk a little bit about styling.

All right, so, real quickly, in the last 10 minutes, we're gonna go over how you can style AGGrid. We're gonna talk about cell styles, we're gonna talk about row styles, and we're gonna learn how to customize the themes that are provided by AGGrid. So, AGGrid has several pre-built themes. We've been using the Alpine all along. There's the Ballroom, the Alpine, and a Material theme. Those themes are customizable. We can override global CSS styles that are in our application to style the grid. We can also customize the styling of cells and rows. Take a look at both of those. There's a general recommendation from AGGrid here. So when overriding global CSS styles, so there's a lot of classes on AGGrid that you can certainly target, like agsel, agrow, all of these things if you want to kind of globally apply CSS styles, and you're encouraged to do so. But the thing that you need to be aware of is that you should not change CSS positioning, overflow, or pointer events because the grid relies on those and you'll run into some issues with that. So just be aware of that.

Alright, let's talk about cell styles. So we can specify cell styles using a cell style property and a column definition. We can add classes using the cell class property, and then we can add in remove classes using the cell class rules property. Let's take a look at each one of those. So in this instance, I'm using the cell style property. Inside of our column definition, I can simply hard code the cell style. That's kind of like an inline style that's going to be applied to that div element. I can also add cell classes and accept an array of strings, and I can apply those classes to the cells in this row. So in my customer name column, I can have all of those cells will have the customer-name class applied to it. And I can have multiple here. And then I can also have a callback function for cell class where it receives a params object. In this instance, I'm destructuring that and just kinda plucking out the value.

27. Styling Individual Cells in AG Grid

Short description:

We can style individual cells in AG Grid by using cell classes, cell styles, and cell class rules. Cell classes are conditionally applied, added, or removed to cells based on logic defined in a callback function. Cell styles can override existing styles on cells, but they are never removed. Cell class rules allow for both adding and removing classes based on specified rules. AG Grid manages the application of classes based on the rules provided in the column definition.

And I'm gonna do some sort of logic and say, hey, if the value is equal to zero, then I want the cell class to be this error, otherwise we're gonna have customer name, and then I could target those classes to style those cells appropriately. I can also have cell class rules. Cell class rules is an object, and the property of the object is the class that will be conditionally applied, added or removed to that cell. And then I have a callback function that receives that cell class params object. And I can do any kind of logic that I want inside of here to return a true or false Boolean that then will tell azgrid to either add or remove the appropriate class on that cell. There's a few things to note when regard to refreshing of cells and styles. So when using cell styles property, we can add an override the existing styles that are on that div, those styles are never removed. Similarly with cell class, it will allow us to add classes, but it never removes any of those classes even if we use the cell class function. Finally, if we use cell class rules, this allows us to both add and remove classes. So in this instance, AG grid's kinda managing which classes are applied based on the rules that I provide to that column definition. So that's how we style individual cells inside of AG grid.

28. Row Styling in AG Grid

Short description:

Let's explore row styling in AG Grid. We can add styles to all rows using row styles and conditionally apply styles using the getRowStyle callback. The row class allows us to set classes for all rows, and the getRowClass callback enables conditional class application. Row class rules let us add and remove classes based on conditions. These styling options are useful for highlighting rows and indicating selection.

Next, let's take a look at how we do row styling. So when we're using row styling, very similar to cell styling, we have a row style that can add styles to all rows in the grid. There's also a get row style callback and that allows to conditionally add styles. There's a row class as well, and that allows us to set the classes for all rows in the grid. There's also a get row class callback to conditionally add those classes. And just like before, we have row class rules, which allow us to add and remove classes. Here's an example of how we might configure those on the EGGoodReact component. And I've got my props here and I can do a get row class and provide it a reference to that callback function. I can specify kind of hardcode the row class. I can do the row class rules, which is an object where the property is the class that is applied, and then a callback function that returns a Boolean that either adds or removes the class to those rows. And then I can also just hardcode row styles. So here's an example of those row class rules. Here, I've created this constant that we're binding the prop to. And I've got the row highlight class that is conditionally applied based on the total of the order. And I've got a row danger class that is conditionally applied, added and removed based on the date of order. And then I've also got my get row class function and I provided a reference to that as a prop. And here, I'm doing conditionally adding a row class. Remember it doesn't remove a row class, in this instance, only the row class rules that will add and remove. So the cell styling and row styling is really helpful if you wanna highlight, again, maybe you wanna highlight rows or you wanna show that the rows are selected and all these kinds of things. So it allows you to apply styles broadly as well as conditionally using either as kind of inline CSS or using classes.

29. Styling AG Grid with Themes

Short description:

Agigrid provides several themes, including bollum, Alpine, and material. Each theme has its own characteristics and density. The bollum and Alpine themes offer dark mode options. Customizing themes is possible using theme parameters, CSS variables, CSS rules, and Sass mixins and functions. CSS variables are recommended for customization, allowing for runtime changes. Targeting built-in classes is also an option, but caution must be exercised to avoid overriding critical style properties. Starting with one of the provided themes and then customizing it is a common approach. It is also possible to write a custom theme, although the complexity of doing so is unknown. Overall, AG Grid offers flexibility in styling, allowing you to meet your product's user requirements. If you have any questions, feel free to reach out to us. We appreciate your participation and hope you enjoy the rest of the conference.

And then finally, we have themes. Like I mentioned, Agigrid has several provided themes. There's the bollum theme. This is kind of the original one that came out with Agigrid years ago. It's the good thing about the bollum theme is it's quite dense. So if you are displaying lots of data and you wanna be able to display lots of data to the user, maybe you think something more like Excel or Google Sheets in terms of spacing and all of that.

There's also the Alpine theme, which is a little bit more newer than the bollum theme. It's less dense, it's a little bit more modern looking. And then finally, there's the material theme. And the material theme is generally follows the material specification for the design. It's certainly of the three is the least dense, a lot of white space, and very comfortable in that way. I should also note that the bollum and Alpine theme also include dark mode options. There is not currently a dark mode option for the material theme. And we can customize those things. So we can customize them in multiple ways. We can use theme parameters, we can use CSS variables, CSS rules, and we can use Sass, Mixins and functions. So let's take a look at how we might use those.

So in this instance, we're gonna import the SCSS file as well as the Alpine Mixin. And then I'm gonna go ahead and use that AGE theme, Alpine Mixin. I'm gonna customize that by setting some property values. And there's a documentation that you can pull up in terms of the different properties that you can set here and how they all work. This grid size is kind of like an overall variable that's used to calculate lots of sizing, padding, margin, all of that. You can also customize maybe the active color as well as turn off borders. Again, there's lots more that you can do with these. Take a look at the docs and you can pull up those. We can also use CSS variables. So in this instance, I'm gonna override those CSS variables. This is certainly my recommended approach in terms of customizing the grid is applying these CSS variables. And I think about this as we can also change it at runtime. And so I can apply background colors, foreground colors, border colors, all kinds of stuff using those CSS variables. There's also some additional SAS or STSS rules that you can use where they've got these functions that you can invoke and you can also include additional mix ins. Again, it's a little bit, once you get into really customizing the grid, you might want to reach for these. But in general, the CSS variables tend to work quite well in my experience. Notice also that we're using, we're targeting some of the built-in classes and you're more than welcome to target these classes. They're not gonna change. So I can say, hey, for the header row, I want this background color, for example, and then for even rows, I want this background color. So you can kind of target these classes, the easiest way to figure out what those classes are is just honestly to inspect the DOM and take a look at them and you can start targeting those classes. Again, remember in the beginning I said, don't change anything around positioning, pointer events and maybe overflow, I forget. But just be careful that you're not overriding some of those style properties cause you will cause errors and you'll get some funky behavior in the grid. Here, again, I guess I'm just kind of calling out the mixins and functions. And I think that kind of concludes how you can style the grid. The nice part about it is you can kinda, usually the way I approach, is I usually start with one of the themes and then customize them after that. You could probably try to write your own theme though. I don't know if, I've never tried it and I'm not sure how complicated that would be. There is no like theme generator or anything like that as far as I'm aware of. But I generally usually start with one of these and then customize them. Kind of depends if I'm already using Material and I might wanna use Material, but I might wanna make it a little more dense or I might wanna change coloring and look and borders and all of that kinda get it to look like my application. I will say in general that between a row styling and cell styling and theme customizations, you could certainly make a G grid look however you really want it to look and kind of meet that user requirement for your product. With that, I'm gonna stop there. I know we kinda blasted through a bunch of content at the end. Certainly if you have any questions, let us know. And I think we actually ended right on time. Go ahead, Mike. Yeah. I was gonna say, I think Bryan mentioned it in the beginning. We don't work for A G Grid. We work for LiveWellap, we're a consultancy to help you design, develop and deliver apps with joy. While we don't work for A G Grid, we certainly love A G Grid. So feel free to reach out to us if you need any help with your A G Grid implementation, putting code reviews, workshops, and consulting. Just wanted to thank you all for joining us this morning. Hope you all have a great day for the rest of the conference.

Watch more workshops on topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Top Content
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
Do you have a large product built by many teams? Are you struggling to release often? Did your frontend turn into a massive unmaintainable monolith? If, like me, you’ve answered yes to any of those questions, this talk is for you! I’ll show you exactly how you can build a micro frontend architecture with Remix to solve those challenges.
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
Top Content
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.