Yii2.0框架中使用ajax动态显示提示hint
本文基于《魏曦教你学 - Yii2.0 ****”》视频的第4.9课(4.9 后台功能完善之Post部分 ),在视频中将content:ntext,注释掉了,如图:
本文将content列截取20个字符显示,并在后面加上a 标签,a 标签显示的内容为 ...,鼠标的hover事件使用ajax显示将content截取500字符的提示框(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)方法,如图:
源码:
/* 命名为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(' ... ','#',['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); }