GridView เป็น Widget พื้นฐานที่เราน่าจะคุ้นเคยกันดี และส่วนใหญ่เวลาแสดงผล เราก็มักจะใช้ GridView เป็นหลักเพราะด้วยความที่ใช้งานง่ายและสะดวก วันนี้จะขอแนะนำการปรับแต่ง GridView เพื่อให้เราสามารถใช้งาน GridView ได้อย่างเต็มประสิทธิภาพ และส่วนที่เราใช้งานมากที่สุดนั้นก็คือ columns

Columns

Columns มีอยู่ 2 ส่วนหลักที่เราใช้งานบ่อยๆ คือ

  • columns เป็นส่วนที่เอาไว้กำหนดว่าเราต้องการแสดงข้อมูลคอลัมน์ใหนบ้างโดยระบุชื่อคอลัมน์เข้าไป
  • Shortcut Format เป็นการกำหนด format ของการแสดงผลในแต่ละคอลัมน์สามารถระบบ format ต่อท้ายชื่อคอลัมน์ได้เลยโดยคั่นด้วยเครื่องหมาย :
  • Anonymous functions เป็นการปรับแต่งคอลัมน์ที่ยือยุ่นที่สุด สามารถใส่เงื่อนไข รับค่าตัวแปรต่างๆ ได้ กำหนดสี, ใส่ icon อืนๆ

การใช้งาน column

ซึ่งในส่วนของ columns เมื่อเราต้องการที่จะแสดงข้อมูล column อะไรบ้างเราสามารถระบุชื่อ column ลงไปได้เลยเช่น ต้องการแสดงข้อมูล title,name,surname

 <?= GridView::widget([
      'dataProvider' => $dataProvider,
      'filterModel' => $searchModel,
      'columns' => [
          'title',
          'name',
          'surname'
      ],
  ]); ?>

ส่วนใหญ่เราก็จะใช้กันแค่นี้..แต่จริงๆ แล้ว มันมีฟังชันก์อีก 1 ตัวที่อยากแนะนำคือ Shortcut Format สิ่งที่จะทำให้เรากำหนดรูปแบบการแสดงผลได้ง่ายๆ

Shortcut Format

ปกติเราก็จะระบุแค่ชื่อคอลัมน์เข้าไป แต่จริงๆ GridView คุณสมบัติอีกอย่างนึง ที่มันทำให้เราปรับแต่งการแสดงผลใน column ได้ง่ายๆ นั้นคือ shortcut format ซึ่งรูปแบบจะเป็นดังนี้ "attribute:format:label" ปกติเราจะใส่แต่ชื่อคอลัมน์เข้าไปแต่นี่ เราสามารถกำหนดการแสดงผลได้ ว่าจะให้ออกมา format อะไร และยังกำหนด label ในตรงนี้ได้อีกด้วย แค่คั้นด้วยเครื่องหมาย :

  • attribute คือชื่อคอลัมน์ที่ต้องการแสดงผล
  • format คือข้อมูลที่เราต้องการให้แสดงผลออกมาในรูปแบบที่ต้องการ เช่น เราเก็บข้อมูลเป็นวันที่ 2015-06-01 เราสามารถกำหนด format เป็น date ได้โดยผลลัพจะออกมาเป็น Jun 24, 2015 ได้ซึ่งมีหลาย format มาก เช่น date,dateTime,email,time,text,html ไปเลือกใช้งานกันเองได้ที่นี่
  • label เป็นข้อความของหัวคอลัมน์ที่เราต้องการแสดงผลให้เปลี่ยนจากของเดิมที่กำหนดไว้ใน attributesLabel() ใน Model และตรงนี้เป็น option จะระบุหรือไม่ก็ได้

