之前有个需求要写个类似省市县三级联动的页面,于是,网上找了点资料看了下,其实原理很简单:
当我们选择一级栏目中某条记录的时候,会获取该栏目的vaule值,并发起ajax请求,后台根据这个vaule值,返回对应的二级数据,并且将数据填充到二级栏目列表;
当我们选择二级栏目中某条记录的时候,会获取该栏目的vaule值,再次发起ajax请求,后台根据这个vaule值,返回对应的三级数据,并且将数据填充到三级列表。
多说无益,请看效果:
下面贴上这个页面的html代码(这个$data数据来源会在后面说明):
<div class="panel-body"> <h3>查看详细栏目</h3> <div class="signForm"> <label>一级分类名称:</label> <div class="input-group short-row"> <select class="form-control parent" id="fClass"> <option value="">请选择一级分类名称</option> <?php foreach ($data as $value): ?> <option value="<?= $value['fname'] ?>" ><?= $value['fname'] ?></option> <?php endforeach; ?> </select> </div> </div> <div class="signForm"> <label>二级分类名称:</label> <div class="input-group short-row"> <select class="form-control parent" id="sClass"> <option value="">请选择二级分类名称</option> </select> </div> </div> <div class="signForm"> <table class="table table-bordered bg-white"> <thead> <tr> <th class="text-center">ID</th> <th>标题</th> <th>详细图片</th> <!--<th>描述</th>--> <th>操作</th> </tr> </thead> <col style="width: 5%"> <col style="width: 15%"> <col style="width: 15%"> <col style="width: 15%"> <col style="width: 15%"> <col style="width: 15%"> <tbody id = "list"> </tbody> </table> </div> </div>
接下来是js代码:
<script> $("#fClass").change( function() { getSclass(); } ); $("#sClass").change( function() { getList(); } ); function getSclass() { //获取选定的一级分类名称 var fVal = $("#fClass").val(); //根据一级分类查二级数据 $.ajax({ //取消异步,也就是必须完成上面才能走下面 async:false, url:"http://localhost/yii2/web/index.php/mch/book/zhong/findsname", data:{val:fVal}, type:"get", dataType:"JSON", success: function(data){ var str="<option value=\"\">请选择二级分类名称</option>"; //遍历数组,把它放入str for(var i=0;i<data.length;i++){ var content = data[i]; str+="<option value=\""+content.sname+"\">"+content.sname +"</option>"; } $("#sClass").html(str); } }); } function getList() { //获取选定的一级分类名称 var sVal = $("#sClass").val(); //根据一级分类查二级数据 $.ajax({ //取消异步,也就是必须完成上面才能走下面 async:false, url:"http://localhost/yii2/web/index.php/mch/book/zhong/findtclass", data:{val:sVal}, type:"get", dataType:"JSON", success: function(data){ var str="";//遍历数组,把它放入str for(var i=0;i<data.length;i++){ var res = data[i]; str+="<tr> <td>"+res.id+"</td><td>"+res.tname+"</td><td> <img src='"+res.tpic+"'/></td>"+"<td></td></tr>"; } $("#list").html(str); } }); } </script>
然后就是上面涉及到的两个接口,不难看出这两个action都是ZhongController.php类里面的方法:
public function actionFindsname($val) { $conn = \Yii::$app->db; $sql = "select * from sclass where fname ='".$val."'"; $command =$conn->createCommand($sql); $data = $command->queryAll(); return $res=json_encode($data); } public function actionFindtclass($val) { $conn = \Yii::$app->db; $sql = "select * from tclass where sname ='".$val."'"; $command =$conn->createCommand($sql); $data = $command->queryAll(); return $res=json_encode($data); }
补充说明:
$data:这个页面(index.php)是由控制器里面的actionIndex跳过来的,那么$data自然是来自actionIndex这方法;
public function actionIndex() { $conn = \Yii::$app->db; $sql = "select * from fclass"; $command =$conn->createCommand($sql); $data = $command->queryAll(); return $this->render('index', ['data'=>$data,]); }
这就是一级栏目数据的来源了,换种说法就是,页面的初始化数据,一级栏目数据在页面(index.php)初始化的时候就是必须有的。
然后,当这个一级栏目数据发生改变的时候,会触发这个select标签的change事件,于是就会执行相应的回调函数(getSclass());
相应地,当二级栏目数据发生改变的时候,会触发二级栏目select标签的change事件,于是就会执行相应的回调函数(getList());
这样一来,三级栏目数据就会显示出来了。