Yii2.0框架中使用ajax动态显示提示hint

本文基于《魏曦教你学 - Yii2.0 ****”》视频的第4.9课(4.9 后台功能完善之Post部分 ),在视频中将content:ntext,注释掉了,如图:

Yii2.0框架中使用ajax动态显示提示hint

 

本文将content列截取20个字符显示,并在后面加上a 标签,a 标签显示的内容为 ...,鼠标的hover事件使用ajax显示将content截取500字符的提示框(hint),如图:

Yii2.0框架中使用ajax动态显示提示hint

Yii2.0框架中使用ajax动态显示提示hint

 

------------------------------------------------------------正文开始--------------------------------

Yii2.0基于MVC 框架,因此在视图(advanced/backend/views/post/index.php)中处理a 标签,在控制器(advanced/backend/controllers/PostController.php)中响应ajax请求,并且本文用到了hint.css和hint.js两个自定义的文件,因此需要在AppAsset(advanced/backend/assets/AppAsset.php)中加入这两个文件。

一、PostController.php文件中加入 actionHint($id)方法,如图:

Yii2.0框架中使用ajax动态显示提示hint

源码:

/* 命名为actionHint的原因是由前端提交的url路由决定的。

hint.js 中ajax 的url参数为:url : "index.php?r=post/hint", 路由就是“r=post/hint ”,

其中,斜杠“/”之前的post决定了使用PostController控制器,斜杠后面的是动作hint,决定了在控制器中寻找 actionHint方法。

基本上可以理解为Yii2.0使用字符串分析及拼接函数,自动对接了相应的控制器和动作,post+controller和action+hint,

只不过类名使用了大驼峰命名法,方法使用了小驼峰命名法。

*/

            /* 

$this->findModel($id)->content 获取了原文。

strip_tags 去掉html标签

mb_substr(...,0,500,'utf-8'); 截取前500字符串,并使用utf-8编码显示。

          */


    public function actionHint($id)
    {
        if(Yii::$app->request->isAjax) {//ajax提交上来的方法              
            return mb_substr(strip_tags($this->findModel($id)->content),0,500,'utf-8'); 

        }
    }

如果有多个参数,可以使用下面的代码。

  public function actionHint()
    {
        if(Yii::$app->request->isAjax) {              
           // return mb_substr(strip_tags($this->findModel($id)->content),0,500,'utf-8'); 
            $data= Yii::$app->request->get();  // or    Yii::$app->request->post();获取前端提交上来的参数    
            $id= explode(":", $data['id']);
            $id= $id[0]; 
            $id2= explode(":", $data['id2']);
            $id2= $id2[0]; //更多参数 id3,id4...
            return $id2 . ":" .  mb_substr(strip_tags($this->findModel($id)->content),0,500,'utf-8');
        }
        
    }

二、视图index.php(advanced/backend/views/post/index.php)

在本页面中设置显示列内容和加入a标签

<?php

use yii\helpers\Html;
use yii\grid\GridView;
use common\models\Poststatus;


//use backend\assets\AppAsset; //可以局部页面加载css与js文件,使用AppAsset类的静态方法addScript和addCss

