Yii框架中选择选项后如何正确获取CHtml::dropDownList的选中值
问题根因
你现在的写法混淆了后端渲染和前端交互的执行时机:
- PHP代码在页面请求到达服务器、渲染页面的时候就已经全部执行完毕,返回给浏览器的只是静态的HTML内容
- 你在浏览器中选择下拉选项是前端用户操作,此时没有和服务器交互的话,后端的
$dropvalue变量不会更新,自然不会触发你写的PHP判断逻辑 dropDownList的第二个参数只是用来设置页面首次渲染时下拉框的默认选中值,不会实时接收前端的选中结果
解决方案
根据你的场景复杂度,可以从以下两种方案里选择:
方案1:前端直接控制显隐(轻量场景首选)
适合需要展示的动态内容不多的场景,直接预渲染所有可能的内容块,默认隐藏,通过前端事件控制显隐即可:
<div class="row top10"> <div class="col-md-6 "> <?php echo CHtml::dropDownList( 'driver-names', $dropvalue, (array)Driver::driverDropDownList(Driver::getUserId()), array( 'class' => "form-control", 'id' => 'driver-select' // 手动指定id方便选择器调用 ) ) ?> </div> </div> <!-- 预渲染所有司机对应的内容,默认隐藏 --> <div class="driver-content" data-driver="George" style="display:none;"> <label class="col-sm-2 control-label"><?php echo Driver::t("first check") ?></label> <div class="col-sm-6"> <?php echo CHtml::checkBox( 'yes and no', $dropvalue=='George' ? true : false, array( 'class' => "switch-boostrap" ) ) ?> </div> </div> <!-- 其他司机对应的区块可以按照同样格式添加 -->
Yii1默认自带jQuery,直接添加以下JS代码即可:
<script> $(function(){ // 页面加载完成后先显示默认选中值对应的内容 let defaultDriver = $('#driver-select').val(); $(`.driver-content[data-driver="${defaultDriver}"]`).show(); // 监听下拉选择变化 $('#driver-select').on('change', function(){ let selectedDriver = $(this).val(); // 先隐藏所有内容区块 $('.driver-content').hide(); // 显示选中司机对应的区块 $(`.driver-content[data-driver="${selectedDriver}"]`).show(); }); }) </script>
方案2:Ajax动态加载内容(复杂场景适用)
如果动态内容需要依赖后端计算、数据查询,预渲染成本高,就用Ajax异步拉取对应内容:
- 首先在对应控制器里添加处理请求的动作,示例为SiteController:
public function actionGetDriverContent() { $driverName = Yii::app()->request->getPost('driver_name'); // 在这里根据司机名处理业务逻辑,渲染对应的内容片段 $this->renderPartial('_driver_content', array('driverName' => $driverName)); }
- 新建视图片段
_driver_content.php,存放动态内容逻辑:
<?php if($driverName == 'George'): ?> <label class="col-sm-2 control-label"><?php echo Driver::t("first check") ?></label> <div class="col-sm-6"> <?php echo CHtml::checkBox( 'yes and no', true, array( 'class' => "switch-boostrap" ) ) ?> </div> <?php endif; ?> <!-- 其他司机的判断逻辑也写在这里 -->
- 视图页添加内容容器和对应的JS逻辑:
<!-- 下拉列表代码和之前一致,加id="driver-select" --> <div id="driver-content-wrapper"></div> <script> $(function(){ // 页面加载完成先加载默认值对应的内容 loadDriverContent($('#driver-select').val()); $('#driver-select').on('change', function(){ loadDriverContent($(this).val()); }); function loadDriverContent(driverName){ $.post('<?php echo Yii::app()->createUrl("site/getDriverContent") ?>', {driver_name: driverName}, function(res){ $('#driver-content-wrapper').html(res); // 如果有动态加载的组件需要初始化,比如switch-boostrap,在这里执行初始化逻辑 }); } }) </script>
注意:使用该方案需要给新增的
actionGetDriverContent配置访问权限,避免被系统权限拦截。
内容的提问来源于stack exchange,提问作者Даяна Димитрова
相关产品推荐
相关产品推荐

