image.png
这是预览图,然后是双击后,弹出选择的界面。
image.png

从途中可以看出,支持双击选择复选框,支持多选,指定的字典值,后面还可以添加text的文本输入框。
支持的Layer版本比较低,主要适用于老的没人维护的系统。
代码如下:

<!DOCTYPE html>


<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>可配置文本输入框选项的选择组件</title>
<!-- 仅保留必要依赖 -->
<script src="https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js"></script>
<script src="http://localhost:8015/views/js/layer/layer.js"></script>

<style>
    /* 基础样式 */
    body {
        font-family: "Microsoft YaHei", Arial, sans-serif;
        background-color: #f5f5f5;
        padding: 40px;
        color: #333;
    }
    
    .container {
        max-width: 800px;
        margin: 0 auto;
        background-color: white;
        padding: 30px;
        border-radius: 5px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    }
    
    h2 {
        color: #333;
        border-bottom: 1px solid #eee;
        padding-bottom: 15px;
        margin-top: 0;
    }
    
    /* 表单样式 */
    .form-group {
        margin-bottom: 25px;
    }
    
    
    /* 选择器div样式 */
    .selector-div {
        min-height: 40px;
        padding: 10px 12px;
        border: 1px solid #ddd;
        border-radius: 4px;
        cursor: pointer;
        transition: all 0.2s ease;
    }
    
    .selector-div:hover {
        border-color: #66afe9;
        box-shadow: 0 0 0 2px rgba(102, 175, 233, 0.2);
    }
    
    .selector-div.empty {
        color: #999;
    }
    
    /* 结果标签样式 */
    .result-tag {
        display: inline-block;
        background-color: #e6f7ff;
        color: #1890ff;
        padding: 3px 10px;
        border-radius: 12px;
        margin-right: 5px;
        margin-bottom: 5px;
        font-size: 12px;
    }
    
    .input-text {
        color: #ff6b6b;
        font-style: italic;
    }
    
    /* 复选框样式 */
    .checkbox-group {
        margin-bottom: 20px;
    }
    
    .checkbox-item {
        display: block;
        margin-right: 15px;
        margin-bottom: 10px;
        cursor: pointer;
        padding: 5px 0;
    }
    
    .checkbox-item input[type="checkbox"] {
        margin-right: 5px;
    }
    
    .option-input {
        margin-left: 5px;
        padding: 3px 5px;
        border: 1px solid #ddd;
        border-radius: 3px;
        width: 200px;
    }
    
    /* 按钮样式 */
    .btn {
        display: inline-block;
        padding: 6px 12px;
        margin-bottom: 0;
        font-size: 14px;
        font-weight: 400;
        line-height: 1.42857143;
        text-align: center;
        white-space: nowrap;
        vertical-align: middle;
        cursor: pointer;
        background-image: none;
        border: 1px solid transparent;
        border-radius: 4px;
        transition: background-color 0.2s ease;
    }
    
    .btn-primary {
        color: #fff;
        background-color: #337ab7;
        border-color: #2e6da4;
    }
    
    .btn-primary:hover {
        background-color: #286090;
        border-color: #204d74;
    }
    
    .btn-default {
        color: #333;
        background-color: #fff;
        border-color: #ccc;
    }
    
    .btn-default:hover {
        color: #333;
        background-color: #e6e6e6;
        border-color: #adadad;
    }
    
    /* 提交结果区域 */
    .result-area {
        margin-top: 30px;
        padding: 15px;
        background-color: #f9f9f9;
        border-radius: 4px;
    }
    
    .result-area h3 {
        margin-top: 0;
        color: #666;
    }
    
    pre {
        margin: 0;
        padding: 10px;
        background-color: #f0f0f0;
        border-radius: 4px;
        overflow-x: auto;
        font-size: 13px;
    }
    
    /* 提示文本 */
    .hint-text {
        font-size: 12px;
        color: #999;
        margin-top: 5px;
    }
</style>


