[task-419] [int]

This commit is contained in:
fenris 2025-10-28 00:25:20 +01:00
parent 7a5aeb3ff3
commit 1c8d3d0725
8 changed files with 281 additions and 204 deletions

View file

@ -101,7 +101,7 @@ a:hover
button
{
padding: 8px;
padding: 4px 8px;
text-transform: uppercase;
cursor: pointer;

View file

@ -0,0 +1,164 @@
/*
This file is part of »dali«.
Copyright 2025 'kcf' <fenris@folksprak.org>
»dali« is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
»dali« is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with »dali«. If not, see <http://www.gnu.org/licenses/>.
*/
namespace _dali.widgets
{
/**
*/
export class class_widget_special_number_input
implements lib_plankton.zoo_widget.interface_widget
{
/**
*/
private action_change : ((int) => Promise<void>);
/**
*/
private label : (null | string);
/**
*/
private minimum : (null | int);
/**
*/
private maximum : (null | int);
/**
*/
private value : int;
/**
*/
public constructor(
{
"label": label = null,
"minimum": minimum = null,
"maximum": maximum = null,
"initial_value": initial_value = 0,
"action_change": action_change = ((value) => Promise.resolve<void>(undefined)),
}
:
{
label ?: (null | string);
minimum ?: (null | int);
maximum ?: (null | int);
initial_value ?: int;
action_change ?: ((int) => Promise<void>);
}
=
{
}
)
{
this.label = label;
this.minimum = minimum;
this.maximum = maximum;
this.value = initial_value;
this.action_change = action_change;
}
/**
* [implementation]
*/
public async load(
target_element : HTMLElement
)
: Promise<void>
{
const dom_dummy = document.createElement("div");
dom_dummy.innerHTML = await _dali.helpers.template_coin(
"widget-special_number_input",
"main",
{
"label": this.label,
}
);
const dom_input : HTMLInputElement = (dom_dummy.querySelector(".widget-special_number_input-input > input") as HTMLInputElement);
// listeners
{
dom_input.addEventListener(
"change",
() => {
this.value = parseInt(dom_input.value);
if (
((this.minimum === null) || (this.value >= this.minimum))
&&
((this.maximum === null) || (this.value <= this.maximum))
)
{
this.action_change(this.value);
}
else
{
// do nothing
}
}
);
dom_dummy.querySelector(".widget-special_number_input-prev").addEventListener(
"click",
() => {
if ((this.minimum === null) || (this.value > this.minimum))
{
this.value -= 1;
dom_input.value = this.value.toFixed(0);
this.action_change(this.value);
}
else
{
// do nothing
}
}
);
dom_dummy.querySelector(".widget-special_number_input-next").addEventListener(
"click",
() => {
if ((this.maximum === null) || (this.value < this.maximum))
{
this.value += 1;
dom_input.value = this.value.toFixed(0);
this.action_change(this.value);
}
else
{
// do nothing
}
}
);
}
dom_input.value = this.value.toFixed(0);
target_element.appendChild(dom_dummy.querySelector(".widget-special_number_input"));
}
}
}

View file

@ -0,0 +1,8 @@
<div class="widget-special_number_input">
<label class="widget-special_number_input-label">{{label}}</label>
<div class="widget-special_number_input-input">
<button class="widget-special_number_input-prev">&#x25C2;</button>
<input type="text" pattern="-?[0-9]+"/>
<button class="widget-special_number_input-next">&#x25B8;</button>
</div>
</div>

View file

@ -571,19 +571,6 @@ namespace _dali.widgets.weekview
}
/**
*/
private async update_controls(
) : Promise<void>
{
const context : Element = this.container;
(context.querySelector(".weekview-control-year input") as HTMLInputElement).value = this.year.toFixed(0);
(context.querySelector(".weekview-control-week input") as HTMLInputElement).value = this.week.toFixed(0);
(context.querySelector(".weekview-control-count input") as HTMLInputElement).value = this.count.toFixed(0);
(context.querySelector(".weekview-control-vertical input") as HTMLInputElement).checked = this.vertical;
}
/**
*/
private async update_table(
@ -881,169 +868,91 @@ namespace _dali.widgets.weekview
"widget-weekview",
"main",
{
"label_control_year": lib_plankton.translate.get("widget.weekview.controls.year"),
"label_control_week": lib_plankton.translate.get("widget.weekview.controls.week"),
"label_control_count": lib_plankton.translate.get("widget.weekview.controls.count"),
"label_control_vertical": lib_plankton.translate.get("widget.weekview.controls.vertical"),
"label_control_apply": lib_plankton.translate.get("widget.weekview.controls.apply"),
}
);
this.container = target_element.querySelector(".weekview");
// controls
// control:year
{
// direct inputs
{
[
{
"name": "year",
"selector": ".weekview-control-year input",
"retrieve": element => parseInt(element.value),
"write": x => {this.year = x;}
},
{
"name": "week",
"selector": ".weekview-control-week input",
"retrieve": element => parseInt(element.value),
"write": x => {this.week = x;}
},
{
"name": "count",
"selector": ".weekview-control-count input",
"retrieve": element => parseInt(element.value),
"write": x => {this.count = x;}
},
{
"name": "vertical",
"selector": ".weekview-control-vertical input",
"retrieve": element => element.checked,
"write": x => {this.vertical = x;}
},
].forEach(
(entry) => {
const element : HTMLInputElement = (target_element.querySelector(entry.selector) as HTMLInputElement);
element.addEventListener(
"change",
async (event) => {
event.preventDefault();
const value : unknown = entry.retrieve(element);
entry.write(value);
await this.update_table();
await this.update_entries();
}
);
}
);
}
// buttons
{
// year
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_special_number_input(
{
/**
* @todo limit
*/
target_element.querySelector(".weekview-control-year-prev").addEventListener(
"click",
async () => {
this.year -= 1;
await this.update_controls();
await this.update_table();
await this.update_entries();
}
);
/**
* @todo limit
*/
target_element.querySelector(".weekview-control-year-next").addEventListener(
"click",
async () => {
this.year += 1;
await this.update_controls();
await this.update_table();
await this.update_entries();
}
);
"label": lib_plankton.translate.get("widget.weekview.controls.year"),
"minimum": 1900,
"maximum": 2500,
"initial_value": this.year,
"action_change": async (value) => {
this.year = value;
await this.update_table();
await this.update_entries();
},
}
// week
{
target_element.querySelector(".weekview-control-week-prev").addEventListener(
"click",
async () => {
if (this.week >= 1)
{
this.week -= 1;
}
else
{
this.year -= 1;
/**
* @todo get correct week
*/
this.week = 51;
}
await this.update_controls();
await this.update_table();
await this.update_entries();
}
);
target_element.querySelector(".weekview-control-week-next").addEventListener(
"click",
async () => {
/**
* @todo correct limit
*/
if (this.week <= 51)
{
this.week += 1;
}
else
{
this.year += 1;
this.week = 1;
}
await this.update_controls();
await this.update_table();
await this.update_entries();
}
);
}
// count
{
target_element.querySelector(".weekview-control-count-prev").addEventListener(
"click",
async () => {
if (this.count >= 2)
{
this.count -= 1;
await this.update_controls();
await this.update_table();
await this.update_entries();
}
else
{
// do nothing
}
}
);
target_element.querySelector(".weekview-control-count-next").addEventListener(
"click",
async () => {
if (this.count <= 6)
{
this.count += 1;
await this.update_controls();
await this.update_table();
await this.update_entries();
}
else
{
// do nothing
}
}
);
}
}
);
await widget.load(target_element.querySelector(".weekview-controls"));
}
await this.update_controls();
// control:week
{
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_special_number_input(
{
"label": lib_plankton.translate.get("widget.weekview.controls.week"),
"minimum": 1,
/**
* @todo correct
*/
"maximum": 53,
"initial_value": this.week,
"action_change": async (value) => {
this.week = value;
await this.update_table();
await this.update_entries();
},
}
);
await widget.load(target_element.querySelector(".weekview-controls"));
}
// control:count
/*
{
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_special_number_input(
{
"label": lib_plankton.translate.get("widget.weekview.controls.count"),
"minimum": 2,
"maximum": 6,
"initial_value": this.count,
"action_change": async (value) => {
this.count = value;
await this.update_table();
await this.update_entries();
},
}
);
await widget.load(target_element.querySelector(".weekview-controls"));
}
*/
// control:vertical
{
const dom_dummy : HTMLElement = document.createElement("div");
dom_dummy.innerHTML = await _dali.helpers.template_coin(
"widget-weekview",
"control-vertical",
{
"label": lib_plankton.translate.get("widget.weekview.controls.vertical"),
}
);
const dom_input : HTMLInputElement = (dom_dummy.querySelector("input") as HTMLInputElement);
dom_input.addEventListener(
"change",
async () => {
event.preventDefault();
const value : boolean = dom_input.checked;
this.vertical = value;
await this.update_table();
await this.update_entries();
}
);
dom_input.checked = this.vertical;
target_element.querySelector(".weekview-controls").appendChild(dom_dummy.querySelector(".weekview-control-vertical"));
}
this.container = target_element.querySelector(".weekview");
await this.update_table();
await this.update_entries();

