<div class="form-group">
<label for="c-channel_id" class="control-label col-xs-12 col-sm-2">{:__('Channel_id')}</label>
<div class="col-xs-12 col-sm-8">
<div class="input-group">
<select id="c-channel_id" data-rule="required" class="form-control selectpicker" data-live-search="true" name="row[channel_id]">
{$channelOptions}
</select>
<span class="input-group-btn">
<button class="btn btn-info" type="button" id="btn-channel-sel" title="快速选择"><i class="fa fa-list"></i></button>
</span>
</div>
<div class="c-channel_sel" style="display:none; position: absolute; z-index: 999; width: 100%; box-shadow: 0 5px 15px rgba(0,0,0,0.2); background: #fff; margin-top: 5px; border-radius: 4px;">
<style>
.channel-selector {
display: flex;
border: 1px solid #ddd;
height: 250px;
background: #fff;
overflow-x: auto;
border-radius: 4px;
}
.channel-col {
min-width: 50px;
border-right: 1px solid #eee;
overflow-y: auto;
height: 100%;
padding: 0;
margin: 0;
list-style: none;
flex-shrink: 0;
}
.channel-col:last-child {
border-right: none;
}
.channel-item {
padding: 10px 30px 10px 15px;
cursor: pointer;
border-bottom: 1px solid #f9f9f9;
transition: background-color 0.2s;
display: flex;
align-items: center;
color: #666;
position: relative;
}
.channel-item:hover {
background-color: #f5f5f5;
}
.channel-item.active {
background-color: #18bc9c;
color: #fff;
}
.channel-item.disabled-item {
color: #ccc;
}
.channel-item.disabled-item.active {
background-color: #18bc9c;
color: #fff;
opacity: 0.8;
}
.channel-arrow {
font-size: 12px;
opacity: 0.7;
position: absolute;
right: 10px;
}
.channel-selector-close {
position: absolute;
top: 0;
right: 0;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
background: #e74c3c;
color: #fff;
cursor: pointer;
z-index: 10;
border-bottom-left-radius: 5px;
border-top-right-radius: 4px;
}
.channel-selector-close:hover {
background: #c0392b;
}
</style>
<div class="channel-selector-close" title="关闭"><i class="fa fa-times"></i></div>
<div id="channel-selector-box" class="channel-selector"></div>
<script src="/assets/libs/jquery/dist/jquery.min.js"></script>
<script>
$(function(){
var channelData = {:json_encode($channelArr,JSON_UNESCAPED_UNICODE)};
var currentId = "{$row.channel_id|htmlentities}";
var $box = $('#channel-selector-box');
var $input = $('#c-channel_id');
var $container = $('.c-channel_sel');
var columns = [];
// Toggle visibility
$('#btn-channel-sel').on('click', function() {
$container.toggle();
});
$('.channel-selector-close').on('click', function() {
$container.hide();
});
// Close when clicking outside
$(document).on('click', function(e) {
if (!$(e.target).closest('.c-channel_sel').length && !$(e.target).closest('#btn-channel-sel').length) {
$container.hide();
}
});
// Find path to currentId
function findPath(list, id) {
for(var i=0; i<list.length; i++) {
var item = list[i];
if(item.id == id) {
return [item];
}
if(item.childlist && item.childlist.length > 0) {
var path = findPath(item.childlist, id);
if(path) {
return [item].concat(path);
}
}
}
return null;
}
function renderColumn(list, level, activeItem) {
// Remove subsequent columns
for(var i = columns.length - 1; i >= level; i--) {
columns[i].remove();
columns.pop();
}
if(!list || list.length === 0) return;
var $col = $('<ul class="channel-col"></ul>');
$.each(list, function(index, item) {
var $li = $('<li class="channel-item"></li>');
$li.data('item', item);
var text = item.name;
var hasChild = item.childlist && item.childlist.length > 0;
$li.text(text);
if(hasChild) {
$li.append('<span class="channel-arrow"><i class="fa fa-chevron-right"></i></span>');
}
if(item.disabledId == 1) {
$li.addClass('disabled-item');
}
if(activeItem && activeItem.id == item.id) {
$li.addClass('active');
}
$li.on('click', function() {
if($(this).hasClass('active')) return;
// Handle visual selection
$col.find('.channel-item').removeClass('active');
$(this).addClass('active');
// Handle Logic
if(item.disabledId == 0) {
$input.val(item.id);
$input.trigger('change');
if($input.data('selectpicker')) {
$input.selectpicker('refresh');
}
}
// Render next column
renderColumn(item.childlist || [], level + 1, null);
});
$col.append($li);
});
$box.append($col);
columns.push($col);
// Scroll active into view
var $active = $col.find('.active');
if($active.length) {
var top = $active.position().top;
// $col.scrollTop(top);
}
// Scroll container to far right to show new column
setTimeout(function() {
$box.animate({scrollLeft: $box[0].scrollWidth}, 300);
}, 50);
}
// Initialize
var path = [];
if(currentId) {
path = findPath(channelData, currentId);
}
if(!path && channelData.length > 0) {
// Default to first item if no selection
path = [channelData[0]];
// Also update input if allowed
if(channelData[0].disabledId == 0) {
$input.val(channelData[0].id);
$input.trigger('change');
}
}
// Render path recursively
if(path) {
var currentList = channelData;
for(var i=0; i<path.length; i++) {
var item = path[i];
renderColumn(currentList, i, item);
currentList = item.childlist || [];
}
var lastItem = path[path.length-1];
if(lastItem.childlist && lastItem.childlist.length > 0) {
renderColumn(lastItem.childlist, path.length, null);
}
} else {
renderColumn(channelData, 0, null);
}
});
</script>
</div>
</div>
</div>
app\admin\controller\cms\Archives;
100行 用于添加页面
$channelArr=$tree->getTreeArray(0,"",$disabledIds);
$this->view->assign('channelArr', $channelArr);
283行 用于编辑页面
$channelArr=$tree->getTreeArray(0,"",$disabledIds);
$this->view->assign('channelArr', $channelArr);
fast\Tree 加个参数
public function getTreeArray($myid, $itemprefix = '',$disabledIds=[])
$value['spacer'] = $spacer;$value['disabledId']=in_array($value['id'],$disabledIds)?1:0;
$data[$n] = $value;
发表评论 取消回复