เทวดาองค์ใหม่มาดูแลบ้านเมืองแทนองค์เดิม


ทำระบบ Tag สำหรับ Post ด้วย Taggable Behavior และ Selectize Widget

คู่มือการเรียนรู้ Yii Framework 2 (Yii2)

บทเรียนดีๆ สำหรับผู้ที่ต้องการแบ่งปัน บทเรียนของคุณอาจมีค่าสำหรับอีกหลายๆ คน

beta version

ทำระบบ Tag สำหรับ Post ด้วย Taggable Behavior และ Selectize Widget

มานพ กองอุ่น Yii2 Yii Framework taggable 374

สวัสดีครับ วันนี้มาแนะนำการใช้งาน Tag ในแต่ละ Post นะครับ ซึ่งเราจะเห็นคุ้นตากันในแต่ละ web เช่น เว็บที่สร้างจาก Wordpress ก็จะมีระบบ Tag มาให้ ในที่นี่เราจะมาสร้างระบบ Tag ใน Yii Framework 2 กันนะครับ เริ่มจาก

ติดตั้ง Package

ทำการติดตั้ง Package ที่เกี่ยวข้องซึ่งมี 2 Package ด้วยกันคือ yii2-taggable-behavior และ yii2-selectize-widget ด้วยคำสั่งต่อไปนี้

$ composer require 2amigos/yii2-taggable-behavior:~1.0
$ composer require 2amigos/yii2-selectize-widget:~1.0

กำหนดโครงสร้างตาราง

ขั้นตอนนี้เรามากำหนดโครงสร้างตารางกันนะครับ โดยมีตารางหลัก และตารางเก็บ tag ดังต่อไปนี้ครับ

ตารางหลักให้เก็บข้อมูลใน filed ชื่อ tags

...
tags	varchar(255)	utf8_general_ci	
...

ตารางเก็บข้อมูล tag และความถี่ของ tag

CREATE TABLE `tags` (
  `id` int(11) NOT NULL,
  `name` varchar(100) NOT NULL,
  `frequency` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

ALTER TABLE `tags`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `tags`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

ตาราง post มี tag อะไรบ้าง

CREATE TABLE `post_has_tag` (
  `post_id` int(11) NOT NULL,
  `tag_id` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

สร้าง Model Tags

ทำการสร้าง Model ด้วย Gii โดยวางไว้ใน common/models/Tags และเพิ่ม method findAllByName() ไว้ เพื่อค้นหาโดยใช้ tag name นั่นเอง

<?php

namespace common\models;

use Yii;

/**
 * This is the model class for table "tags".
 *
 * @property integer $id
 * @property string $name
 * @property integer $frequency
 */
class Tags extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'tags';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['name', 'frequency'], 'required'],
            [['frequency'], 'integer'],
            [['name'], 'string', 'max' => 100],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => 'Name',
            'frequency' => 'Frequency',
        ];
    }

    public static function findAllByName($query)
    {
        return self::find()->where(['like', 'name', $query])->all();
    }
}

เพิ่ม method behaviors() ใน Model หลัก

ทำการเพิ่ม method behaviors() ใน model หลักเพื่อเรียกใช้งาน Taggable

use dosamigos\taggable\Taggable;

class Post extends ActiveRecord
{
    public function behaviors() {
        return [
            [
                'class' => Taggable::className(),
                'attribute' => 'tags'
            ],
        ];
    }

//...
    public function getTags()
    {
        return $this->hasMany(Tag::className(), ['id' => 'tag_id'])->viaTable('post_has_tag', ['post_id' => 'id']);
    }
}

เขียนโปรแกรมส่วน View

ทำการเขียนโปรแกรมในส่วนแสดงผลเพื่อให้เรียกใช้งาน Tag 

<?php
use dosamigos\selectize\SelectizeTextInput;
//...


if($model->isNewRecord){
    $data = [];
}else{
    $data = explode(',',$model->tags);
}
?>
...
<?= $form->field($model, 'tags')->widget(SelectizeTextInput::className(), [
    'loadUrl' => ['/site/tag-list'],//load ข้อมูล
    'options' => ['class' => 'form-control'],
    'clientOptions' => [
        'plugins' => ['remove_button'],
        'valueField' => 'name',
        'labelField' => 'name',
        'searchField' => ['name'],
        'create' => true,
    ]
])->hint('ใช้ comma เพื่อแยก tag เช่น yii,android,meteor,รับสมัครงาน') ?>
...

เขียนโปรแกรมใน Controller เพื่อโหลดข้อมูล Tag

ทำการเขียนโปรแกรมใน Controller ในที่นี้คือ frontend/controllers/SiteController.php โดยเพิ่ม actionTagList()

    use yii\web\Response;
    use common\models\Tags;
    //...
    
    public function actionTagList($query)
    {
        $models = Tags::findAllByName($query);
        $items = [];

        foreach($models as $model){
            $items[] = ['name' => $model->name];
        }
        Yii::$app->response->format = Response::FORMAT_JSON;
        return $items;
    }
    //...

ทดลองเปิดหน้าฟอร์ม

เมื่อเปิดหน้าเว็บจะเห็นว่าสามารถใช้งานระบบ Tag ได้แล้ว

และเมื่อบันทึกข้อมูลจะเห็นข้อมูลในตาราง tags


หากบทเรียนรู้มีความผิดพลาดประการใด หรือมีข้อเสนอแนะกรุณาแจ้ง contact@programmerthailand.com
มานพ กองอุ่น

มานพ กองอุ่น
admin

  • 2 เพื่อน
  • 8 ผู้ติดตาม
  • 754 โพสต์
กลับขึ้นบน