/* @var $this yii\web\View */
/* @var $searchModel common\models\PostSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = '文章管理';
$this->params['breadcrumbs'][] = $this->title;

 
//自定义css 使gridview 的行标题居中
$this->registerCss('th {text-align: center;}',['depends'=>['backend\assets\AppAsset']]); 

//使用AppAsset类的静态方法addScript和addCss可以放在这里

//addScript($this,'css/hint.js'); addCss($this,'css/hint.css');


?>
<div class="post-index">

    <h1><?= Html::encode($this->title) ?></h1>

    <p>
        <?= Html::a('创建文章', ['create'], ['class' => 'btn btn-success']) ?>
    </p>

    <?php // echo $this->render('_search', ['model' => $searchModel]); ?>

    <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,         
        'columns' => [
         //   ['class' => 'yii\grid\SerialColumn'],           
            
            'id',
            'title',
            //'author_id',
            [
                'attribute'=>'author_id',
                'value'=>'author.nickname',
             //   'headerOptions' => ['style'=>'text-align:center'],
            ],


            //content:ntext,
            [
                'attribute'=>'content',
                'format' => 'raw', //a标签能显示自定义属性的关键raw
                'value'=>function($model)
                     {
                        $tmpStr=strip_tags($model->content);       

//a 标签中的data-hint用来显示hint的内容,hint.js通过改变 data-hin显示提示文本                                  
                        $html=Html::a('&nbsp...&nbsp','#',['class'=>'hint hint-info','data-hint'=>'',]);                                       
                         $tmpLen=mb_strlen($tmpStr);
                         return mb_substr($tmpStr,0,20,'utf-8').(($tmpLen>20)?$html:'');
                     }       
               
            ],


            'tags:ntext',
            // 'status',
            [
                'attribute'=>'status',
                'value'=>'status0.name',
                'filter'=>Poststatus::find()
                    ->select(['name','id'])
                    ->orderBy('position')
                    ->indexBy('id')
                    ->column(),
            ],
            //'create_time:datetime',
            //'update_time:datetime',
            //'author_id',            
            ['class' => 'yii\grid\ActionColumn'],
        ],
       
    ]); ?>
</div>

三、AppAsset.php(advanced/backend/assets/AppAsset.php)

本页面中加入css和js文件

<?php

namespace backend\assets;

use yii\web\AssetBundle;

/**
 * Main backend application asset bundle.
 */
class AppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        'css/site.css'
        'css/hint.css', //自定义css与js的文件保存位置 advanced/backend/web/css
    ];
    public $js = [
        'css/hint.js', //自定义css与js的文件保存位置 advanced/backend/web/css
    ];
    public $depends = [
        'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',
    ];
    
    public static function addScript($view, $jsfile) {
        $view->registerJsFile($jsfile, [AppAsset::className(), 'depends' => 'backend\assets\AppAsset']);
    }
    //定义按需加载css方法,注意加载顺序在最后
    public static function addCss($view, $cssfile) {
        $view->registerCssFile($cssfile, [AppAsset::className(), 'depends' => 'backend\assets\AppAsset']);
    } 
    
}

四、使用的hint.js和hint.css

hint.js

$(function(){
    $('.hint').hover(
            function(){
            let e = $(this);      //保存当前的html对象,ajax中使用    
            $.ajax({
                 url : "index.php?r=post/hint",//路由指定的控制器及触发动作
                 type : 'get',
                // data : {id:e.parent().parent().attr('data-key'),id2:"ps"},
                 data : {id:e.parent().parent().attr('data-key')},
                 dataType : 'text',
                // async : false,
                 success : function(data){                        
                     e.attr('data-hint',data);    
                    
                 },
                 error : function(){
                    console.log('ajax error exec');
                 }

            });
        },function(){
            $(this).attr('data-hint','')                
        }
    );
})

hint.css


.hint-info{
  position: relative;
  display: inline-block;
  background-color: #e6e6e6;
    
 }

 .hint-info:hover{
    background-color:#9e9a9a;
 }

  .hint-info:before, .hint-info:after {   
    position: absolute;
    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    visibility: hidden;
    opacity: 0;
    z-index: 1000000;
    pointer-events: none;
    -webkit-transition: 0.3s ease;
    -moz-transition: 0.3s ease;
    transition: 0.3s ease;
    -webkit-transition-delay: 0ms;
    -moz-transition-delay: 0ms;
    transition-delay: 0ms; }

  .hint-info:hover:before, .hint-info:hover:after {
    visibility: visible;
    opacity: 1; }

  .hint-info:hover:before, .hint-info:hover:after {
    -webkit-transition-delay: 100ms;
    -moz-transition-delay: 100ms;
    transition-delay: 100ms; }

    
  .hint-info:before {
    content: '';  
  /*  position: absolute;*/
    background: transparent;
    border: 6px solid transparent;
    z-index: 1000001; }

  .hint-info:after {
    background: #383838;
    color: white;
    padding: 8px 10px;
    font-size: 12px;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    line-height: 12px;
    min-width: 300px;
   /* white-space: nowrap; */}

  .hint-info[data-hint]:after {
    content: attr(data-hint); }

[data-hint='']:before,
[data-hint='']:after {
  display: none !important; }

.hint-info:after {
    text-shadow: 0 -1px 0px black;
    box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3); }