UNPKG

@wiajs/ui

Version:

wia ui packages

312 lines (311 loc) 10 kB
/** @jsxImportSource @wiajs/core */ /** * editTable 中的chip模块 */ import { jsx as _jsx, jsxs as _jsxs } from "@wiajs/core/jsx-runtime"; import { log as Log } from '@wiajs/util'; const log = Log({ m: 'chip' }) // 创建日志实例 ; /** * @typedef {import('./index').default} EditTable */ /** * @typedef {import('jquery')} $ * @typedef {JQuery} Dom */ /** * 填充Chip * @param {EditTable} _ - 组件实例 * @param {*[][]} value - 二维数组 * @param {HTMLElement} td - td * @param {boolean} [read] - 只读 * @param {number} [idx] - Kv编辑数据索引或表格编辑字段索引 * @param {number} [idy] - 表格编辑时的数据行索引 */ function fillChip(_, value, td, read = false, idx = 0, idy = 0) { try { const $td = $(td); $td.data('idx', idx) // td 保存 EditTable 的数据索引 ; $td.data('idy', idy) // td 保存 EditTable 的数据行索引 ; // @ts-expect-error td._value = value // 原值 ; $td.click(chipClick); fillTd(_, td, value, read, idx, idy); } catch (e) { log.err(e, 'fillChip'); } } /** * 填充 td 内容 * @param {*} _ - editDable 实例 * @param {*} td * @param {*} value * @param {boolean} read * @param {number} idx - EditTable 数组数据索引 * @param {number} [idy] - EditTable 数组数据索引 */ function fillTd(_, td, value, read, idx, idy = 0) { try { const { fields, opt } = _; const r = fields[idx] || {}; const { field } = r; if (!r.color) r.color = [ 'pink', 'yellow', 'red' ]; td = $(td); td.data('field', field) // td 保存 EditTable 的字段名 ; const chip = $(/*#__PURE__*/ _jsx("div", { class: 'etChip' })).appendTo(td); _.chip = chip; // 封装层,超出左右滑动 const wrap = $(/*#__PURE__*/ _jsx("div", { class: "chip-wrap" })).appendTo(chip); let vs = value || []; // @ts-expect-error if (!Array.isArray(vs[0])) vs = vs.map((v)=>[ v, v ]) // 转为二维数组 ; fillItem(vs, wrap, r); // 新增 if (!read) { wrap.append(/*#__PURE__*/ _jsxs("div", { class: "_add", children: [ /*#__PURE__*/ _jsx("input", { name: `${field}-chip-add`, class: "_addVal", type: "hidden" }), /*#__PURE__*/ _jsx("div", { class: "_box", children: /*#__PURE__*/ _jsx("div", { name: "btnAdd", class: "_btn" }) }) ] })); if (_.Autocomplete) { const { source, field, addUrl } = r; const { placeholder } = r; if (!r.option) r.option = []; // 创建Ac const dvAc = $(/*#__PURE__*/ _jsx("div", { class: "autocomplete" })).appendTo(td); dvAc.hide(); // tx.addClass('dy-input') const ac = new _.Autocomplete(_.page, { el: dvAc, // name: `${field}-chip-ac`, // 不纳入getVal placeholder, data: r.option, // refEl: [el.dom], // 关联元素,点击不关闭列表,否则会关闭列表 source, addUrl }); ac.on('blur', ()=>{ // 选择赋值在 blur 后 setTimeout(()=>{ const val = ac.val(); const key = ac.key(); let vs; if (key && val) vs = [ [ key, val ] ]; else if (val) vs = [ [ val, val ] ]; fillItem(vs, wrap, { ...r, add: true }); chip.show(); ac.hide(); }, 200); }); ac.hide(); } if (!opt.edit) wrap.find('._add').hide(); } } catch (e) { log.err(e, 'fillTd'); } } /** * * @param {*[][]} vs * @param {Dom} wrap * @param {{field: string, color: string[], maxWord: number, add: boolean}} opts */ function fillItem(vs, wrap, opts) { try { if (!vs?.length) return; const { color, add, maxWord = 6 } = opts; if (add) addItem(vs, wrap, opts); // @ts-expect-error vs = vs.map((v, i)=>{ const clr = color?.[i % color.length] || 'pink'; const media = firstLetter(v[1], true) // 颜色 ; let val = v[1]; if (val.length > maxWord) val = val.substr(0, maxWord); return { media, color: clr, key: v[0], val }; }); const htm = vs?.map((v)=>{ const rt = /*#__PURE__*/ _jsxs("div", { class: `chip ${add ? '_addChip' : ''}`, "data-key": v.key, "data-val": v.val, children: [ /*#__PURE__*/ _jsx("div", { class: `chip-media bg-color-${v.color}`, children: v.media }), /*#__PURE__*/ _jsx("div", { class: "chip-label", children: v.val }), /*#__PURE__*/ _jsx("a", { class: "chip-delete" }) ] }); return rt // + v ; }); const addBtn = wrap.find('._add'); if (addBtn?.length) addBtn.before(htm); else wrap.append(htm); } catch (e) { log.err(e, 'addItem'); } } /** * 添加新增项到 input * @param {*[][]} vs * @param {Dom} wrap * @param {{field: string, color: string[], maxWord: number, add: boolean}} opts */ function addItem(vs, wrap, opts) { try { const td = wrap.upper('td'); const input = wrap.find('input._addVal'); if (!input.dom._add) input.dom._add = new Set(); const { _add, _del } = input.dom; // 保存新增 for (const v of vs)_add.add(v); if (_add?.size || _del?.size) td.addClass('etChange'); else td.removeClass('etChange'); } catch (e) { log.err(e, 'addItem'); } } /** * 删除 * @param {Dom} chip - */ function delItem(chip) { try { if (chip.dom) { const td = chip.upper('td'); const input = td.find('input._addVal'); const { _add } = input.dom; let { _del } = input.dom; const key = chip.data('key'); const val = chip.data('val'); // 新增附件删除 if (chip.hasClass('_addChip')) { for (const item of _add)if (Array.isArray(item) && item[0] === key) _add.delete(item); } else { if (!_del) { _del = new Set(); input.dom._del = _del; } _del.add([ key, val ]); } chip.remove(); if (_add?.size || _del?.size) td.addClass('etChange'); else td.removeClass('etChange'); } } catch (e) { log.err(e, 'delItem'); } } /** * 点击tr、td 浏览大图或删除附件 * @param {*} ev */ async function chipClick(ev) { try { const btnAdd = $(ev).upper('._btn'); if (btnAdd.dom) { const td = btnAdd.upper('td'); const chip = td.find('.etChip'); chip?.hide(); const dvAc = td.find('.autocomplete'); const ac = dvAc.dom?._wiaAutocomplete; ac?.show(); ac?.focus() // 自动触发下拉 ; } else { const btnDel = $(ev).upper('.chip-delete'); if (btnDel.dom) { // 删除 const chip = btnDel.upper('.chip'); delItem(chip); } } } catch (e) { log.err(e, 'chipClick'); } } /** * * @param {*} tb */ function edit(tb) { const wrap = tb.find('.chip-wrap'); wrap.find('._add').show(); } /** * * @param {*} tb */ function view(tb) { const wrap = tb.find('.chip-wrap'); wrap.find('._add').hide(); } /** * 提取中文字符的拼音首字母 * @param {string} ch - 输入字符,仅取首字符 * @param {boolean} upper - 是否返回大写,默认 false * @return {string} 首字母,无效输入返回空 */ function firstLetter(ch, upper = false) { if (!ch) return ''; const t = ch[0]; if (/^[a-zA-Z0-9]$/.test(t)) return upper ? t.toUpperCase() : t.toLowerCase(); const letters = 'ABCDEFGHJKLMNOPQRSTWXYZ'.split(''); const bases = '阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀'.split(''); for(let i = 0; i < letters.length; i++){ if (t.localeCompare(bases[i]) >= 0 && (i === letters.length - 1 || t.localeCompare(bases[i + 1]) < 0)) { return upper ? letters[i] : letters[i].toLowerCase(); } } return ''; } export { edit, fillChip, view };