export DateSelector, fix issue about column.align and filter panel position of the last header cell.

This commit is contained in:
Chen Lily 2024-01-30 11:16:57 +08:00
parent df42221b52
commit 0b897cae8a
8 changed files with 133 additions and 30 deletions

View File

@ -10,6 +10,7 @@ import { GridColumn, GridInputColumn, GridDropdownColumn, GridCheckboxColumn, Gr
import { Popup, createPopup, showAlert, showConfirm } from "./ui/popup"; import { Popup, createPopup, showAlert, showConfirm } from "./ui/popup";
import { createPicture, createAudio, createVideo, createFile } from './ui/media'; import { createPicture, createAudio, createVideo, createFile } from './ui/media';
import { validation, convertCssStyle } from './ui/extension'; import { validation, convertCssStyle } from './ui/extension';
import { createDateInput, formatDate, setDateValue, getDateValue, DateSelector } from './ui/date';
export { export {
createElement, createElement,
@ -40,6 +41,12 @@ export {
createPopup, createPopup,
showAlert, showAlert,
showConfirm, showConfirm,
// dateSelector
createDateInput,
formatDate,
setDateValue,
getDateValue,
DateSelector,
// media // media
createPicture, createPicture,
createAudio, createAudio,

View File

@ -320,7 +320,7 @@
} }
.ui-check-wrapper { .ui-check-wrapper {
display: flex; display: inline-flex;
justify-content: center; justify-content: center;
.ui-check-inner { .ui-check-inner {

71
lib/ui/date.d.ts vendored
View File

@ -1,10 +1,11 @@
/** /**
* *
* @param min * @param min
* @param max * @param max
* @returns * @param element
* @returns
*/ */
export function createDateInput(min?: string, max?: string): HTMLInputElement; export function createDateInput(min?: string, max?: string, element?: HTMLInputElement): HTMLInputElement;
/** /**
* *
@ -36,22 +37,48 @@ export function getDateValue(element: HTMLInputElement, formatter?: (date: Date)
/** 日期选择框类 */ /** 日期选择框类 */
export class DateSelector { export class DateSelector {
/** /**
* * `input[data-type="date"]` <br/><br/>
* @param date * `id`, `class`, `data-min`, `data-max`, `disabled`
* @param dom
* @param trigger `DateSelector`
* @example
* HTML:
* ```html
* <input id="dateFrom" data-type="date" data-min="1980-01-01"/>
* ```
* js:
* ```js
* const libUI = window['lib-ui'];
* const DateSelector = libUI.DateSelector;
* const formatDate = libUI.formatDate;
*
*
* // 解析 document.body 下所有符合条件的元素,转换为日期选择框,第二个参数可选
* DateSelector.resolve(document.body, function (date) {
* console.log(`element(#${this.element.id}), date changed to: ${formatDate(date)}`);
* // 当日期选择改变时控制台将会输出element(#dateFrom), date changed to: 1/30/2024
* });
*
*
* // 在其他地方调用时
* const value = document.querySelector('#dateFrom').value;
* console.log(`dateFrom.value = '${value}', formatted: '${formatDate(value)}'`);
* // 控制台会输出dateFrom.value = '2024-01-30', formatted: '1/30/2024'
* ```
*/ */
onDateChanged?: (date: Date | any) => void; static resolve(dom?: HTMLElement, trigger?: (date: Date) => void): HTMLElement;
/** /**
* *
* @param opts * @param opts
*/ */
constructor(opts: { constructor(opts: {
/** 父容器元素,可以为 `string` 作为选择器 */
parent: HTMLElement | string,
/** 最小可选择日期 */ /** 最小可选择日期 */
minDate?: string, minDate?: string,
/** 最大可选择日期 */ /** 最大可选择日期 */
maxDate?: string, maxDate?: string,
/** 是否启用 */
enabled?: boolean,
/** /**
* *
* @param date * @param date
@ -60,12 +87,40 @@ export class DateSelector {
valueFormatter?: (date: Date) => any valueFormatter?: (date: Date) => any
}); });
/**
*
* @param element
* @returns
*/
create(element?: HTMLInputElement): HTMLInputElement;
/** 获取日期选择框元素 */
get element(): HTMLInputElement;
/** 获取日期选择框是否启用 */
get enabled(): boolean; get enabled(): boolean;
/** 设置日期选择框启用状态 */
set enabled(flag: boolean); set enabled(flag: boolean);
/** 获取设置的日期值,或经过格式化函数返回的值 */
get value(): Date | any; get value(): Date | any;
/** 设置日期值,支持的格式参见 {@linkcode formatDate} */
set value(val: Date | number | string); set value(val: Date | number | string);
/** 获取最小可选择日期 */
get minDate(): string;
/** 设置最小可选择日期 */
set minDate(date: string); set minDate(date: string);
/** 获取最大可选择日期 */
get maxDate(): string;
/** 设置最大可选择日期 */
set maxDate(date: string); set maxDate(date: string);
/**
*
* @param date
* @eventProperty
*/
onDateChanged?: (date: Date | any) => void;
} }

View File

@ -1,7 +1,13 @@
import { createElement } from "../functions"; import { createElement } from "../functions";
export function createDateInput(min, max) { export function createDateInput(min, max, element) {
const date = createElement('input', 'ui-date-cell'); let date;
if (element instanceof HTMLInputElement) {
date = element;
date.classList.add('ui-date-cell');
} else {
date = createElement('input', 'ui-date-cell');
}
date.required = true; date.required = true;
date.type = 'date'; date.type = 'date';
if (min != null) { if (min != null) {
@ -89,16 +95,15 @@ export class DateSelector {
constructor(opts) { constructor(opts) {
opts ??= {}; opts ??= {};
if (typeof opts.parent === 'string') {
opts.parent = document.querySelector(opts.parent);
}
if (!(opts.parent instanceof HTMLElement)) {
throw new Error('no specified parent.');
}
this._var.options = opts; this._var.options = opts;
this._var.parent = opts.parent; }
const el = createDateInput(opts.minDate, opts.maxDate); create(element) {
const opts = this._var.options;
const el = createDateInput(opts.minDate, opts.maxDate, element);
if (element == null) {
el.disabled = opts.enabled === false;
}
el.addEventListener('blur', e => { el.addEventListener('blur', e => {
const date = this._getDate(e.target.valueAsDate); const date = this._getDate(e.target.valueAsDate);
if (date == null) { if (date == null) {
@ -109,9 +114,11 @@ export class DateSelector {
} }
}); });
this._var.el = el; this._var.el = el;
parent.appendChild(el); return el;
} }
get element() { return this._var.el }
get enabled() { return !this._var.el.disabled } get enabled() { return !this._var.el.disabled }
set enabled(flag) { set enabled(flag) {
this._var.el.disabled = flag === false; this._var.el.disabled = flag === false;
@ -122,16 +129,13 @@ export class DateSelector {
setDateValue(this._var.el, val); setDateValue(this._var.el, val);
} }
/** get minDate() { return this._var.el.min }
* @param {string} date
*/
set minDate(date) { set minDate(date) {
this._var.el.min = date; this._var.el.min = date;
this._var.options.minDate = date; this._var.options.minDate = date;
} }
/**
* @param {string} date get maxDate() { return this._var.el.max }
*/
set maxDate(date) { set maxDate(date) {
this._var.el.max = date; this._var.el.max = date;
this._var.options.maxDate = date; this._var.options.maxDate = date;
@ -150,4 +154,23 @@ export class DateSelector {
} }
return null; return null;
} }
static resolve(dom = document.body, trigger) {
const dates = dom.querySelectorAll('input[data-type="date"]');
for (let dat of dates) {
const val = dat.value;
const dateSelector = new DateSelector({
minDate: dat.getAttribute('data-min'),
maxDate: dat.getAttribute('data-max')
});
if (typeof trigger === 'function') {
dateSelector.onDateChanged = date => trigger.call(dateSelector, date);
}
dat.removeAttribute('data-type');
dat.removeAttribute('data-min');
dat.removeAttribute('data-max');
dateSelector.create(dat);
dateSelector.value = val;
}
}
} }

View File

@ -47,11 +47,13 @@ export interface DropdownOptions {
/** 下拉框类 */ /** 下拉框类 */
export class Dropdown { export class Dropdown {
/** /**
* `select` * `select` <br/><br/>
* `value`, `disabled`, `tabIndex`
* @param dom * @param dom
* @param trigger `Dropdown`
* @returns * @returns
*/ */
static resolve(dom?: HTMLElement): HTMLElement; static resolve(dom?: HTMLElement, trigger?: (item: DropdownItem) => void): HTMLElement;
/** /**
* *

View File

@ -560,7 +560,7 @@ export class Dropdown {
} }
} }
static resolve(dom = document.body) { static resolve(dom = document.body, trigger) {
const selects = dom.querySelectorAll('select'); const selects = dom.querySelectorAll('select');
for (let sel of selects) { for (let sel of selects) {
const source = [...sel.children].map(it => { const source = [...sel.children].map(it => {
@ -572,6 +572,9 @@ export class Dropdown {
tabIndex: sel.tabIndex tabIndex: sel.tabIndex
}); });
drop.source = source; drop.source = source;
if (typeof trigger === 'function') {
drop.onSelected = item => trigger.call(drop, item);
}
sel.parentElement.replaceChild(drop.create(), sel); sel.parentElement.replaceChild(drop.create(), sel);
} }
return dom; return dom;

View File

@ -975,6 +975,11 @@ export class Grid {
th.addEventListener('mousedown', e => this._onDragStart(e, col)); th.addEventListener('mousedown', e => this._onDragStart(e, col));
} }
const wrapper = createElement('div'); const wrapper = createElement('div');
if (col.align === 'right') {
wrapper.style.justifyContent = 'flex-end';
} else if (col.align === 'center') {
wrapper.style.justifyContent = 'center';
}
th.appendChild(wrapper); th.appendChild(wrapper);
if (!this.readonly && col.enabled !== false && col.allcheck && isCheckbox) { if (!this.readonly && col.enabled !== false && col.allcheck && isCheckbox) {
const check = createCheckbox({ const check = createCheckbox({
@ -1239,6 +1244,8 @@ export class Grid {
const style = col.styleFilter(item); const style = col.styleFilter(item);
if (style != null) { if (style != null) {
type.setStyle(element, style); type.setStyle(element, style);
} else {
element.style.cssText = '';
} }
} }
if (col.events != null) { if (col.events != null) {
@ -1562,7 +1569,12 @@ export class Grid {
const th = filter.parentElement; const th = filter.parentElement;
const width = th.offsetWidth; const width = th.offsetWidth;
panel.style.top = `${th.offsetHeight + this._var.el.scrollTop}px`; panel.style.top = `${th.offsetHeight + this._var.el.scrollTop}px`;
panel.style.left = (th.offsetLeft + (width > FilterPanelWidth ? width - FilterPanelWidth : 0)) + 'px'; const offsetLeft = th.offsetLeft;
const totalWidth = th.parentElement.offsetWidth;
const left = offsetLeft + FilterPanelWidth > totalWidth ?
totalWidth - FilterPanelWidth :
offsetLeft + (width > FilterPanelWidth ? width - FilterPanelWidth : 0);
panel.style.left = `${left}px`;
// search // search
let searchbox; let searchbox;

View File

@ -1,5 +1,6 @@
{ {
"entryPoints": [ "entryPoints": [
"lib/ui/date.d.ts",
"lib/ui/dropdown.d.ts", "lib/ui/dropdown.d.ts",
"lib/ui/grid/column.d.ts", "lib/ui/grid/column.d.ts",
"lib/ui/grid/grid.d.ts" "lib/ui/grid/grid.d.ts"