下拉 —— 名册一多就变成"在一长串里瞪眼找",而且三种地方三种手感。 * * 用法(在模板里先准备好变量再 include): * $ppName 表单字段名。多选传 'attendees[]';单选传 'owner_id' 等 * $ppPeople 候选的人(Person::roster() 的行,至少要有 id / name) * $ppSelected 已选的 id 数组(单选传 0 或 1 个) * $ppMode 'multi'(默认)| 'single' * $ppOpenBtn 打开按钮文案(默认 multi=「+ 添加人」/ single=「选择」) * $ppTitle 弹窗标题(默认「选择人」) * $ppAllowEmpty 单选模式下是否给一个「不选」选项(筛选表单用;值为 0) * $ppEmptyText 单选且未选时的占位(默认「未选择」) * $ppTip 可选,渲染在按钮下面的一句话 * * ⚠️ 无 JS 时也能用:选项就是弹窗列表里的原生 checkbox / radio, * noscript 样式把弹窗摊平成一个普通列表,提交语义与有 JS 时完全一致。 * * ⚠️ 同一页出现多个选择器时 $ppId 必须不同 —— 片段自己按出现顺序编号, * 调用方不用管(但同一页重复 include 同一份变量也不会撞)。 */ $ppMode = $ppMode ?? 'multi'; $ppPeople = $ppPeople ?? []; $ppSelected = array_map('intval', (array)($ppSelected ?? [])); $ppOpenBtn = $ppOpenBtn ?? ($ppMode === 'single' ? '选择' : '+ 添加人'); $ppTitle = $ppTitle ?? '选择'; $ppEmptyText = $ppEmptyText ?? '未选择'; $ppAllowEmpty = !empty($ppAllowEmpty); // 同一页多个实例要各有一套 id,否则 document.getElementById 全抓到第一个 static $ppSeq = 0; $ppSeq++; $ppId = 'pp' . $ppSeq; $ppIsMulti = $ppMode === 'single' ? false : true; $ppInputType = $ppIsMulti ? 'checkbox' : 'radio'; // ⚠️ 「已选」要按**非零**判断:筛选表单常用 0 表示「全部」,[0] 是个非空数组, // 直接 !$ppSelected 会误判成"选了人",于是「不选」那一项反而不勾。 $ppHasSel = count(array_filter($ppSelected)) > 0; ?>