Create a uiComponent listing (grid) in the magento2 admin

This tutorial is the 7th in a long series of magento2 tutorial. In the last episode, you learned how to create a model and interact with the magento2 database. If you do not know magento (v1) it does not matter, I will talk about it but you do not need to know the magento (v1) platform to master this tutorial on magento2.But you have to do the 6 previous tutorials before starting this one.
In the previous tutorial we saw how to add its module to the administration (backend) of magento2! We will now see how to add a grid and a form magento2. We'll implemente the CRUD (adding, modifying, deleting, mass deletion) for our contacts. Let start from the files in our previous tutorial.

Create the controller for the grid magento2

First of all, we will create our magento2 grid which will allow us to view our contacts in the backend. To do this, start by editing the Index action of your Contact controller (/Pfay/Contacts/Controller/Adminhtml/Test/Index.php) like this to load and display your layout:

Here it is told to get uiComponent and put it in the container "content" of our theme. We will give it the name "contacts_test_listing" (pay attention to the name you give here because we will use it to create the following file).
This magento2 uiComponent is as you can imagine our Grid.
So we will define our uiComponent.
Create the /app/code/Pfay/Contacts/view/adminhtml/ui_component/ folder with the following contacts_test_listing.xml file:

This file looks complex but it is not as complex as it seems.It is just a listing tag that contains 4 child tags:
- argument:
Here we declare the data_sources to use (which makes the links between your grid and the database) with the tag js_config.
We also declare the spinner, that is the name of the tag "columns" that will be used in our grid.
We then declare our buttons in the buttons tag with a name, a label, a class and a target url.

- dataSource:
Here we define the dataProvider (the object that will fetch our data in database). With a "class" tag to define the name of the object to be used. This object will be defined later in the di.xml (dependency node file).
We give a name to our dataSource via the "name" attribute and then we give it the field to use as the id for the grid in the database ("primaryFieldName") and for the request ("requestFieldName").
We then define in "config" the component to use (here "Magento_Ui/js/grid/provider") and the identifier in our bdd "indexField" which here has the value "pfay_contacts_id".

- columns:
It was defined above in the "spinner" section of the "argument" section, here it is named listing_columns.
This area will allow us to define our columns with the identifier to be used to find oneself, the type of fields and filters to use for the grid, the type of sorting that will be used and a label.

In the actionsColumn we defined the class to use to define the buttons to know ContactsActions. Therefore, create the corresponding app/code/Pfay/Contacts/Ui/Component/Listing/Column/ContactsActions.php file:

Then remember that in this file we defined an object called ContactsGridDataProvider, currently it does not correspond to anything so we will declare this object called a dataProvider by defining it in the dependency injection file (di. Xml).

Here it looks like it is complicated but in fact it is very simple:
1- We define a virtualType ContactsGridDataProvider, we pass it to the class of our collection Pfay\Contacts\Model\ResourceModel\Contact\Collection and we tell magento to use a "filterPool" with the name "ContactsGirdFilterPool".
2- We define the "ContactsGirdFilterPool" just declared by passing a item "regular" and a item "fulltext".
3- we create the type contacts_test_listing_data_source that we use above in our XML (be careful to put the same name) and we define that it will use our collection.
4. Create a VirtualType SearchResult, pass it on to our collection, and tell it to use our "pfay_contacts" table and the resourceModel "Pfay\Contacts\Model\ResourceModel\Contact" to find out.

Go to your admin interface and you should now see your grid appears.

If this is not the case, do not hesitate to empty your cache, run the update command (see previous tutorials) and give the right rights to your files.

Add the add button to our magento2 grid

In our listing component (our grid : /app/code/Pfay/Contacts/view/adminhtml/ui_component/contacts_test_listing.xml) add the following code in argument to add the "add" button of our grid:

It is in the item "buttons" that you will put all your buttons. This element is an "array", so you can put several items in a row.
Each element will be a button, for which you define a name, label, class and url. Which one is redirecting when clicked (here we redirect to */*/add which means that we will redirect To the "Add" action of the same folder as our current Action.
We create a file /app/code/Pfay/Contacts/Controller/Adminhtml/Test/Add.php that contains our action:

Reload your page and click on the "Add a new Contact" button that appears now, you should arrive on your action which displays a blank page with "test add".
We'll see in the next tutorial how to display the form that will add a new contact.

Optional items:

The optional elements are put in the "container". The "container" is the 4th non-mandatory tag of the listing element after "argument", "dataSource", and "columns" which are mandatory. It takes at least one data argument which allows to define its template ( ui/grid/toolbar ).
Here's how to integrate it into our /app/code/Pfay/Contacts/view/adminhtml/ui_component/contacts_test_listing.xml file

So this is in this "container" element that we'll put the optional elements.

Add the "columns controls" Container

The columns controls is an element that allows you to manage the columns of your grid on the fly, you can add/remove a column/reset the grid to a base state and you can save the grid state in the session.
Here is the code to integrate in the "container" to display the columns controls:

Mass Actions under magento2

You want to be able to select several lines of your grid to delete them all at once or do another specific processing on all the lines selected at the same time? The Mass Actions are made for this.
First of all it will be necessary to add the inputs on the edge of our grid to be able to select the lines, so in "columns" add this before the "column":

You now see the checkboxes on the side that allow you to select multiple lines.
Here is how to integrate the selectbox which allows to select the action to be performed once we have selected our lines:

Here it is the same, we have to be careful on what we enter as a path for the "selectProvider" and we add the actions following each other. In order to prepare the next tutorial, we will create the MassDelete controller. This is where we will be redirected when we select our action (*/*/massDelete).
Create the following file /app/code/Pfay/Contacts/Controller/Adminhtml/Test/MassDelete.php :

Here we check that the parameter "selected" has indeed been sent and that it is indeed a non-empty array otherwise we redirect to the grid. If it's ok, then we go through the ids and delete the contacts. Then we redirect to the grid.
And voila if you use your mass actions you should arrive on your action.

Create a search field in admin magento2

To create a search field on the magento admin, you must add an optional element in the container that will be called "filterSearch" like this:
In app/code/Pfay/Contacts/view/adminhtml/ui_component/contacts_test_listing.xml you can add:

You notice here that for version 0.3.0, we add for the table pfay_contacts an index on the name and the email of type FULLTEXT. It is this index that will be used to filter our admin listing in magento2.

We will see in the next tutorial how to create the create/delete/edit actions and the creation and editing form linked to our grid and our contact object!
This is the end of this tutorial on magento2 uiComponent listing, congratulations to you who followed this tutorial until the end. If this tutorial tells you more or you have a question, share this article on twitter and don't hesitate to let a comment!