Custom columns in a grid

As mentioned in the previous paragraph, the columns property of the GridView widget is mainly filled with strings.

When we need to apply a specific format, such as currency or date/time, we can append this specification to the column name with a colon and the type used for formatting, as currency or datetime.

But the most general form of a GridView column is an object of the yiigridColumn class, derived by the yiigridDataColumn class.

A GridView column extended by the yiigridColumn class is rendered using an array with the following keys:

        [
// can be omitted, as it is the default
'class' => 'yiigridDataColumn',

        'attribute',    // name of model attribute
        'format',         // format use to display data
        'header',        // header of column
        'footer',        // footer of column
        'visible',        // flag to set visibility
        'content'         // callback to print data
        ],

There are also other parameters but these ones are the most used.

Example – displaying a reservations list by clicking on a customer grid row

We are now ready to create a customer grid that contains a reference to the linked reservation list in every row. First of all, make sure that the structure and the data for the customer and reservation tables is the following:

--
-- Structure of Table `customer`
--

CREATE TABLE IF NOT EXISTS `customer` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `surname` varchar(50) NOT NULL,
  `phone_number` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

--
-- Data Dump of Table `customer`
--

INSERT INTO `customer` (`id`, `name`, `surname`, `phone_number`) VALUES
(1, 'James', 'Foo', '+39-12345678'),
(2, 'Bar', 'Johnson', '+47-98438923');

--
-- Structure of Table `reservation`
--

CREATE TABLE IF NOT EXISTS `reservation` (
  `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  `room_id` int(11) NOT NULL,
  `customer_id` int(11) NOT NULL,
  `price_per_day` decimal(20,2) NOT NULL,
  `date_from` date NOT NULL,
  `date_to` date NOT NULL,
  `reservation_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `room_id` (`room_id`),
  KEY `customer_id` (`customer_id`)
);

--
-- Data Dump of table `reservation`
--

INSERT INTO `reservation` (`id`, `room_id`, `customer_id`, `price_per_day`, `date_from`, `date_to`, `reservation_date`) VALUES
(1, 2, 1, 90.00, '2015-04-01', '2015-05-06', '2015-05-24 22:45:37'),
(2, 2, 1, 48.00, '2019-08-27', '2019-08-31', '2015-05-24 22:45:37'),
(3, 1, 2, 105.00, '2015-09-24', '2015-10-06', '2015-06-03 00:21:14');

Create a new controller named CustomersController in basic/controllers/CustomersController.php with the actionGrid action to display a list in the grid view:

<?php

namespace appcontrollers;

use Yii;
use yiiwebController;
use appmodelsCustomer;
use yiidataActiveDataProvider;

class CustomersController extends Controller
{
    public function actionGrid()
    {
        $query = Customer::find();
        
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
            'pagination' => [
                'pageSize' => 10,
            ],
        ]);
        
        return $this->render('grid', [ 'dataProvider' => $dataProvider ]);
        
    }
}

This action actionGrid simply creates a data provider with all the data from the customer (unfiltered) and with a pagination that displays ten items on a page. Finally, render the grid view.

This is the content of the grid view in basic/views/customers/grid.php:

<?php
use yiigridGridView;
use yiihelpersHtml;
?>

<h2>Customers</h2>

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'columns' => [
        'id',
        'name',
        'surname',
        'phone_number',
        
        [
            'header' => 'Reservations',
            'content' => function ($model, $key, $index, $column) {
                return Html::a('Reservations', ['reservations/grid', 'Reservation[customer_id]' => $model->id]);
            }
        ],
        
        [
            'class' => 'yiigridActionColumn',
            'template' => '{delete}',
            'header' => 'Actions',
        ],        
    ],
]) ?>

The last two columns require particular explanation.

The penultimate one, Reservation, displays a link to give you access to the list of all customer reservations. We have put Reservations as the header and filled the content property with dynamic data passed from the callback function, which returns an HTML link to the reservations/index route with a parameter indicating customer_id selected.

The last column headed Actions displays the ActionColumn with the single action delete to remove the selected record.

Point your browser to http://hostname/basic/customers/grid and you should have the following output:

Example – displaying a reservations list by clicking on a customer grid row

The Customers grid using the GridView widget

Note

The language used in GridView is configured in basic/config/web.php with the language property. This property has a global effect on every core widget.

We can complete this example by just putting a counter near the Reservations link to indicate the number of reservations for each customer.

For this purpose, we need to add a new relation named getReservationsCount to the Customer model in basic/models/Customer.php, which returns the number of reservations linked to the customer:

    public function getReservationsCount()
    {
      return $this->hasMany(appmodelsReservation::className(), ['customer_id' => 'id'])->count();
    }

Now we can modify the penultimate column with:

        [
            'header' => 'Reservations',
            'content' => function ($model, $key, $index, $column) {
                $title = sprintf('Reservations (%d)', $model->reservationsCount);
                return Html::a($title, ['reservations/grid', 'Reservation[customer_id]' => $model->id]);
            }
        ],

If we refresh our browser now, we will see near the Reservations anchor link, the correct number of reservations for that customer appears.

This example represents the complete reservations list displayed when a user clicks on the link Reservations.

Create ReservationsController as a new file in basic/controllers/ReservationsController.php with an action grid and the following content:

<?php

namespace appcontrollers;

use Yii;
use yiiwebController;
use appmodelsReservation;
use yiidataActiveDataProvider;

class ReservationsController extends Controller
{
    public function actionGrid()
    {
        $query = Reservation::find();
        
        if(isset($_GET['Reservation']))
        {
            $query->andFilterWhere([
                'customer_id' => isset($_GET['Reservation']['customer_id'])?$_GET['Reservation']['customer_id']:null,
            ]);
        }
        
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
            'pagination' => [
                'pageSize' => 10,
            ],
        ]);
        
        return $this->render('grid', [ 'dataProvider' => $dataProvider ]);
        
    }
}

In this controller, we applied an andFilterWhere condition to query whether $_GET['Reservation'] is set. The andFilterWhere()method will apply a filter passed as a parameter only if the condition is not empty. So if $_GET['Reservation']['customer_id'] is not set, the andFilterWhere() condition parameter will have a null value and will not be appended to any other query condition.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.143.244.83