<div class="container">
    <h2>双击选择组件示例(可配置文本输入框)</h2>
    
    <form id="myForm">
        <!-- 隐藏的输入框用于表单提交 -->
        <input type="hidden" id="selectedValues" name="selectedValues">
        
        <div class="form-group">
            <label>声音类型选择</label>
            <!-- 这是唯一的div元素 -->
            <div id="soundSelector" class="selector-div empty">双击选择声音类型...</div>
            <div class="hint-text">提示:双击区域打开选择窗口,带输入框的选项可填写补充信息</div>
        </div>
        
        <button type="submit" class="btn btn-primary">
            提交表单
        </button>
    </form>
    
    <div class="result-area">
        <h3>表单提交结果</h3>
        <pre id="submitResult"></pre>
    </div>
</div>

<script>
// 声音类型数据
var soundTypeData = {
    "1":["1","正常"],
    "2":["2","哮鸣音"],
    "3":["3","未查"],
    "4":["4","干性啰音"],
    "5":["5","未见异常"],
    "6":["6","湿性啰音"],
    "7":["7","呼吸音减弱"],
    "8":["8","干湿性啰音"],
    "9":["9","呼吸音粗糙"],
    "10":["10","其他"]
};

// 转换数据格式为组件需要的格式
function convertDataFormat(rawData, textInputValues = []) {
    return Object.keys(rawData).map(key => {
        const [value, text] = rawData[key];
        return {
            key: key,
            value: value,
            text: text,
            // 判断当前选项是否需要显示文本输入框
            needInput: textInputValues.includes(value)
        };
    });
}