View file

@ -2,7 +2,7 @@
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
flex-wrap: nowrap;
justify-content: right;
margin-bottom: 12px;
@ -16,11 +16,23 @@
flex-grow: 0;
flex-shrink: 1;
min-width: 80px;
margin: 0 0 0 8px;
}
.weekview-controls .widget-special_number_input
{
flex-basis: 0;
flex-grow: 0;
flex-shrink: 1;
min-width: 140px;
margin: 0 12px;
margin: 0 0 0 8px;
}
.weekview-control-label
,
.weekview-controls .widget-special_number_input-label
{
display: block;
@ -35,7 +47,7 @@
display: inline-block;
}
.weekview-control input
.weekview-controls .widget-special_number_input input
{
max-width: 40px;
}

View file

@ -0,0 +1,6 @@
<div class="weekview-control weekview-control-vertical">
<label class="weekview-control-label">{{label}}</label>
<div class="weekview-control-input">
<input type="checkbox"/>
</div>
</div>

View file

@ -1,35 +1,5 @@
<div class="weekview">
<div class="weekview-controls">
<div class="weekview-control weekview-control-year">
<label class="weekview-control-label">{{label_control_year}}</label>
<div class="weekview-control-input">
<button class="weekview-control-year-prev">&#x25C2;</button>
<input type="text"/>
<button class="weekview-control-year-next">&#x25B8;</button>
</div>
</div>
<div class="weekview-control weekview-control-week">
<label class="weekview-control-label">{{label_control_week}}</label>
<div class="weekview-control-input">
<button class="weekview-control-week-prev">&#x25C2;</button>
<input type="text"/>
<button class="weekview-control-week-next">&#x25B8;</button>
</div>
</div>
<div class="weekview-control weekview-control-count">
<label class="weekview-control-label">{{label_control_count}}</label>
<div class="weekview-control-input">
<button class="weekview-control-count-prev">&#x25C2;</button>
<input type="text"/>
<button class="weekview-control-count-next">&#x25B8;</button>
</div>
</div>
<div class="weekview-control weekview-control-vertical">
<label class="weekview-control-label">{{label_control_vertical}}</label>
<div class="weekview-control-input">
<input type="checkbox"/>
</div>
</div>
</div>
<div class="weekview-table">
<table>

View file

@ -31,6 +31,7 @@ ${dir_build}/index.html: \
.PHONY: templates
templates: \
templates-widgets-login \
templates-widgets-special_number_input \
templates-widgets-sources \
templates-widgets-listview \
templates-widgets-weekview \
@ -45,6 +46,13 @@ templates-widgets-login: \
@ ${cmd_mkdir} ${dir_build}/templates/widget-login
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/login/templates/* ${dir_build}/templates/widget-login/
.PHONY: templates-widgets-special_number_input
templates-widgets-special_number_input: \
$(wildcard ${dir_source}/widgets/special_number_input/templates/*)
@ ${cmd_log} "templates:widget:special_number_input …"
@ ${cmd_mkdir} ${dir_build}/templates/widget-special_number_input
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/special_number_input/templates/* ${dir_build}/templates/widget-special_number_input/
.PHONY: templates-widgets-sources
templates-widgets-sources: \
$(wildcard ${dir_source}/widgets/sources/templates/*)