ตัวอย่างการเรียกใช้งาน shortcut format

 <?= GridView::widget([
      'dataProvider' => $dataProvider,
      'filterModel' => $searchModel,
      'columns' => [
          'created_at:date:วันที่สร้าง', // แสดงผลวันที่
          'updated_at:dateTime', // แสดงผลวันที่และเวลา
          'email:email', // แสดงผลเป็น link MailTo
          'website:url',  // แสดงผล link url
          'is_admin:boolean', // แสดงเป็น Yes,No
          'payroll:decimal', // แสดงผลเป็นทศนิยม
          'content:html',// แสดงผลเป็น Html
          'photo:image',// แสดงผลเป็นรูปภาพ
          'age:integer',// แสดงผลเป็นจำนวนเต็ม
          'vat:percent',// แสดงผลเป็น %
          'content:text',// แสดงผลข้อความ text
          'created_at:time',// แสดงผลเป็นเวลา
          'file_size:size',// แสดงผลเป็นหน่วยของขนาดเช่น 12 kilobytes ค่าข้อมูลต้องเป็น bytes
          'file_size:shortSize',// แสดงผลเป็นหน่วยของขนาดเช่น 12 KB ค่าข้อมูลต้องเป็น bytes
          'created_at:relativeTime'// แสดงผลเป็นเวลาที่ผ่านมาแล้ว
      ],
  ]); ?>

จะเห็นว่าเราสามารถกำหนดแบบสั้นๆ ได้ โดยที่เราไม่ต้องระบุโค้ดแบบเต็มๆ ทำให้ลดเวลาได้มากๆ เพราะถ้าเขียนเต็มๆ จะยาวมากๆ แบบนี้ทุกคอลัมน์

 //...
 'columns' => [
   [
        'attribute' => 'name',
        'format' => 'text',
        'label' => 'Name',
    ],
  ]

การปรับแต่งคอลัมน์โดยใช้ Anonymous functions

Anonymous functions เป็นความสามารถของ PHP นะครับ มีให้ใช้ตั้งแต่เวอร์ชั่น 5.3.0 แต่แนะนำ 5.4.0 นะครับเพราะน่าจะทำงานได้ดีกว่า

ปกติการใช้งาน GridView หากไม่ได้มีการใช้งานที่มีเงื่อนไขซับซ้อนอะไร ก็สามารถใช้ตามแบบที่แนะนำเบื้องต้นก็เพียงพอ แต่หากมีเงื่อนไขที่ซับซ้อน เราก็ยังสามารถปรับแต่งคอลัมน์ได้อีก ซึ่งการใช้งานแบบนี้ เรียกว่า anonymous function ถ้าใครเคยเขียน JavaScript & jQuery จะเห็นว่าคล้ายๆกัน โดยเราสามารถประการ function เข้าไปที่ property value แบบนี้ได้เลย value=>function(){} สะดวกมากๆ

รายละเอียด anonymous function จะมี parameter ให้สามารถเรียกใช้งานได้ดังนี้

  • $model คือตัวแทนข้อมูล record นั้นๆ สามารถเรียกคอลัมน์อื่นๆ ได้
  • $key pk ของ record นั้น
  • $index ลำดับของ index
  • $column yii\grid\DataColumn object

เราสามารถตั้งค่าตัวแปรพวกนี้เป็นชื่ออะไรก็ได้ เพราะมันจะยึดตามลำดับเป็นหลัก เพราะฉะนั้นเราต้องรู้เองนะครับว่า ตัวแปรที่ตั้งใหม่อยู่ที่ลำดับอะไร ชื่ออะไร