// 单div双击选择组件
(function($) {
    // 检查依赖
    if (typeof layer === 'undefined') {
        console.error('请先引入layer v1.9.3库');
        return;
    }
    
    // 存储实例数据的命名空间
    var dataNamespace = 'doubleClickSelector';
    
    // 定义组件
    $.fn.doubleClickSelector = function(options) {
        // 默认配置
        var defaults = {
            title: '请选择',          // 弹窗标题
            emptyText: '双击选择...', // 空状态文本
            width: '550px',           // 弹窗宽度
            height: 'auto',           // 弹窗高度
            data: [],                 // 选项数据
            hiddenInputId: null,      // 关联的隐藏输入框ID
            initialValues: [],        // 初始值 [{value: '', inputText: ''}]
            textInputValues: []       // 需要显示文本输入框的value数组
        };
        
        // 合并配置
        var settings = $.extend({}, defaults, options);
        
        // 确保数据格式正确
        if (!Array.isArray(settings.data) || settings.data.length === 0) {
            console.error('请提供有效的选项数据');
            return this;
        }
        
        // 为每个元素初始化组件
        return this.each(function() {
            var $element = $(this);
            
            // 初始化实例数据
            var instanceData = {
                selectedItems: [...settings.initialValues] // 存储选中项,包含value和inputText
            };
            $element.data(dataNamespace, instanceData);
            
            // 存储配置
            $element.data('doubleClickSelectorSettings', settings);
            
            // 初始化DOM和事件
            function init() {
                // 设置初始状态
                $element.addClass('selector-div');
                renderSelected();
                
                // 绑定双击事件
                $element.dblclick(openSelector);
                
                // 同步初始值到隐藏输入框
                if (settings.hiddenInputId) {
                    syncToHiddenInput();
                }
            }
            
            // 打开选择窗口
            function openSelector() {
                var data = $element.data(dataNamespace);
                
                // 构建选项HTML
                var optionsHtml = '';
                settings.data.forEach(function(item, index) {
                    var isSelected = data.selectedItems.some(selected => selected.value === item.value);
                    // 找到已保存的输入文本
                    var inputText = '';
                    if (item.needInput) {
                        var selectedItem = data.selectedItems.find(selected => selected.value === item.value);
                        inputText = selectedItem ? selectedItem.inputText || '' : '';
                    }
                    
                    // 对于需要输入框的选项,添加文本输入框
                    var inputHtml = item.needInput ? 
                        `<input type="text" class="option-input" placeholder="请输入补充信息" value="${inputText}">` : '';
                    
                    optionsHtml += `
                        <div class="checkbox-item">
                            <input type="checkbox" name="multiselectOptions" id="opt${index}" 
                                   value="${item.value}" data-need-input="${item.needInput}" ${isSelected ? 'checked' : ''}>
                            <label for="opt${index}">${item.text}</label>
                            ${inputHtml}
                        </div>
                    `;
                });
                
                // 弹层内容
                var layerContent = `
                    <div style="padding: 20px;">
                        <h3 style="margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; font-size: 16px;">${settings.title}</h3>
                        <div class="checkbox-group">${optionsHtml}</div>
                        <div style="text-align: right; margin-top: 20px;">
                            <button class="cancel-btn btn btn-default" style="margin-right: 10px;">
                                取消
                            </button>
                            <button class="confirm-btn btn btn-primary">
                                确认选择
                            </button>
                        </div>
                    </div>
                `;
                
                // 打开弹层
                var index = layer.open({
                    type: 1,
                    title: settings.title,
                    area: [settings.width, settings.height],
                    content: layerContent,
                    shade: 0.3,
                    scrollbar: false,
                    success: function(layero) {
                        // 为需要输入框的复选框添加事件:勾选时聚焦到输入框
                        layero.find('input[type="checkbox"][data-need-input="true"]').change(function() {
                            if ($(this).is(':checked')) {
                                $(this).closest('.checkbox-item').find('.option-input').focus();
                            }
                        });
                        
                        // 绑定确认按钮事件
                        layero.find('.confirm-btn').click(function() {
                            // 收集选中值
                            var newSelected = [];
                            layero.find('input[name="multiselectOptions"]:checked').each(function() {
                                var $checkbox = $(this);
                                var value = $checkbox.val();
                                var needInput = $checkbox.data('need-input');
                                var inputText = '';
                                
                                // 如果是需要输入框的选项,获取输入框的值
                                if (needInput) {
                                    inputText = $checkbox.closest('.checkbox-item').find('.option-input').val() || '';
                                }
                                
                                newSelected.push({
                                    value: value,
                                    inputText: inputText
                                });
                            });
                            
                            // 更新实例数据
                            data.selectedItems = newSelected;
                            $element.data(dataNamespace, data);
                            
                            // 更新显示
                            renderSelected();
                            
                            // 同步到隐藏输入框
                            syncToHiddenInput();
                            
                            // 关闭弹层
                            layer.close(index);
                        });
                        
                        // 绑定取消按钮事件
                        layero.find('.cancel-btn').click(function() {
                            layer.close(index);
                        });
                        
                        // 点击标签选中复选框
                        layero.find('.checkbox-item label').click(function(e) {
                            var checkbox = $(this).prev('input');
                            checkbox.prop('checked', !checkbox.prop('checked'));
                            // 如果是需要输入框的选项且被勾选,聚焦到输入框
                            if (checkbox.data('need-input') && checkbox.is(':checked')) {
                                $(this).next('.option-input').focus();
                            }
                            e.preventDefault();
                        });
                    }
                });
            }
            
            // 渲染选中项
            function renderSelected() {
                var data = $element.data(dataNamespace);
                
                if (data.selectedItems.length > 0) {
                    $element.removeClass('empty');
                    var html = '';
                    data.selectedItems.forEach(function(selected) {
                        // 找到对应的文本
                        var item = settings.data.find(item => item.value === selected.value);
                        if (item) {
                            // 如果是需要输入框的选项且有输入内容,显示输入的内容
                            var displayText = item.text;
                            if (item.needInput && selected.inputText) {
                                displayText += `(<span class="input-text">${selected.inputText}</span>)`;
                            }
                            html += `<span class="result-tag">${displayText}</span>`;
                        }
                    });
                    $element.html(html);
                } else {
                    $element.addClass('empty');
                    $element.html(settings.emptyText);
                }
            }
            
            // 同步到隐藏输入框,用于表单提交
            function syncToHiddenInput() {
                if (settings.hiddenInputId) {
                    var data = $element.data(dataNamespace);
                    var $hiddenInput = $('#' + settings.hiddenInputId);
                    if ($hiddenInput.length) {
                        // 转换为JSON字符串存储,包含value和inputText
                        $hiddenInput.val(JSON.stringify(data.selectedItems));
                    }
                }
            }
            
            // 初始化组件
            init();
        });
    };
    
    // 定义获取数据的方法
    $.fn.getSelectorData = function() {
        var data = this.data(dataNamespace);
        return data ? [...data.selectedItems] : [];
    };
    
    // 定义设置数据的方法
    $.fn.setSelectorData = function(items) {
        if (!Array.isArray(items)) return this;
        
        return this.each(function() {
            var $element = $(this);
            var data = $element.data(dataNamespace);
            if (!data) return;
            
            // 获取当前组件的配置
            var settings = $element.data('doubleClickSelectorSettings');
            if (!settings) return;
            
            // 过滤并格式化数据
            data.selectedItems = items.filter(item => {
                return settings.data.some(option => option.value === item.value);
            }).map(item => ({
                value: item.value,
                inputText: item.inputText || ''
            }));
            
            $element.data(dataNamespace, data);
            
            // 更新显示
            renderSelected();
            
            // 同步到隐藏输入框
            if (settings.hiddenInputId) {
                var $hiddenInput = $('#' + settings.hiddenInputId);
                if ($hiddenInput.length) {
                    $hiddenInput.val(JSON.stringify(data.selectedItems));
                }
            }
            
            // 渲染选中项的内部函数
            function renderSelected() {
                if (data.selectedItems.length > 0) {
                    $element.removeClass('empty');
                    var html = '';
                    data.selectedItems.forEach(function(selected) {
                        var item = settings.data.find(item => item.value === selected.value);
                        if (item) {
                            var displayText = item.text;
                            if (item.needInput && selected.inputText) {
                                displayText += `(<span class="input-text">${selected.inputText}</span>)`;
                            }
                            html += `<span class="result-tag">${displayText}</span>`;
                        }
                    });
                    $element.html(html);
                } else {
                    $element.addClass('empty');
                    $element.html(settings.emptyText);
                }
            }
        });
    };
    
})(jQuery);

