Mobil-Ansicht #4
|
|
@ -101,7 +101,7 @@ a:hover
|
||||||
|
|
||||||
button
|
button
|
||||||
{
|
{
|
||||||
padding: 8px;
|
padding: 4px 8px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
cursor: pointer;
|
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(
|
private async update_table(
|
||||||
|
|
@ -881,169 +868,91 @@ namespace _dali.widgets.weekview
|
||||||
"widget-weekview",
|
"widget-weekview",
|
||||||
"main",
|
"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");
|
// control:year
|
||||||
// controls
|
|
||||||
{
|
{
|
||||||
// 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;}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"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
|
|
||||||
{
|
{
|
||||||
/**
|
"label": lib_plankton.translate.get("widget.weekview.controls.year"),
|
||||||
* @todo limit
|
"minimum": 1900,
|
||||||
*/
|
"maximum": 2500,
|
||||||
target_element.querySelector(".weekview-control-year-prev").addEventListener(
|
"initial_value": this.year,
|
||||||
"click",
|
"action_change": async (value) => {
|
||||||
async () => {
|
this.year = value;
|
||||||
this.year -= 1;
|
await this.update_table();
|
||||||
await this.update_controls();
|
await this.update_entries();
|
||||||
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
|
);
|
||||||
{
|
await widget.load(target_element.querySelector(".weekview-controls"));
|
||||||
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();
|
// 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_table();
|
||||||
await this.update_entries();
|
await this.update_entries();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
{
|
{
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: nowrap;
|
||||||
justify-content: right;
|
justify-content: right;
|
||||||
|
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
|
@ -16,11 +16,23 @@
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
flex-shrink: 1;
|
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;
|
min-width: 140px;
|
||||||
margin: 0 12px;
|
margin: 0 0 0 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.weekview-control-label
|
.weekview-control-label
|
||||||
|
,
|
||||||
|
.weekview-controls .widget-special_number_input-label
|
||||||
{
|
{
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
|
|
@ -35,7 +47,7 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.weekview-control input
|
.weekview-controls .widget-special_number_input input
|
||||||
{
|
{
|
||||||
max-width: 40px;
|
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">
|
||||||
<div class="weekview-controls">
|
<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>
|
||||||
<div class="weekview-table">
|
<div class="weekview-table">
|
||||||
<table>
|
<table>
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ ${dir_build}/index.html: \
|
||||||
.PHONY: templates
|
.PHONY: templates
|
||||||
templates: \
|
templates: \
|
||||||
templates-widgets-login \
|
templates-widgets-login \
|
||||||
|
templates-widgets-special_number_input \
|
||||||
templates-widgets-sources \
|
templates-widgets-sources \
|
||||||
templates-widgets-listview \
|
templates-widgets-listview \
|
||||||
templates-widgets-weekview \
|
templates-widgets-weekview \
|
||||||
|
|
@ -45,6 +46,13 @@ templates-widgets-login: \
|
||||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-login
|
@ ${cmd_mkdir} ${dir_build}/templates/widget-login
|
||||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/login/templates/* ${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
|
.PHONY: templates-widgets-sources
|
||||||
templates-widgets-sources: \
|
templates-widgets-sources: \
|
||||||
$(wildcard ${dir_source}/widgets/sources/templates/*)
|
$(wildcard ${dir_source}/widgets/sources/templates/*)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue