Mobil-Ansicht #4
|
|
@ -101,7 +101,7 @@ a:hover
|
|||
|
||||
button
|
||||
{
|
||||
padding: 8px;
|
||||
padding: 4px 8px;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
|
||||
|
|
|
|||
164
source/widgets/special_number_input/logic.ts
Normal file
164
source/widgets/special_number_input/logic.ts
Normal 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"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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">◂</button>
|
||||
<input type="text" pattern="-?[0-9]+"/>
|
||||
<button class="widget-special_number_input-next">▸</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -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
|
||||
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_special_number_input(
|
||||
{
|
||||
[
|
||||
{
|
||||
"name": "year",
|
||||
"selector": ".weekview-control-year input",
|
||||
"retrieve": element => parseInt(element.value),
|
||||
"write": x => {this.year = x;}
|
||||
"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();
|
||||
},
|
||||
}
|
||||
);
|
||||
await widget.load(target_element.querySelector(".weekview-controls"));
|
||||
}
|
||||
// control:week
|
||||
{
|
||||
"name": "week",
|
||||
"selector": ".weekview-control-week input",
|
||||
"retrieve": element => parseInt(element.value),
|
||||
"write": x => {this.week = x;}
|
||||
},
|
||||
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_special_number_input(
|
||||
{
|
||||
"name": "count",
|
||||
"selector": ".weekview-control-count input",
|
||||
"retrieve": element => parseInt(element.value),
|
||||
"write": x => {this.count = x;}
|
||||
"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
|
||||
/*
|
||||
{
|
||||
"name": "vertical",
|
||||
"selector": ".weekview-control-vertical input",
|
||||
"retrieve": element => element.checked,
|
||||
"write": x => {this.vertical = x;}
|
||||
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();
|
||||
},
|
||||
].forEach(
|
||||
(entry) => {
|
||||
const element : HTMLInputElement = (target_element.querySelector(entry.selector) as HTMLInputElement);
|
||||
element.addEventListener(
|
||||
}
|
||||
);
|
||||
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) => {
|
||||
async () => {
|
||||
event.preventDefault();
|
||||
const value : unknown = entry.retrieve(element);
|
||||
entry.write(value);
|
||||
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"));
|
||||
}
|
||||
);
|
||||
}
|
||||
// buttons
|
||||
{
|
||||
// year
|
||||
{
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
);
|
||||
}
|
||||
// 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 this.update_controls();
|
||||
|
||||
this.container = target_element.querySelector(".weekview");
|
||||
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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">◂</button>
|
||||
<input type="text"/>
|
||||
<button class="weekview-control-year-next">▸</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">◂</button>
|
||||
<input type="text"/>
|
||||
<button class="weekview-control-week-next">▸</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">◂</button>
|
||||
<input type="text"/>
|
||||
<button class="weekview-control-count-next">▸</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>
|
||||
|
|
|
|||
|
|
@ -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/*)
|
||||
|
|
|
|||
Loading…
Reference in a new issue