// 使用组件
$(document).ready(function() {
    // 配置需要显示文本输入框的选项值
    var textInputValues = ["4", "6", "10"]; // 干性啰音、湿性啰音、其他
    
    // 转换数据格式,传入需要显示输入框的value数组
    var formattedData = convertDataFormat(soundTypeData, textInputValues);
    
    // 初始化选择器组件
    var $selector = $('#soundSelector').doubleClickSelector({
        title: '选择声音类型',
        emptyText: '双击选择声音类型...',
        hiddenInputId: 'selectedValues',
        textInputValues: textInputValues, // 传递需要显示输入框的value数组
        // 初始值示例
        initialValues: [
            { value: '1', inputText: '' }, // 正常(无输入框)
            { value: '4', inputText: '左侧明显' }, // 干性啰音(有输入框)
            { value: '10', inputText: '轻微杂音' } // 其他(有输入框)
        ],
        data: formattedData
    });
    
    // 表单提交处理
    $('#myForm').submit(function(e) {
        e.preventDefault();
        
        // 方式1: 通过隐藏输入框获取值
        var hiddenInputValue = $('#selectedValues').val();
        
        // 方式2: 通过组件方法获取值
        var componentValue = $selector.getSelectorData();
        
        // 显示提交结果
        $('#submitResult').text(`

需要显示输入框的value: [${textInputValues.join(', ')}]
隐藏输入框的值: ${hiddenInputValue || '空'}
组件方法获取的值: ${JSON.stringify(componentValue, null, 2)}
提交时间: ${new Date().toLocaleString()}

        `);
    });
});