aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2020-10-02 16:49:43 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2020-10-02 16:52:06 +0200
commitf533f5050bb4899e18dc1656458697b1d277dd56 (patch)
treed440d808b7db76164c5fc5bd36f756dfc63088d4
parentBetter mapping of fields. (diff)
downloadcalp-f533f5050bb4899e18dc1656458697b1d277dd56.tar.gz
calp-f533f5050bb4899e18dc1656458697b1d277dd56.tar.xz
Binding of fields in edit tab work.
-rw-r--r--module/calp/html/vcomponent.scm50
-rw-r--r--static/script.js91
2 files changed, 86 insertions, 55 deletions
diff --git a/module/calp/html/vcomponent.scm b/module/calp/html/vcomponent.scm
index 7a4de873..0f8014db 100644
--- a/module/calp/html/vcomponent.scm
+++ b/module/calp/html/vcomponent.scm
@@ -56,18 +56,21 @@
;; (format (current-error-port) "fmt-single-event: ~a~%" (prop ev 'X-HNH-FILENAME))
`(div (@ ,@(assq-merge
attributes
- `((class " eventtext "
+ `((class " eventtext summary-tab "
,(when (and (prop ev 'PARTSTAT)
(eq? 'TENTATIVE (prop ev 'PARTSTAT)))
" tentative ")))))
(h3 ,(fmt-header
(when (prop ev 'RRULE)
`(span (@ (class "repeating")) "↺"))
- `(span (@ (class "summary")) ,(prop ev 'SUMMARY))))
+ `(span (@ (class "bind summary")
+ (data-property "summary"))
+ ,(prop ev 'SUMMARY))))
(div
,(call-with-values (lambda () (fmt-time-span ev))
(case-lambda [(start)
- `(div (time (@ (class "dtstart")
+ `(div (time (@ (class "bind dtstart")
+ (data-property "dtstart")
(data-fmt ,(string-append "~L" start))
(datetime ,(datetime->string
(as-datetime (prop ev 'DTSTART))
@@ -76,7 +79,8 @@
(as-datetime (prop ev 'DTSTART))
start)))]
[(start end)
- `(div (time (@ (class "dtstart")
+ `(div (time (@ (class "bind dtstart")
+ (data-property "dtstart")
(data-fmt ,(string-append "~L" start))
(datetime ,(datetime->string
(as-datetime (prop ev 'DTSTART))
@@ -84,23 +88,30 @@
,(datetime->string (as-datetime (prop ev 'DTSTART))
start))
" — "
- (time (@ (class "dtend")
+ (time (@ (class "bind dtend")
+ (data-property "dtend")
(data-fmt ,(string-append "~L" end))
(datetime ,(datetime->string
(as-datetime (prop ev 'DTSTART))
"~1T~3")))
,(datetime->string (as-datetime (prop ev 'DTEND))
end)))]))
+
+ ;; TODO add optional fields when added in frontend
+ ;; Possibly by always having them here, just hidden.
+
(div (@ (class "fields"))
,(when (and=> (prop ev 'LOCATION) (negate string-null?))
`(div (b "Plats: ")
- (div (@ (class "location"))
+ (div (@ (class "bind location") (data-property "location"))
,(string-map (lambda (c) (if (char=? c #\,) #\newline c))
(prop ev 'LOCATION)))))
,(awhen (prop ev 'DESCRIPTION)
- `(div (@ (class "description"))
+ `(div (@ (class "bind description")
+ (data-property "description"))
,(format-description ev it)))
+ ;; TODO add bind once I figure out how to bind lists
,(awhen (prop ev 'CATEGORIES)
`(div (@ (class "categories"))
,@(map (lambda (c)
@@ -111,6 +122,8 @@
c)))
,c))
it)))
+
+ ;; TODO bind
,(awhen (prop ev 'RRULE)
`(div (@ (class "rrule"))
,@(format-recurrence-rule ev)))
@@ -124,11 +137,12 @@
(define*-public (fmt-for-edit ev
optional: (attributes '())
key: (fmt-header list))
- `(div (@ (class " eventtext "))
+ `(div (@ (class " eventtext edit-tab "))
(form (@ (class "edit-form"))
(h3 (input (@ (type "text")
(placeholder "Sammanfattning")
(name "summary") (required)
+ (class "bind") (data-property "summary")
(value ,(prop ev 'SUMMARY)))))
,(let ((start (prop ev 'DTSTART))
@@ -138,11 +152,15 @@
(input (@ (type "date")
(name "dtstart-date")
(style "grid-column:1;grid-row:2")
+ (class "bind")
+ (data-property "--dtstart-date")
(value ,(date->string (as-date start)))))
(input (@ (type "date")
(name "dtend-date")
(style "grid-column:1;grid-row:3")
+ (class "bind")
+ (data-property "--dtend-date")
,@(when end `((value ,(date->string (as-date end)))))))
,@(with-label
@@ -151,13 +169,17 @@
(name "wholeday"))))
(input (@ (type "time")
- (name "dtstart-end")
+ (name "dtstart-time")
+ (class "bind")
+ (data-property "--dtstart-time")
(style "grid-column:3;grid-row:2;"
,(when (date? start) "display:none"))
(value ,(time->string (as-time start)))))
(input (@ (type "time")
(name "dtend-time")
+ (class "bind")
+ (data-property "--dtend-time")
(style "grid-column:3;grid-row:3;"
,(when (date? end) "display:none"))
,@(when end `((value ,(time->string (as-time end)))))
@@ -168,11 +190,13 @@
`(input (@ (placeholder "Plats")
(name "location")
(type "text")
+ (class "bind") (data-property "location")
(value ,(or (prop ev 'LOCATION) "")))))
,@(with-label
"Beskrivning"
`(textarea (@ (placeholder "Beskrivning")
+ (class "bind") (data-property "description")
(name "description"))
,(prop ev 'DESCRIPTION)))
@@ -190,6 +214,8 @@
(type "text")
))))
+ ;; TODO extra fields
+
(hr)
(div (@ (class "newfield"))
@@ -275,10 +301,12 @@
(div (@ (class "event-body"))
,(when (prop ev 'RRULE)
`(span (@ (class "repeating")) "↺"))
- (span (@ (class "summary"))
+ (span (@ (class "bind summary")
+ (data-property "summary"))
,(format-summary ev (prop ev 'SUMMARY)))
,(when (prop ev 'LOCATION)
- `(span (@ (class "location"))
+ `(span (@ (class "bind location")
+ (data-property "location"))
,(string-map (lambda (c) (if (char=? c #\,) #\newline c))
(prop ev 'LOCATION)))))
(div (@ (style "display:none !important;"))
diff --git a/static/script.js b/static/script.js
index 7fcdf48f..b703a21a 100644
--- a/static/script.js
+++ b/static/script.js
@@ -928,7 +928,7 @@ function toggle_popup(popup_id) {
default_value - default value when creating
bind_to_ical - should this property be added to the icalendar subtree?
*/
-function get_property(el, field, default_value, bind_to_ical=true) {
+function get_property(el, field, default_value) {
if (! el.properties) {
el.properties = {};
}
@@ -952,20 +952,6 @@ function get_property(el, field, default_value, bind_to_ical=true) {
});
}
- if (bind_to_ical) {
- let ical_properties = el.querySelector("icalendar vevent properties");
- if (! ical_properties.querySelector(field)) {
- let text = document.createElementNS(xcal, 'text');
- let element = document.createElementNS(xcal, field);
- element.appendChild(text);
- if (default_value) {text.innerHTML = default_value;}
-
- ical_properties.appendChild(element);
- el.properties["_slot_" + field].push(
- [text, (s, v) => s.innerHTML = v]);
- }
- }
-
return el.properties["_slot_" + field];
}
@@ -1001,45 +987,61 @@ class vcomponent {
and binds the value to the slot.
*/
function bind_properties (el, wide_event=false) {
+
el.properties = {}
let popup = document.getElementById("popup" + el.id);
// let children = el.getElementsByTagName("properties")[0].children;
- let children = el.querySelector("vevent > properties").children;
- for (let child of children) {
- let field = child.tagName;
+ /* actual component (not popup) */
+ for (let e of el.querySelectorAll(".bind")) {
+ let f = ((s, v) => s.innerHTML = v.format(s.dataset && s.dataset.fmt));
+ get_property(el, e.dataset.property).push([e, f]);
+ }
- let lst = get_property(el, field);
+ /* primary display tab */
- /* Bind HTML fields for this event */
- for (let s of el.getElementsByClassName(field)) {
- let f = ((s, v) => s.innerHTML = v.format(s.dataset && s.dataset.fmt));
- lst.push([s, f]);
+ for (let e of popup.querySelectorAll(".summary-tab .bind")) {
+ let f = (s, v) => s.innerHTML = v.format(s.dataset && s.dataset.fmt);
+ get_property(el, e.dataset.property).push([e, f]);
+ }
+
+ /* edit tab */
+ for (let e of popup.querySelectorAll(".edit-tab .bind")) {
+ let p = get_property(el, e.dataset.property);
+ e.oninput = function () {
+ el.properties[e.dataset.property] = this.value;
}
- for (let s of popup.getElementsByClassName(field)) {
- let f = ((s, v) => s.innerHTML = v.format(s.dataset && s.dataset.fmt));
- lst.push([s, f]);
+ let f;
+ switch (e.tagName) {
+ case 'input':
+ // TODO format depending on type
+ switch (e.type) {
+ case 'time': f = (s, v) => s.value = v.format("~H:~M:~S"); break;
+ case 'date': f = (s, v) => s.value = v.format("~Y-~m-~d"); break;
+ default: f = (s, v) => s.value = v;
+ }
+ p.push([e, f])
+ break;
+ case 'textarea':
+ f = (s, v) => s.innerHTML = v;
+ p.push([e, f])
+ break;
+ default:
+ alert("How did you get here??? " + e.tagName)
+ break;
}
+ }
- /* edit tab */
- for (let s of popup.querySelectorAll(`[name='${field}']`)) {
- let f;
- s.oninput = function () {
- el.properties[s.name] = this.value;
- }
- switch (s.name) {
- case 'description':
- f = ((s, v) => s.innerHTML = v.format(s.dataset && s.dataset.fmt));
- lst.push([s, f]);
- break;
- default:
- f = ((s, v) => s.value = v);
- lst.push([s, f]);
- break;
- }
- }
+ /* TODO propagate `--dtstart-*' to `dtstart' */
+ get_property(el, 'dtstart').push(
+ [el, (el, v) => { el.properties['--dtstart-time'] = v;
+ el.properties['--dtstart-date'] = v; }]);
+ for (let child of el.querySelector("vevent > properties").children) {
+ let field = child.tagName;
+
+ let lst = get_property(el, field);
/* Bind vcomponent fields for this event */
for (let s of el.querySelectorAll(field + " > :not(parameters)")) {
@@ -1055,6 +1057,7 @@ function bind_properties (el, wide_event=false) {
}
}
+ /* set up graphical display changes */
let container = el.closest(".event-container");
if (container === null) {
console.log("No enclosing event container for", el);
@@ -1087,7 +1090,7 @@ function bind_properties (el, wide_event=false) {
el.dataset.calendar = "Unknown";
}
- let calprop = get_property(el, 'calendar', el.dataset.calendar, false);
+ let calprop = get_property(el, 'calendar', el.dataset.calendar);
const rplcs = (s, v) => {
let [_, calclass] = s.classList.find(/^CAL_/);