ตัวอย่างการใช้งาน

 <?= GridView::widget([
      'dataProvider' => $dataProvider,
      'filterModel' => $searchModel,
      'columns' => [
        [ // รวมคอลัมน์
          'label'=>'ชื่อ-นามสกุล',
          'format'=>'html',
          'value'=>function($model, $key, $index, $column){
            return $model->title.$model->firstname.' '.$model->lastname;
          }
        ],
        [ // แสดงข้อมูล string
          'attribute' => 'is_admin',
          'format'=>'html',
          'value'=>function($model, $key, $index, $column){
            return $model->is_admin==1 ? "YES":"NO";
          }
        ],
        [ // แสดงข้อมูลออกเป็น icon
          'attribute' => 'is_admin',
          'format'=>'html',
          'value'=>function($model, $key, $index, $column){
            return $model->is_admin==1 ? "<i class=\"glyphicon glyphicon-ok\"></i>" : "<i class=\"glyphicon glyphicon-remove\"></i>";
          }
        ],
        [ // แสดงข้อมูลออกเป็นสีตามเงื่อนไข
          'attribute' => 'is_admin',
          'format'=>'html',
          'value'=>function($model, $key, $index, $column){
            return $model->is_admin==1 ? "<span style=\"color:green;\">YES</span>":"<span style=\"color:red;\">No</span>";
          }
        ],
        // ...
      ],
  ]); ?>

ตัวอย่างการแสดงผล

และเราสามารถระบุใช้งาน parameter แค่บางตัวก็ได้ ส่วนใหญ่ใช้แค่ $model ก็เพียงพอแล้ว ระบุแบบนี้ได้

 <?= GridView::widget([
      'dataProvider' => $dataProvider,
      'filterModel' => $searchModel,
      'columns' => [
        [
          'attribute' => 'created_at',
          'value'=>function($model){
            return $model->title.$model->firstname.' '.$model->lastname;
          }
        ]
        // ...
      ],
  ]); ?>

จะสังเกตได้ว่า หาเรากำหนด anonymous function แบบนี้แล้ว ตัว property attribute จะมีหน้าที่แค่ดึงข้อมูล hedader label มาแสดงเท่านั้น หากเราไม่ต้องการ ก็สามารถระบุเข้าไปโดยตรงได้ โดยใช้ attribute label กำหนดค่า ข้อความที่ต้องการเข้าไปได้เลย

และถ้าอยากกำหนด format เองแบบ shortcut format ก็สามารถทำได้ และสามารถใช้ได้ทุก format ที่กล่าวมา

 <?= GridView::widget([
      'dataProvider' => $dataProvider,
      'filterModel' => $searchModel,
      'columns' => [
        [
          'attribute' => 'created_at',
          'value'=>function($model){
            return Yii::$app->formatter->asDate($model->created_at, 'medium');
          }
        ]
        // ...
      ],
  ]); ?>

อ่านเพิ่มเติมการใช้งาน formatter ได้ทีนี่

เรียกใช้งานตัวแปรที่อยู่นอก scoping anonymous function

ปกติการใช้งาน anonymous function ภายใน function นี้ มันจะไม่รู้จักตัวแปรที่อยู่ด้านนอก function เลย แต่ก็มีบางกรณี ที่เราต้องการนำตัวแปรต่างๆ เข้าไปใช้ใน anonymous function ซึง anonymous function เองนั้น รองรับอยู่แล้ว แค่ use ตัวแปรที่ต้องการใช้งานเข้าไป รูปแบบ

function () use ($parms1,$parms2,$parms n....) {}

ตัวอย่าง ผมได้ประกาศตัวแปรไว้ด้านนอก GridView และจะทำการเรียกใช้งานที่ anonymous function ซึ่งสามารถเรียกได้ทุกๆ column เลย จะใช้กี่ตัวก็ได้แค่ use เข้าไป

ตัวอย่างการใช้งาน

<?php

$fullname = 'Satit Seethaphon';

 <?= GridView::widget([
      'dataProvider' => $dataProvider,
      'filterModel' => $searchModel,
      'columns' => [
        [
          'attribute' => 'created_at',
          'value'=>function($model) use ($fullname){
            return $model->created_at . " | " . $fullname;
          }
        ]
        // ...
      ],
  ]); ?>

อ่านเพิ่มเติม functions.anonymous

ขอบคุณ อ.@Utehn Phnu ที่แนะนำมาครับ

หวังว่าน่าจะเป็นประโยชน์และช่วยให้เราสามารถปรับแต่งได้ง่ายขึ้นนะครับ.

รายละเอียดเพิ่มเติม