Learn how to put MUI’s complete ecosystem to use to build a beautiful and sophisticated project management dashboard in a fraction of the time that it would take to construct it from scratch. In particular, we’ll see how to integrate the MUI X Data Grid with Joy UI, our newest component library and sibling to the industry-standard Material UI.
Table of contents:
- Introducing our project and tools
- App setup and package installation
- Constructing the dashboard
- Prototyping, styling, and themes - Joy UI features
- Filtering, sorting, editing - Data Grid features
Today's Workshop focused on building a CRUD app using the MUI X data grid and Joy UI. Material UI is still popular and will continue to be developed, with efforts to implement Material Design version 3. The workshop covered various topics such as adding columns, filtering data, replacing slots with Joy UI components, creating an autocomplete column, customizing appearance and styling, saving and updating data, and handling errors. The workshop concluded with plans for future features and a call to connect with attendees for further assistance.
1. Introduction to MUI Workshop
Today we're going to be demonstrating how you can build a clean and sophisticated CRUD app using the MUI X data grid in conjunction with joy UI. By the end, you will walk away with a solid foundational template that you can use to expand on to your heart's content. If you do build something cool with the code from today's workshop, let us know and we could potentially share it on our project showcase at mui.com.
Let's get it started then without any further ado. Alright. Well, thank you all for being here. This is a MUI workshop. Today we're going to be demonstrating how you can build a clean and sophisticated CRUD app. That's create read update delete. A very sophisticated CRUD app that can handle massive amounts of data with features like filtering and sorting right out of the box. Using the MUI X data grid in conjunction with joy UI which is our latest React UI component library and a sister library to our flagship product material UI. Hopefully some of you here are familiar with.
Now if you were to build such an app from scratch it could take days or weeks of full time work. And that's before you account for the bugs and edge cases that trust me will definitely come up along the way. By contrast we will be up and running here in a matter of minutes something like 90 minutes give or take. And by the end you will walk away with a solid foundational template that you can use to expand on to your heart's content. If you do build something cool with the code from today's workshop or just from anything we learn today the workshop I hope you'll let us know. We'd love to see it and if it's cool we could potentially share it on our project showcase which is at mui.com.
2. Introduction to MUI Workshop
Today we're going to be demonstrating how you can build a clean and sophisticated CRUD app using the MUI X data grid in conjunction with joy UI. By the end, you will walk away with a solid foundational template that you can use to expand on to your heart's content. If you do build something cool with the code from today's workshop, let us know and we could potentially share it on our project showcase at mui.com.
Joining me here today is my colleague Jun who is an engineer on our core team and the primary developer behind the component library Joy UI that we're working with today. So I'm really glad he's here with us to answer any questions, and just to show us all the cool stuff he's been building. Jun has been with MUI for about two years now and is very passionate about all things related to developer experience, which I think really shines through in Joy UI. And I think you'll agree once you see it. So Jun will be the one leading the live coding with us here in just a few moments. And we're also joined today by Andrew who's our tech lead on the DataGrid team. So he's here in the workshop. He's also hanging out on Discord. He'll be around to answer any questions you might have about MUIX and the grid, especially if there are any super technical questions. I'm certainly no expert on the grid. But if anyone is, it's this fellow right here. So we're glad to have him with us.
Now you know a little bit about who we are. Let's talk about who we represent at this conference. So maybe I'm preaching to the choir for those of you who chose to show up for this workshop. Maybe you already know everything there is to know about us. But let's just make sure we're all on the same page. So MUI as a company began with Material UI, which is the open source implementation of Google's Material design in React. Despite popular misconceptions, MUI is in fact not affiliated with Google. No disrespect. We love the Google family. But we are an independent entity with a headcount of just over 30 these days. And MUI's product offerings now extend well beyond the realm of Material design. So you can see here we've got on our core team, our products include Base UI, which is for headless components and low level hooks. We've got Joy UI, which implements our own in-house design system and some fresh new ideas and developer experience. And then we've also got MaterialUI, as you well know, and Material, or sorry, MUI system, which is our in-house style system. And that's just on the core side. On the X side, that is MUIX, we've got our advanced components like the Data Grid, which we'll be working with today. We've also got the date and time pickers and, coming soon in the not-so-distant future, we'll have some cool new stuff as well. And then we've got MUI-Toolpad. We're still in very early stages of this app, but this is our low-code admin builder where essentially you can take all of the MUI components that you know and love and start building a full stack app just by dragging and dropping. So we're very excited about that. And if you have any questions about any of those products, please don't hesitate to reach out. I'd be happy to walk you through them all.
3. Introduction to MUI and Joy UI
We will be bundling our app with Vite which seems as quickly becoming the industry standard for building a react app that doesn't use next.js. If you haven't used it before, I highly recommend it, super cool again, would be a bit beyond the scope of this workshop to go too deep into it. But it just works and that's why we love it.
Now, our user interface, which is really the star of the show today, will be constructed using joy UI, as I mentioned, plugged into the MUI X data grid. So joy UI was created by MUI to serve as an alternative to Material UI for implementing design systems that don't adhere to Material Design. These features are very similar to Material UI so if you've worked with that library before, it should be pretty simple for you to pick up joy UI as well. But since joy UI features our own in-house design system, as mentioned, this gives us a lot more freedom and flexibility to experiment with new kinds of features that we wouldn't necessarily be able to introduce in Material UI. Things like global variants, which help you to quickly define the hierarchy of importance between a group of components, using a consistent set of styles that can be applied across all components in the library. And also what we call automatic adjustments, which is to say that joy UI components, thanks primarily to the magic of CSS variables, are essentially aware of their surroundings and can actually adapt their styles and structures relative to those of their children and parents. So, I'm really excited for you to see some of that.
4. Introduction to MUIX and Mock Service Worker
Today we're working with the MUIX data grid, which arose from the needs of the material UI community. We've decoupled MUIX's components from material UI to work with joy UI. Additionally, we're using mock service worker to fake a rest API for our app.
Next up, we've got MUIX. And specifically, as I've mentioned, we're working with the MUIX data grid today. Now, MUIX arose from the needs of the material UI community when it was observed that it just wasn't feasible for nights and weekends hobbyists to reliably maintain components with such advanced functionality. So, we built a team of engineers, I say we as though I had anything to do with it. I'm just here to tell the story. The MUI constructed a team of engineers to work on these components full time. And we've released licensed versions for power users who need the most advanced features and functionality. But there is a community version that is completely open source and free to use. So, that's what we're working with today. Most, most recently, thanks to June's work in collaboration with the MUIX team, we've begun the process of, you can say decoupling MUIX's components from material UI so they'll play nicely with joy UI. That in effect is why we're here today. Which is to show you how it's possible to build a data table using joy UI plugged into the MUIX data grid. And finally, last but not least, we're working with a package called mock service worker. And you don't need to worry too much about what's going on with this bad boy. Just know that we're using it to basically fake a rest API to interact with. So we can pretend like our app is actually talking to a server without going through all the trouble of setting that up for real. So, don't need to know much about this. We've got all the boiler plates set up in the repo. So that should also just work right out of the box.
5. Material UI and Joy UI
Material UI is not going anywhere. We know it. Everybody loves it. Super popular. It will continue to be around probably as long as React is around, I would say. That said, Material UI currently implements Material Design V2. And we actually just brought on a new engineer to work full-time on implementing Material U, which is Material Design version 3. So not only is Material UI here forever, but we're making efforts to bring it to the latest version of Material Design. And so yeah, Joy UI will always be an alternative. And we hope you will stay in our ecosystem, because that's what it's all about. We've learned a lot through Material UI. And so Joy UI was created to answer a lot of the feedback that's come up over the years about Material UI.
I see a question in the chat that I just want to acknowledge. Jory asks, will UI stay in alternate forever or is a plan to replace Material UI at one point? It's a great question. Material UI is not going anywhere. We know it. Everybody loves it. Super popular. It will continue to be around probably as long as React is around, I would say. That said, Material UI currently implements Material Design V2. And we actually just brought on a new engineer to work full-time on implementing Material U, which is Material Design version 3. So not only is Material UI here forever, but we're making efforts to bring it to the latest version of Material Design. And so yeah, Joy UI will always be an alternative. And we hope you will stay in our ecosystem, because that's what it's all about. We've learned a lot through Material UI. And so Joy UI was created to answer a lot of the feedback that's come up over the years about Material UI.
6. Building React App with Joy UI and MUIX
Today we're building a React app with Joy UI and the MUIX data grid, featuring full CRUD functionality. We'll use mock service worker and a fake arrest API. Users can add, delete, and edit rows and cells in the data grid. The Joy UI auto complete component provides suggestions for the manufactured country column. Let's dive into the coding with Jun.
So with that, let's get into this project. So our workshop today will be guiding you through the process of building a React app with Joy UI and the MUIX data grid, featuring full CRUD functionality, so the ability to create, read, update and delete. As I mentioned before, in lieu of a fully fledged backend, we'll be using mock service worker and a fake arrest API, that'll come into effect a bit later. And in this app, users will be able to add and delete rows on the data grid, they will be able to edit every cell in every row, and when a user edits a cell in the manufactured country column, they'll be given a list of suggestions to choose from, thanks to the Joy UI auto complete component. So I'm really stoked that we're able to include that. The auto complete is one of the cooler components I think we've got in the Joy UI collection at this time. So we'll get to see just how cool that is. And yeah, with that, I think we're ready to dive into the coding. So now I'm going to hand the reins over to Jun, who's going to get us started here.
7. Setting up the Repo and Exploring the Page
Let's make sure everyone has the repo set up and open the app.jsx file. Clone the repo, choose your package manager, install dependencies, and run the development server. The page displays a title and a simple data grid. We import joy UI components like container, CSS baseline, and typography. The data grid has important props like row and column, with rows and columns defined from a dataset. Column props define how the data grid handles the dataset.
Alright Sam, thanks for the great introduction. So first, let's make sure that everyone has this repo set up. So now I'm sharing my screen, so I could not find my chat. Okay, I found it. Okay. So we will be using this repo to build our dashboard with the Delibri Enjoy UI. Feel free to clone it, I'll give it a few minutes to wait for everybody. And once you clone this and open the project, you will see a wheat boilerplate with our main file here that we'll be using today, which is the app.jsx. And I will explain other setup along the way, but right now, we can just focus on the app.jsx. And so, once you open, you will notice a lot of linked error, which is fine right now. I prepared the import so that we don't have to, you know, go up and down in this workshop all the time so that we can focus on the UI mostly. All right. So once you clone the repo, then choose the package that you like. In my case, I used Yarn, and so I will run Yarn install, and now with my super-fast internet, and once you do this, then run Yarn dev. This will start the development server. And then you can click, command click or control click in the window to open this link. And this is the page that you will see initially. All right. You will see a title and then simple data grid right here. All right. Now, let's give it a minute for people to clone and try to install the dependency and run the dev server. In the meanwhile, if anyone has done it already, I will start explaining what we have in this page. So right now, in this page, we are importing joy UI components. So the first one is the container. It's pretty common in web development. So it creates a boundary for each view port so your content is not overflowing the limit of the width. And the next one, the CSS baseline, this one is our in-house CSS reset. You might have heard about normalize.css. It's the same thing, just to make sure that, you know, our component looks the same for all the browsers. And the next one is our typography component which is created for using with text. Well, I will explain the probs along the way. Right now it's using level H3 with will sync with the default same. So this is like the typography size. And we have the SxProp if you've used Material before it's the same. So these props allow us to write CSS inside this prop. So it is a very powerful prop. And then in this workshop, we'll do it together in a few components and our stars here. So the data grid. So most important props, which is row and column, I will move row above. So you can think of it as a spreadsheet that you have like a row of data and a set of columns. So the rows come from, we have the data set here. Click here, which I have prepared as a true row with ID, name, manufacture date and price. So each one of these will be defined as a column. And each item of these array will be a row. Right? And for the column props, this is a prop that we can define how we want to, how the data grid will deal with this data set. So right now we have the field id which will render the id from the data, from the data set that we have. And another one is the header name. Use to configure what appears on the header. Right? I assume that you all have installed the dependencies and you have this page on your screen. So let's get started.
8. Exploring DataGrid and Adding Columns
In the first hour, we will cover the basic features of the datagrid and create a custom component for selecting options. We will then add more columns to the table, starting with the name column. The DataGrid allows cells to be editable with just one line of code. We will add another column for price, ensuring the input type is number for better functionality. The input can be edited and saved, and it will work with filtering as well.
So in the first hour we will get some hands on the basic features of the datagrid, and try to create a custom component that will let users select some options or country from the autocomplete. And then we'll take a break and move forward to the next step.
All right, so now what I'm going to do next is to add more columns to our table here. And the first column that I will add it to is, I will pull the name column as a second column. So to do that, you type field and point to the field that you want. In this case, it's the key name here. So, you type name. And then you can add the header name. With the name you like, it can be named or it can be a product name. And then I'm going to save this file and the hot payload will do the job. And now you will see that this is the second column that we just added. Let me zoom in a little bit. All right. Let me know if you cannot see the code.
All right. And one powerful property that DataGrid provides out of the box is this one. So you can turn a cell of the column to be editable. So right now, you cannot do anything with this DataGrid. It just renders the stuff. But you can add editable as true. And this will make the cell able to be edited. So users can edit the cell of this column by double-click. So when you double-click, you will see a text input that users can type something else. And then they can save it with blur or with enter. Now the data will change and save to the Datagrid state. So this is pretty neat. Just a one line of code, and then you get a very hard to implement feature out of the box.
Alright, umm now let's add the next column. So same here. Just start with the field. And I will start with prise first. I will keep the other field as the last one. And then add the header name as prise. And then same here, I will add editable as true. So now, when you save it, you should have the third column. Which can be edited. But one thing that I notice is that since the prise is number, But right now I cannot use keyboard or arrow to increase or decrease the values. Because by default, if you don't provide any type to the column definition. So this is called the column definition. You will get a text, plain text input. And this is not what we want because the data type will affect how filter works and how sorting works as well. So we should provide a type if it's not a text. So in this case, I will provide as number. All right. And then I would save the file. And now, if you click on this, double click on this to enter index mode, you will see that the input change from plain text to input type number. And then this is better for accessibility because the users can now use their keyboard Now use their keyboard to interact with this input, or they can type the number that they want without mistype all the character. Right. And then press enter to save data here. Now, this will work with a filter as well.
9. Data Grid Filtering and Column Management
The data grid provides default filtering and sorting. However, when dealing with date columns, the data type needs to be converted from string to date. The width and format of the date can also be customized. Additionally, the data grid offers managed columns for filtering and searching based on column types.
So these come out of the box from the data grid, it gives you by default for filtering things like like a very complex filter, and you will get the sorting by default. So with the correct type, and this will sort in the correct order.
Now, the next one, the last column that we have from the data set here is the manufacture date. So I'm going to add to the last column here. As same as before, let's type manufacture date. And then let's type header name manufactured dates. Alright, and then I will add edit table true as well, and now because we know that this will be type of this is date right? So let's add type date. Oops. Alright, and then if I save the file then, boom, so this is not a feature, but it crashed. Alright, so what happened? It says that date column type only accepts date objects as values. So what's wrong? If we take a look at our data type, you will see that our data is a string. And this happens all the time because usually the data comes from the server, and the data cannot be typed from the server. It will most of the time be a string. And because we define type date to the Data Grid, but our data that we send to the Data Grid is a string so that's why Data Grid throws an error. What we have to do is we have to turn that data type from string to date and send to Data Grid. And Data Grid has a property called value getter to let us turn the type to the Data Grid So we can do that by adding a function here. And the values will be inside values. So param.value is a string from this one. So we have to turn this into a date object. So we can just wrap this with new dates. Okay, so this line is like, turn the incoming data into a date object so that it matches the type that we defined here. And let's save the file. Okay. And now it is back. All right.
So right now the date is quite narrow. So we can also define with as number. In this case, let's try 200. Okay. It's much better. And now you will come across this this use case where you want to turn this into a different format. So now it's using month, date, and year. So I want to change this into other format. So to do that, you can add value for matter. And it will be a function as well. And it will send you the values. And then you can add params.values. And these values you have to be aware of. So these values come from the result of value getter. These values is not the raw values because we have to find the value getter, so it will be the result, which is the date object. So because the value is a date object, then we can just add to date string. Because to date string is a method of a date object. So we can use it directly here. Now if I save, I should see a different format here. All right, so this is how you turn the data type, and this is how you can format what show on the screen. All right, cool.
So next, let's take a look at the default, what datagrid provides out of the box. So we have the, we have like managed columns that you can, if you have like a lot of columns, so right now we have only four, but if you have like 20 columns, 30 columns, this feature is pretty useful to filter the columns that the user don't want to see. And you can, they can search in high show all of this is you get this out of the box and filter based on the type of the column definition and filter, which is pretty complex here. So if you provide a type, then the values of the filter for that column will correspond to the type that you provide as well.
10. Replacing Data Grid Slots with Joy UI
The data grid allows you to replace slots with custom components from Joy UI. By importing the joy slots from MUI x-databricks-joy, you can replace slots like the icon, button, and text input. The pagination, look and feel, and various components will change to use Joy UI, providing a different visual experience. More components will be added in the future, making the data grid from Joy UI the ultimate solution.
Something like this, so we don't have this date and we can cancel it. All right, so another powerful features of the data grid is that it allows you to replace all of these slots that you see in the data grid like the icon, the button, the text input with the concept of slots. So it has a slots props, let me put it here, slots props, and you can replace of these with your custom component. And today, what we are going to replace, we will replace these slots, not all of it but almost of it with joy UI components. And, we have already imported it here, which is the joy slots from MUI x-databricks-joy. So it's experimental API right now, but we plan to make it stable in the future. So, let's try it out first. Cool. Maybe we can log what's inside joy slot, as well. Let's take a look first. Alright, so if I save here, you should see an object, which is for example the button. This is the react component, and checkbox is also a react component. So, these keys will match the slots that DataGrid allows you to replace. Alright, so let's put it in the DataGrid. I will put it here and then if you save the file, now you should see some difference. The pagination will change to use JoyUI component. The look and feel will be a bit different now with some border, shadow, and color. And the icon button changed. Some icon changed. Let me open this, right? If you remember the icon will change. And let's see, filter. Okay, now it changed to the text input from JoyUI. And what else? Let's take a look at manage column. Okay, the switch will be using JoyUI components. The text field as well and the button here. So we just replaced the default MaterialEye component with JoyUI. It's not all of it right now, but we will keep adding more. And in the end, you will not, you won't have to import the slots, but you will be using the data grid from Joy at the end. Okay, cool.
11. Creating Autocomplete Column
In this part, we will learn how to create a new column in the data grid that allows users to select options from an input using the autocomplete component. We will go through the steps of adding the column, setting up the autocomplete component, providing options, and improving the user experience by adding the autofocus prop.
So now we have learned the basics of column definition. The next one will be a bit more advanced. Let's do something, something fun. And you will come across this use case all the time when you want to create your own edit component.
So right now, what you get from data grid is a plain text input based on the type that you define. All right, but next we will going to build our own edit component. All right. And what we are going to build is a new column. And that lets user select some options from the input. And that is when autocomplete comes in.
So I will create a new column as always. So I will name it as manufacture country. And then let's add a header name, manufacture country. Country, OK. And let's add editable as true. And then now, when you want to create your own edit component and data grid lets us do it by using render edit cell. And render edit cell will be a function which is the same, will use the same params. Then you can render any react element that you like. Now lets do it with test. And I will save the file, and then we will have our new column here. Alright, I think lets remove the width here, maybe a hundred. I think maybe 64. Ok. And then lets add this width as 200. Alright, now if you double click on this to enter the edit mode, you will see your component here, which is a simple div with a test as a text. Right? Now we will change this to the autocomplete component, which I already imported at the top, somewhere here. Alright? Ok, so lets type autocomplete. And what you have to provide to the autocomplete is options as an array. So right now, lets provide it as empty array to see what it looks like and then lets close it. Now if I save the file, you should see an input here. And if you click on the input, you will see the no option. Because we haven't provided any option yet. Let's a bit more like placeholder. Because right now it's empty. Choose a country. Ok, alright, now you will have it. And now, replace the option with my mock data that I prepared. Let's take a look inside. Now the country, the json is just an array of items here with code and label. So nothing else but this. So let's get back to the code, and let's replace this empty array with country and then I will save the file and you should see some changes. Okay now we have options here, and what's nice about autocomplete is that we get accessibility out of the box. So right now, I'm using my keyboard. So I have indicator here that will detect my keyboard, so I'm using key here and if you press enter, it will select the option. But right now when you enter, it was saved to data grid, but nothing appears yet because we haven't sent that data that we selected to the data grid, which we would do next. Alright, so before we save that data, there's something that I would like to do first to improve the experience. Now if you see that when I double click on the cell, what I have to do next is I have to click again, and it's pretty annoying. So what we can improve here is to add a prop called auto focus so that, you know, once the autocomplete appear, it automatically focus on the input. When I save it, okay, let's close and double click again. Now it will focus on the autocomplete so that users can start typing right away.
12. Customizing Input Options and Appearance
Now, let's open the options on focus using the 'open on focus' prop. We can also remove the input border to match the cell's appearance. JoyUI allows customization through CSS variables and global variance. You can customize the component using SXprop and choose from four default variance and six colors.
All right. Now this one more thing that we can do here is to open the options on focus. And we can do that with this prop open on focus and save. Right. And if I double click, then the options will appear when input is focused. So these two prop is pretty neat for this use case, and it allows user to select the options directly. All right.
Cool. Now there's some styling that I want to show you how JoyUI gives you variables to customize. So because right now, if you double click, you will see that a border is quite repeat. So we have a border focus from the DataGridCell, and we also have the border of the input. So we will remove, we want to, I want to remove the border of the input so that it looks like a same input as the cell. So to do that, let's go to elements, and okay. To do that, let's debug the component to see what is the things that we have to override. Now, when you focus on this input, the the focus will gone. Right? And it's pretty hard to debug what's going on. One trick that you can do is to press command shift and then P. I guess on Window it will be control shift P. It will open the depth tool command. Then you can search for focus. And click on the emulate a focus page. When you click on this, it will focus on the page. And if you scroll down and interact with the depth tool, the focus will stay as it's in the page. Alright. So let's go back to our input here. Now, enjoy what's different from TUI as we experiment with CSS variable. So we shift CSS variable that we think it will be useful for developers to customize the component. And you will see that you will see that right now the focus comes from these variables, comes from the box static. If you remove that, then it is gone. But in this case, it's in the before selector. And if you have to write a CSS with this selector, it will be too long, right? It's easier if you customize or override the CSS variables. So in this case, the color is this one. So if I change the color, all right, it's this one, these variables. Oh, now it's gone. So let's click on this. Now you will see that you can copy this one and then you can customize these variables using SXprop. So SXprop allows you to write CSS on the component and you can write anything like with 100% or like margin, everything that is available in CSS and CSS variable is also a valid property. So what you can do is you can just paste a CSS variable and put the values that you like. In this case, we are going to remove it. So a transparent is the one that we are looking for. All right, and now if you save, the color is gone, right? And next one, you will still see the initial border, the gray one, this one, the gray one here, which appears initially because of the variance. So this is where you want to change the variance and in Joy UI, all components has the same variance. So has the same set of variance, sorry. We call this feature as global variance where you can pick one of the variance from four default variance in any component, and let's try it. So right now, it's by default, the input is in outline variance, so let's change to plain variance to see what it looks like. Cool, so it looks like this is what we want, but maybe let's try other variance. So soft will create a subtle background and what's about solid here? So solid will create a flashing background with a white text. And while you can also change the color because the variant always comes with colors, and we have six colors that you can choose from, and by default, this color is neutral, so you can change to something like primary and or maybe like, what else? Warning, for example. Okay, so in JoyUI, a variant and colors come together. And right now you will see that it not looks good at all because we have two component inside.
13. Saving Data and Enhancing the Autocomplete
In this part, we learned how to save the selected data back to the data grid using the onChange function. The values selected by the user are sent back to the data grid using the params.api.setedcell method. The data is saved to the data grid, but it is rendered as a string. To display the label of the selected option, we used the value formatter. We also explored the option appearance of Joy UI's autocomplete component and implemented it in our code. Finally, we ensured that when the data is saved and clicked on again, the focus is on the previous selection.
This is another component, which is the icon button, but I'll show you a pretty cool feature of JoyUI later. So right now I would just get back to use plain variants. Cool, so this is what I want. And... Okay, so this is done for styling our autocomplete.
Next I'm going to save the data that I select back to the data grid. So how to do that? Now what I have to do is I have to write the onChange function to listen to the option that user select. And inside it will be an event and the values that user select. Let's consol.log the values to see what it looks like. Now I save the file and then I switch to console and then I choose an option here. OK, so this is the values that we get from the on change handler. So it's it's the same object here that we have inside the countries.json. Alright, so what we want to do is we want to use this values that user select. And send it back to the data grid and we can do that by using params.api.setedcell. Alright, so this API is from the data grid. And data grid provide this method. So now if I open. There are three things that we have to specify, which is field, ID and values. So the field will be this field, which comes from the params. And ID will be the same, will be the cells ID. And. Values will be the one that user select, which is the this one. Now let me remove the console.log here. And then once I saved the file, and choose any values here, and then press enter to save. Now the data is saved to DataGrid, but you will see the object object is because we send object to the DataGrid, by default DataGrid will just render it as a string. So it comes from, because we send an object, and so DataGrid will always turn it into a string. So if you tried in your browser, you will get the same result. So object dot two string, you will get this, which is the same as you see here. So you can do the same as we have learned before, which is the value for matter, and then it will be a params, and then a params dot value, so right now, params dot values is the object, and then we'll have to. So I put the optional shading here because some cells can be undefined, and then I put a label because I want to show the label that user select it. Alright? So if I save the file and then I choose the option again and then enter. Now I should see the label on the cell. Once you save, or once you leave the edit mode. Alright?
Now, we are going to do something a bit more fancy here because our option is pretty boring. It just a plain text. So what we can do here is to copy some code and to steal something from Joy UI, documentation, now. Okay. So, let's go to mui.com and then let's open, let me increase this one. And then go to docs and go to JoyUI. And then, for Matt, press command k to search for the components or, on Windows, you can use control k. Alright, now you can type autocomplete and then press enter. It will go to the autocomplete documentation and we have a lot of demos here. And the one that we want is the option appearance. So now you see that this looks a lot better for the options and we will steal this. And so, in all of the demos, you can show the source code or you can open and try it out in the code sandbox as well. And now I will show the source code and then I will copy the render option here. So just copy the code and let's get back to our source code and I will replace it here because I already import all the components at the top of the file, so we don't have to worry about it. Now, if you save the file, then you should have a pretty nice option here, right? So you can remove something if you don't want, that is fine, so at least we have the flag, right? And looks a lot easier. Cool, what else? Ah, okay, so the last thing for the part one, so when you save the data, and then if you click on it again, actually, it should focus on the previous one, but now, there's no values, right? So that is because we haven't sent the values that user select to the autocomplete yet, so we can do that by passing params.values, or if there is no params.values, we would just pass a null. We can not pass and define, because that will, you will see some error from the autocomplete component, and that is because of the control and uncontrol input of React.
14. Customizing Format and Styling with SX Prop
Now, if you save the file and choose an option, it should select the previous one when editing again. You can customize the format using render cell and value formatter. By using the SX prop with the Box component, you can style the div and add CSS properties. The SX prop allows for complex selectors and powerful styling options.
All right, now if you save the file, and then if you choose one, let's say this one, and then enter, and if you try to edit again, now it should select the previous one, which is this one, and then you can use keyboard.
Okay, cool, and I promise this is a last step for the first part, which is we can customize we can customize the format with our own custom component as well, so to do that we can change the value formatter to fully control how it will appear using render cell. All right, so render cell and value formatter is pretty much the same, but render cell let's you control the UI that you want and right now yes I will show the label, but I will put it in a div and I will also use the image that we have here and put it in front of the label. Now you will have to change the option here because we don't have any option in here and the option will be params.value. All right, now if you save then it will crash. Why? Because it cannot read property of undefined which I guess in this one. Oh, okay. So this is because params.values can be undefined so what we can do here is to render a condition here. We will render this UI only when params.values exist. All right, otherwise we will just render null. Because, nope, okay, cool. And if we choose, then enter, okay, now we have the flag. Okay, so I think, I want to point out one last thing here which is the styling in JoyUI in MUI, Mui ecosystem that, so now if, let's say, I want to style this div, how do you do it? So, well, a conventional way is to use the class name, right? And then create a CSS file or maybe a SASS file, or if you want to use Tailwind, that is also fine as well. But in MUI ecosystem, usually, we will use a handy component with the SX prop, and that component is called a Box. And Box is just a plain div with one more feature which is the SX prop. Now, with SX prop, you can write CSS, like display flags, and then a line item sender and add gap here. So if you don't understand what this is, so this is just CSS that you can find out later. This is to create a flex box and add some gap between the element here. And now if I save the file, and then I choose it again, okay, now you should see a gap here. More powerful here is that with SxProp, you can write a complex selector as well. Now I can do this in SxProp. So I can style the image below this box by using AND and then IMG to create a nested CSS as well. So it's pretty powerful here. And I can say that, okay, let's add border radius as 10 pixels slash eight pixel and then save. Now let's see what it looks like. Okay, now it's like an oval. Looks and feel, okay, cool.
15. Creating New Rows and Saving Data
In the first part, we learned about the data grid and column definitions. We explored Joy slots and how to add Joy UI components to the grid. We also saw how to create custom edit cells and build an auto-complete component. Additionally, we learned about customizing JUI components using the SX prop and global variants. Regarding the choice between box and stack, it depends on personal preference and the desired layout. The stack component now supports the flex gap prop, which is recommended for better customization. In the next part, we will focus on creating, reading, updating, and deleting data. We will start by allowing users to add a new row and save the information entered. This will involve using the toolbar slot and adding a button component. We will also explore the use of global variants and the box component for styling.
And this is it for the first part. Let's summarize what we have learned. Sam, shall we summarize and maybe take a break like five minutes? Yeah, yeah, great call. So let's see, what do we learn about and what we've done up to this point? We brought a new data grid into our app. We defined some rows and columns. We saw how to bring Joy slots into the data grid to add Joy UI components internally in the grid. We set up some columns there and saw the column definitions, how to make things editable, change the size. We saw how to create custom edit cells and including how to build a very nice auto-complete component, as well as stealing some code directly from the MUI documentation. We also saw how to take the values from that auto-complete and put them into a custom-rendered cell on the other side. And we got just a little taste of how to start to customize some JUI components using the SX prop and also the global variants.
Yeah, and so with that, let's take a quick break here. I think we're at a good stopping point. All right. Pretty interesting question in the chat. What should we consider when choosing between box and stack? Well, I think this is like... Your preference from experience. Like I use them interchangeably all the time. So it depends on like the layout that you want to build. If I see that, for example, like a button that stay vertically with some spacing between, I always end up with stack, but for other use cases, I always start with box because I can control all the CSS that I want with box. But you always change them anyways, at any time. Yeah, I was trying to think, are there any features like props that are unique to one but not the other? So right now, the stack is using, by default, is using margin approach because before, GAP is not fully support but right now, it's available in most more than browser and we also have a new prop, which is, let me share my screen before we start the next step. All right, now in... Let's open the stack. All right, now I'm going to open the depth tool here and you will see that now the stack is using margin and this, it works okay but when you want to customize something, it creates a lot of issues because, for example, if I want to customize like the margin of this item then it cannot do it because it's very hard to override this CSS selectors here but we have a new prop which you can change the implementation from using margin to using a gap which is a lot better. So you can check out a doc, it's just one prop that you can add on the stack and it will turn the component to use gap instead of margin. And I recommend this because if you take a look at, can I use and then flex gap. Okay, so gap of flex box is almost 93% which pretty close to the gap of CSS grid, which is 95%. So if you care much about that 2%, I really recommend to start with gap instead of the margin. Cool, yeah, thanks a lot for sharing that. I didn't even know about that. Use flex gap prop, just goes to show how massive our product library is. That's super cool. All right, seeing if you're ready for the next part, let's do it. So to recap what we learned from the last session, we have a custom edit component and we learned the basics of the column definition. The next part will be much more interesting. So we will start, the create, read, update, and delete. And the first step is to, let's the users click on some buttons and then it will open the new row and then user can type in the information and press enter to save that new row. Oops. All right, to do that, a data grid let's us insert a slot, the toolbar slot, so we can't create our own component, now we can call it a toolbar and then let's return a div and let's add a button here. So a button is from Joy UI, we already imported at the top and now let's call it add record. All right and then let's put a toolbar inside the slots, so I will spread Joy slots here and add the toolbar slot with my own component. And if I save the file, I should see my button here. All right, okay. And what I mentioned in the previous part is about the global variance. So this is one thing that from my experience that a use joy UI to build examples and all the things I really like the global variance which lets me create a lot of different examples. So now in button, you can also use the same variant as the auto-complete and you will expect the same result. And now for example, I will go with soft. Or this one, and then I can change the color to neutral. All right. Now let's use the box to create a little spacing around the button here.
16. Interacting with the Data Grid
We can interact with the data grid using a powerful React hook called API ref, which provides methods to interact with the data grid. By using the updateRows function, we can create a new row by providing an array of rows to update. When adding a new row, we can generate a temporary ID and pass it along with other initial values. Additionally, we can change the Edit mode of the data grid to Row, allowing the entire row to be edited at once. When adding a record, the row will automatically enter Edit mode, and the user can start typing or changing the data immediately. The changes will be saved when the user presses Enter. However, there is still one problem.
So let's add some padding. Okay we can start with this. And then to, if you want to interact with the data grid, you can use this React hook from the data grid. So it's a very powerful API, so it will return all of the methods that you can interact with the data grid. So we can call it API ref and then call the useCrit API context. So now I will show you what's inside the API ref. Okay, so now I save the file and then we should see an object here. So the method is inside the current object. And you will see that there's a lot of method that you can do or interact, change data or get something from the data grid here. Okay, so I'm not going to explain all of the functions here. So I will use the one that we want. Now in this case, we want to create new row, right, when I click on this button. So that function is, so we can use aprf.parent, and then update rows. Update rows. So the function updateRows let us provide like an array of rows that we want to update. And if the new row has like a new ID, it will add to the table. So what we have to do is we have to create a new ID. So let's say, right now it can be any ID, I will put a temporary ID at this point. And so we will pass in this ID to this object. And then it's the same as what we have in our datasets. So we can pass a name as an initial values here for the users, and then manufacture date, can be no, or can be like a new date. All right, and then what else, price, let's say zero first. Okay, now if I save this file, and then if I click Add record, you should see a new row here. Okay, cool. Now what I want next is that when you add record, it should turn into Edit mode so that user can start typing or changing the data right away, so they don't have to like double-click all the time. And, oh, there's one thing that I forgot to change here. So in DataGrid, there are two types of Edit mode. So right now what you're seeing is you can't edit like cell by cell, right? But it's pretty annoying if for like a crude app like this, what we can change is to change the Edit mode to a different way so we can change it to Row. And then if you save this, and then if you start editing any cell here the whole Row will change into Edit mode. And then you can use keyboard to navigate and change the data right away. So it's pretty convenient and I think it's a very powerful features as well. All right, so now the whole Row will be in Edit mode and when you finish, or when user finish edit of the cell and then they press Enter, it will save the whole thing. Right, cool. Let's get back to what we have here. Okay, so now we can add record but, sorry, let me refresh this one. Um, so what we want is that when we add record, it should focus or turn this row into an edit mode. So we can add a next step when we create new row. We can add this method. Okay, I don't remember, rowEdit. RowEdit. Okay, so we can use StartRowEditMode here as a next step. And this function needs ID. So the ID will be the new one that we just created. And then we can provide a field to focus. And we can specify, like, the field that we want to focus when this row turn into an edit mode. So I can focus on name. Now you can play around with other fields to see what it looks like. And now if I save the file, and then I click Add Record, okay, it will focus on the name, column, and then user can start changing the data. Let's choose this one. Let's change to 100 and let's press Enter and then it will save to DataGridState, cool, right? Cool, right? So now we learn how to create new row, but there's one problem.
17. Updating and Deleting Rows in DataGrid
To ensure that each new row has a unique ID, we can use the processRowUpdate prop of the DataGrid component. By generating a unique ID with the UUID library, we can create a new object that spreads the updated row with the new ID. We can then save this data to our own state and update the rows array with the new row. This will cause the DataGrid to re-render with the latest rows. When updating existing rows, we can differentiate between new and existing rows by checking the ID. By using a temporary ID for new rows and comparing it with the new row's ID, we can determine whether to update an existing row or add a new row. By mapping through the rows and replacing the row with the same ID as the updated row, we can update the specific row. Finally, we can move on to the delete operation, typically implemented using the last column of the DataGrid.
If you try to create more record here, it will focus on the same row. And that is because every time you click on this button, the ID is the same, right? So what we can do here is to, when user finish this new row, you can create a new ID for that row. And this make sense because most of time, the new ID is generated on the backend, right? So let's do this. Now, DataGrid has one prop that lets you handle the event when user stop edit or finish editing. And that prop is called processRowUpdate. And the processRowUpdate will return a new row for you. So new row is the data that user just finished updating. Right, so let's console.log new row first. Right, so if I press here and then if I click anything and then if I press enter, so it goes into this processRowUpdate. But we got one error because the processRowUpdate, you have to return something. And usually you have to return a row back. Otherwise, this processUpdate will troll an error. All right, so now you want to create a new ID when users stop editing. So I can create an ID. And we have installed a library called UUID here, which will generate a unique ID for us. So UUID here, and then, so this will be a unique ID. And now we'll create a new object, object which we will spread the row that users just updated with our new ID, all right. And once we do that, then, so at this point we would have to save this data to somewhere. And we can do that by creating our own state. So here we will create our own state, use state and we can set as default as data as a default, and then at this point we are changing, we take control of the states and then we will send the state to the data grid. All right, so now when we have the updated row, what we want to do is we want to set rows like we adding a new data to these array. So we set rows and we'll get a previous row and then we will spread the previous row and push the new one to the state. All right, so now if I save the file and then if I press add record and I choose data, changing the data paste and then price 100 and then once I okay with this when I push enter it will create a new well create a new, so here the ID is generated in this line right and that it's saved to this date. So when the React re-render, and our rows contain the new row and then sent to the data grid and then data grid will re-render with the latest rows. All right, so right now we have the create actions. So next we are going to do the update operation and let's try to update some of the existing row. So when we try to update here and when we press enter, what happens is it creates a new row. Why is that? It is because every time that you, every time the user stops editing or finished editing, it will goes into this function, which is a process row update. And we, right now, we don't know if it's like a new row or existing row, we will always create new unique ID and push it to as a new row, and that's why we always have a new row here, even though we update the existing row, yeah. All right? So what we have to fix here is that we have to split the condition here. And by saying that, okay, this part is for existing row so that we can just update a specific row. But this part we will use the add new row, all right? And right now we can check it from the ID. So we can say that existing row equal to new row dot ID should not equal to temporary ID. So temporary ID is from the one that we use here, temporary ID. So when we click Add Record, we will create a temporary ID here. And that means if the new row dot ID is not temporary ID, it means that this row is an existing row. All right? And once we know this, then we can add a condition here that if it is an existing row, then we will set row in a different logic. So we will get previous row, and then we will update the row that has the same ID. And so we can do first row dot map, and then we get the row, right? And then if row.id equal to new row.id, then we will replace it with the new row. For other rows, we will keep it the same, like this. And then at the end, we will just return the new row out so that it does not go to these condition. Now, if I save the file and then let's refresh the page, and if I update the existing row, I will use this and maybe this, and then enter. Cool, so it should update to existing row. If I add a record here and choose some country and change to 100, so 100 and then enter, it should create a new row. Or if I try to update this row, and enter, it should save to the existing row. Cool. So we have Create and Update. Now let's take a look at the final operation, which is the delete one. All right. So for the deleting one, usually you might see the last column as being used for doing extra actions like delete.
18. Adding Actions to Data Grid
To add actions to the data grid, we can use the actions field and the actions cell item component. By providing a key, icon, and label, we can create an icon button in the last column. However, the onclick functionality has not been added yet.
So we can do this as well by adding a field actions and a spatial type, which is actions as well. Now, when you use type actions, you have to provide a set of actions that you want to do. So you can do that by use a props called get actions and params. And then you have to provide an array of actions that you want to create. And we can use a component from grid, actions cell item. So once you do this, you will have to provide a key because it's inside array to make the link happy. So put a key delete, and then let's add some icon, delete icon, and then add a label as well. Now, if you save this, then you should see the last column appears as this, as icon button, and right now it does not ring because we have an added the on click. Cool.
19. Adding Delete Action and Learning Joy UI Features
Now let's add the delete action by using on click and to delete it straightforward. We just need to set rows and then removes the role that we just clicked. The Data Grid has a prop called auto-height, which will adjust the height based on the content. So when auto-height is turned on, the Data Grid will adapt to the height that changed. What we learned so far is CRUD in that's changed, the state that we create, and what we do here is the processRoleUpdate which is our main function here that handles the create, create this part, and update the existing role. For DELETE, it's straightforward. Now let's learn some feature of Joy UI. So let's import cheat from MUI Joy Sheet. Sheet is like a handy component, same as Box, but it will contains a variant prop and color prop that you can choose from. Let's turn this toolbar into a flashy background using a variant called solid variant and the color will be a neutral. When you use variant in Joy UI in many layers of the group of components, you can define the importance of the component using global variance.
All right. Now there's some details which I think it should work. So you can put, like you can group some actions into the menu as well. And I think this is pretty cool things that I've seen in common use case. Now, if you put like show in menu, it will group into a vertical dot dot here. So when you click and then you will get a action in a menu instead, but I'm not going to use this now. So let's add the delete action by using on click and to delete it straightforward. We just need to set rows and then removes, removes the role that we just clicked. So now we'll use the same function here and then this time we will filter out the row that does not have the same ID, rms.id. Okay, hope this work, right? If you save the file, so now you filter out the row that has the same ID as the row that you click. So I already saved the file and if you click delete, it should delete this row. Cool. Alright. Oh. Now if you delete all of the rows, it will look strange like this. And I just found out that Data Grid has a prop called auto-height, which will adjust the height based on the content, which is pretty cool. So when auto-height is turned on, then it will look like this. And if I add one more record, you'll see that the Data Grid will adapt to the height that changed. All right. Cool. All right. So I think this is it for the, so what we learned so far is CRUD in that's changed, the state that we create, and what we do here is the processRoleUpdate which is our main function here that handles the create, create this part, and update the existing role. For DELETE, it's straightforward. For DELETE, we create a new actions column that will set, that will filter out the role that we just clicked. All right. Now let's, before we moving to the next step, let's turn this into a more maybe let's learn some feature of Joy UI that I really like to show you. So, let's import some components from Joy UI and use it inside the toolbar. So I will replace this with cheat component. Now I haven't import it. So let's do it together. Okay. So let's import cheat from MUI Joy Sheet. All right. And so, Sheet is like a handy component, same as Box, but it will contains a variant prop and color prop that you can choose from. So now I will turn this toolbar into a flashy background. So to do that, we'll use a variant called solid variant. Okay. And the color will be a neutral. Oops! Oops! Cool. So now you will get a flashy background here. Or maybe let's change to primary palettes. All right. And now for buttons you will see that maybe you can change to solid variant as well. And maybe you remove the color. Okay, so oops. Okay, so what I want to show you here is that when you use variant in joy UI in many layers of the group of components, I can show you one more buttons to make it clear. Okay, so button maybe variant let's call least important and then let's call this use variant plain here. And then maybe let's get back to this, do this first. Okay, let me explain a little bit about the global variance. So the global variance should help you define like a importance see of the component.
20. Customizing Colors and Variants in Joy UI
When using variance in Joy UI, the background and color of the component can be adjusted to attract users and emphasize importance. The inverted colors prop ensures consistent hierarchy by adapting the colors based on the variant. This feature is commonly used in modern design.
So in this case, you will see that when you put a variance solid on the screen, that action should be the most important part of your app because the background and color, it attracts users, right? Now this one is not that important. But this one is more important. However, when you use variance in many layers, it will create inconsistent of the information. Now if I change the variance to solid and then a color to primary. Now this cannot be seen, like it does not have enough contrast. And if I change to soft, then now this one become more important because it looks more obvious, like eye catching than the solid one. And with this, we have another props that we can make all the component inside this one to adapt the colors based on its variance. And this prop is called inverted colors. So when you turn on this, all the shielding inside of this container will adapt the colors based on the variant so that the important hierarchy stays the same. So right now you will see that the add record is more cashy than the other buttons which still stay the same as what you used here. So this is one cool feature of Joy UI, and these kind of UI appears a lot in modern design. So you can learn more on our docs, but right now we are going to go with this one. Maybe let's make it soft. All right. Cool.
21. Connecting to Database with MockServiceWorker
We are using MockServiceWorker to fake the backend and set up the database with a schema. The code creates data in the database and sets up four handlers for the REST API: get products, create, update, and delete.
Now we will move to the last part, which is to connect to our database, and then we will finish our talk. All right. Okay. So as Sam mentioned at the beginning, we are using MockServiceWorker to fake the backend and I can share with you a bit of the setup so that you are not confused about what's coming. All right? Now, all the setup is in browser.js. We have a database created with this schema and then when the code runs, it will create some data in the database, which is the same as what we had in the app.jsx. jsx and at the end, it creates four handlers which are the REST API. So the first one is to allow us to get the products and the second one is to create. The third one is to update the products based on this ID and the last one is to delete the product.
22. Connecting to Backend with MOX Service Worker
MOX Service Worker allows you to interact with your browser without calling the real API. You can control the delay of the API and see changes in real-time. The mock service worker acts as a fake backend, allowing you to test adding and fetching data. To connect to the UI, use effects to fetch data from the backend and create a loading state. Set the loading state to true initially, fetch the API, get the response, and set it as the rows state. Finally, set the loading state back to false. Use the LoadingProp in the Data Grid component to show a spinner when loading. To handle the create operation, update the function and send the data to the server.
Now, what I like about MOX Service Worker is that you can interact with your browser without calling the real API and you can also control like the delay of the API so that you see some changes in case that you have like a complex interaction or loading stops. So right now it's set to 300ms. Now you can try the API right in your browser by copy this line of the code. So it's a plain NativeFetch API. Now if I paste this and then... You should see this one enable as well when you refresh the page. Means that the mock service worker is working. And then if I press enter, you will see that mock service worker respond with the okay status. And then we get the response back. So this is like a fake back end. Right? You can try to add more data as well. So if I press enter, then now you see that the new product is created. Right? And then if you try to fetch it again, you should see three items. Okay. So the last one is a new one. Cool. Now we test that the API works. Now let's connect to our UI. Okay so the first step I will remove the data here and change to empty because at the beginning we don't have any data yet. So we don't need this anymore. And we will get the data from the backend instead. So to do that, we can use effects here to fetch the data from the backend. And we can create a loading state. Is loading and then set is loading. Now state. And by default, it will be true. Okay. So this is just to show you that it's a super, super basic in data fetching or in the future you can improve this by using other libraries as well. So, at the start, we will just set is loading to true. And then we will fetch the API and slash products, right. And then we will get the respond back and then call it respond.json. So, this is how Fetch API works. I just follow the template here and then we will get the result. And finally, we can set that result to our rows state here. Set rows and then result. And now we will set that is loading back to both. Okay, now we can use the LoadingState and pass to the Data Grids as well. Data Grid has LoadingProp, which will show the spinner if it's loading is true. So now let's save this and then let's refresh again to let you see what it looks like. Now, if I refresh the page then you see a spinner for 700 milliseconds. And then now the data comes back from the server and then we set it to our states. Pretty cool. Now, okay so this is it for fetching the data. So next let's just handle the create operation. So we will do, we will update this function. Now what I like about this process rule update is that you can turn this function into a promise or async as well and then you can call API directly inside this function and wait for it. And data grid will also wait for the results. Now, okay, this is the update part, so I will deal with the create part first. So when you have the updated row, what we want is to call the API. Oh, sorry, send the data to the server.
23. Handling Errors in Data Grid
In this section, we learned how to handle errors when creating new rows in the data grid. We simulated an error by setting the manufacture date to null and showed how to handle the error using the fetch API. If the response is not okay, we can throw an error inside the process row update function. This ensures that the user stays in edit mode and can update the data again. We also added an error handling function to the data grid and displayed the error message to the user. This allows for a better user experience when dealing with errors.
Right, and before that, let's set this loading to true. And then let's await. Okay, now I need to copy the code. All right, so I will copy from line 47 to 51. 58, and then paste it here. And then, so this is the raw data. I will replace it with my data here, which is the updated row. All right, so you can learn more about fetch API later, but this is how you call the fetch. If you want to send the post method to your backend. All right, and then, when this is done, now let's set is loading to false. Okay, now let's save this, and then let's try to create new row. All right, if I press Enter, okay, now it's create data to the backend. Now, to verify that it works, I will fetch the data from the backend and using fetch in the browser here. Okay, cool, so here, this is the new data here that we just created. So it works. All right, so next, let's, okay, sorry, before we move to the edit part, I want to show you how we can handle the error as well, because this happen all the time. So for example, if the user missed some field and then they press Enter, and that data sent to the server, and then the server reject with the error, and so how do we handle that error? So for this case, I will fake the data here. Let's say that I forced the manufacture date to null. Okay, so I do this because I want the server to throw errors, because right now, you have to provide all the fields to the backend. So to simulate the error, you can put a null inside manufacturer dates. All right, so if I save here, and then I try to create a new row, right, and then I press Enter. Now. Now this is a, the server will troll the error here, right? But we don't see anything on the frontend because we haven't handled the error yet. And to handle the error with fetch API, we need to get the response. IfResponse, and then we have to check if, ifResponse is okay or not. All right. So, let's just do the, the error part. IfResponse is not okay, meaning that if it's not 200, say 200 x, x datas, then it means that something is wrong. And what we can do here is to troll that error inside this process row update. Okay, and then I'll show you later why we need to troll it. Okay, so let's troll, let's troll, maybe I have to do this first. I will get the error from the response. So respond.data. And then I will troll that error from this function. Now let's see what it looks like when I add new record to, alright, then I press Enter. Alright, so what I like about this is that if something is error inside this function, the user will not leave the Edit Mode. Which makes sense because whatever happens, if user leaves the Edit Mode, it means that the data that they just updated will lost. So this is a good experience. If something wrong, then it should show some warning and then let them update the data and then save it again, right? So, now we can do the same thing here. Next step is how you can handle that error because right now the data grid show an error that a call to process role update was not handled because this function is missing. So, we can use this and add it to the data grid and then it will give us the error and we can do anything with it. And in this case, I'm going to just alert the error. So, the error here is this one and usually the error contain a message property. So if I save the file and then I add a new record and then I submit. Okay, so now what happened here is that when this one sends back as not okay, we throw errors out of the processor update and then DataGrid lets us handle that error in this prop on process will update error and then we show the alert of that message to the user. So if I click okay here, the user will stay in edit mode and then let user change the data to something else. and because I had coded, it will always error every time. Cool okay, I will remove this one and set it back. Alright, so this is how you handle error with the process role update and on process row update, pretty useful. Okay, so next, it's pretty much the same.
24. Handling Editing and Updating
To handle the editing part, set the loading state, use the Update API with the new row ID and data, and set the loading state back to false. The update will be reflected on the server.
We will just need to handle the editing part. So same as before, we will set that is loading and then we will copy this part. Yeah, it's better to just copy from here, alright? So this is the Update API, so I will use it here and await. And then this is the ID, so I have to provide the new row.id. And then the data will be the new row and I will set this loading back to false. All right, and then save. I'll let you handle the error next year. Handle the error. I mean, like this part or to do handle the error. Cool. So I will try to edit this one. And then if I press enter, okay, so now it will, it will update on the server as well. Cool.
25. Finalizing Delete Functionality and Wrapping Up
In the final part, we address the delete functionality. We make adjustments to the autocomplete component to ensure the correct row is selected. We also encounter an issue with the backend sending empty objects and address it in the frontend. To delete data, we change the onClick function to async and use the delete API. We then fetch the data again to update the view. Finally, we wrap up the workshop and answer any remaining questions.
Now, this is the final part, which is the delete part. I think let's give you the five minutes to do the delete part for yourself. And after that we will get back and go through the delete part together. All right. Let's do the final step. I just found something, and so if I try to update a row, so for example, if I double click on the product name here, I will get a warning from auto complete component that you can use it ease option equal to value to ensure that which row is selected. So like which option is selected. So we can just add it to autocomplete component. So this prop will let you, will give you options and values. So it's like we tell the autocomplete how to compare the equality of the options and the values. So in this case, we would just use the code as a similar to ID. Right. And now that one should be, Oh, not all the options match with. Okay. So I think it's because of the back-end send us with this. Send us as code and label as empty. Okay. And that is why it chose this one. So we can't fix another things, which is if Params.values.code, Params.values.code, we will use Params.values, otherwise it can be No. Maybe this should be No. All right. So I think this is about the backend, the backend should not send us that empty object. Okay, that's why frontend, we have to deal with a lot of stuff. All right, now let's back to the deleting part on the final step. So to delete this data on the backend, we can change this, on click to async, and then same as other operators. We'll just set is loading to true and then await the delete. Now I would just be the code again. All right, we can copy the Delete API and then put it here and then use the param.id. All right, and then, so once we delete, so we can remove this as well to get the fresh data, or we can keep this? Let's do another way. So this depends on what you like to do, so there's no right or wrong here. Now I will fetch the data again and then set it back. So I will copy this and then put it here. All right, so let's just save the file and then if I delete one and if we're loading and then, so okay, so delete success and then the data should be just one left. Okay, cool. So yes, that's it Sam. I think this is all done for the workshop. All done for the workshop. Awesome, beautiful. Thank you so much for showing us all of that, June. That was very informative, if I do say so myself. Thank you, it's happy to be here. Yeah, we got to see a lot of cool features of the DataGrid and of JoyUI. And how they play nicely together, excuse me, and, yeah, we also got to see how you can actually start to work with the real backend, thanks to the mock service worker there. So we've got some time here at the end before we wrap things up for good. If folks have any questions about anything we've covered today, whether it's JoyUI, DataGrid, anything about MUI. Yeah, if you just want to chat about the weather, it's all good, we're here. Yeah, so happy to answer any questions. I see PeterD is asking, is there also an auto-fit option on the column text? No? Hmm, I guess you meant like something to let the column grows to fit the text. I guess that's the, okay, cool. So right now, this is a community version, so what we use here is from XDatagrid.
Column Width and Joy UI Compatibility
In the pro and premium version of the data grid, users can drag and change the column width themselves. We plan to work on a feature that allows autosizing the column width, and there is already resizing available. Joy UI is in the process of extracting Material UI from the data grid, so in the future, the data grid will contain 100% Joy UI without any Material UI components. We're excited about achieving 100% compatibility without having to explicitly define the slots. If you have any other questions or need assistance, feel free to ask. Thank you for attending the workshop and checking out Joy UI's templates.
And that feature is, I'm not really sure if that's a feature that lets you, that will auto-fit, but in pro and premium version of the data grid, it will allow users to drag and change the column by themselves. I can tell you here, let's, I'm not sure if I install. Okay, maybe let's, I can show you by adding MUIXdatagridpro. Let's wait a few seconds. Okay, and then, let's change to pro in this one as well. And then rename it as data grid. So once I saved this, and then I run the server again, okay, whoops. Use grid route props, okay. Okay, we don't have the, so route, let me see. Where is this error comes from, grid columns here, there, okay. Let me try to, I'm not sure what's going on here, but let me try to remove the slots, okay. Right now, I just removed a slot, maybe something is wrong with the slot, but just to let you see that if you use pro or premium version, like the features that let user change the width of the column is there of the box. You can install the pro and premium and test with all the features. The only thing that you will see is the watermark here, so yeah, I hope that answers your question. Maybe Andrew can share if there's some feature that, you know, just fits it. Yeah, can you hear me? Yes. All right, cool. Yeah, we actually plan to work on the feature that allows to autosize the column width, especially on a double tap on the double click on the resize handler. Yeah, so we plan to deliver that, but as June mentioned, there's already resizing available. So yeah, hopefully this answers the question. Cool, nice. Can't wait for that feature. Cool. Thanks for sharing that. We get another question here from Jory, who asks, does Joy UI offer slots for all MUI components? So I guess you meant for data grid to be specific. So right now we are in the process of extracting Material UI in the data grid, so that in the future this is the ideal way in the future. If you want to use Joy UI in data grid. So we plan to, you don't have to import the slots, but what you will do is you will import the data grid, from x data grid and maybe slash joy. And this data grid will contain a hundred percent of Joy UI without any Material UI component. So this is the plan, but right now we are in the process of doing that. That's why you have to, right now you have to import this slot and replace the Material components for now. Cool, yeah, we're getting the early alpha, a little peak behind the scenes as to what we're currently working on. But yeah, I'm very excited to see a 100% compatibility without having to explicitly define the slots there. But very cool. All right, do we have any other questions? Is there anything else we can help you all out with while we're here? It's okay if the answer is no. Yeah, thanks everyone for attending. Yeah, thanks a lot for sticking around with us. Cool. And if you like, you can check out like... So JoyUI, we have like a lot of templates that you can start with. So feel free to check it out. I'll drop the link in the chat. Where's my chat? Right. So this is one example, like the marketing page. So you can copy the code and put it in your project to start your new project. Or a dashboard. So it works with dock mode and light mode as well. So, cool. Alright. Well, I think that's about it for us today.
Conclusion and Contact Information
Thanks everyone for attending. If you have any questions or need assistance, feel free to reach out to us via email or Twitter. We appreciate your support and hope to connect with you again in the future.
Thanks again, again, again, everybody for being here. Thank you, Jun, for leading us through that presentation. And once again, for everybody, if anybody's attending the conference in person, I hope you'll come find us at our, we'll have a nice big shiny booth. I'll be working there along with a few other folks. And yeah, hope to see you. Hope to have some good conversations with folks. And yeah, cool. Yeah, thank you all so much.
I'm glad you found this helpful and enjoyable. But yeah, I guess we'll wrap up here. If you need anything, please don't hesitate to reach out to me or anybody here. My email is sammui.com. You can also find all of us on Twitter. We've got Twitter slash MUI underscore HQ, which is where you can find updates about all of our products. Yeah, Twitter is a little crazy these days, but we're doing what we can to stay active there.
And yeah, I think that's going to do it for us. So thanks again. And we will talk to you again soon. Yeah, see you.
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
Design systems aim to bring consistency to a brand's design and make the UI development productive. Component libraries with well-thought API can make this a breeze. But, sometimes an API choice can accidentally overstep and slow the team down! There's a balance there... somewhere. Let's explore some of the problems and possible creative solutions.
There are many ways of authoring components in React, and doing it right might not be that easy, especially when components get more complex. In this talk, you will learn how to build future-proof React components. We will cover two different approaches to building components - Composition and Configuration, to build the same component using both approaches and explore their advantages and disadvantages.
Building products for multiple platforms such as web and mobile often requires separate code-based despite most of the components being identical in look and feel. Is there a way where we could use shared React component library on different platforms and save time? In this presentation I'll demonstrate one way to build truly cross-platform component library with a unique approach of using React & React Native in combination.
Design systems aim to bring consistency to a brand's design and make the UI development productive. Component libraries with well thought API can make this a breeze. But, sometimes an API choice can accidentally overstep and slow the team down! There's a balance there... somewhere. Let's explore some of the problems and possible creative solutions.
Building a design system is not enough. Your dev team has to prefer it over one-off components and third-party libraries. Otherwise, the whole effort is a waste of time. Learn how to use static code analysis to measure if your design system wins over the internal competition and data-driven ways to improve your position.