From 0ff627bca9739fb3d0c8c4f820bc052fc6dd108e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Mon, 23 Nov 2020 21:37:03 +0100 Subject: Bind large part of rrule. --- static/binders.js | 33 ++++++++++++++++++++------------- static/rrule.js | 22 ++++++++++++++++------ static/script.js | 49 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 79 insertions(+), 25 deletions(-) (limited to 'static') diff --git a/static/binders.js b/static/binders.js index d030084d..b609058a 100644 --- a/static/binders.js +++ b/static/binders.js @@ -1,22 +1,28 @@ +/* + bind (event_component, field_to_bind) +*/ /* vcalendar element */ function bind_recur(el, e) { /* todo bind default slots of rrule */ - let p = get_property(el, 'rrule', new rrule); - let rrule = el.rrule; + let p = get_property(el, 'rrule'); + // let rrule = el.rrule; for (let rr of e.querySelectorAll('.bind-rr')) { - rrule.addListener(rr.dataset.name, v => { - /* TODO Different depending on tag type */ - /* TODO scoope of rr? */ - if (! v) { - rr.value = ''; - } else { - rr.vaule = v; - } - }); + if (rr.classList.contains('input-list')) { + rr.addEventListener('input', function () { + let name = rr.attributes.name.value; + el.properties.rrule[name] = this.get_value(); + }); + } else if (rr.tagName === 'input') { + rr.addEventListener('input', function () { + el.properties.rrule[rr.name] = this.value; + }); + } else if (rr.tagName === 'option') { + console.log("TODO"); + } } p.push([e, function (s, v) { @@ -34,8 +40,9 @@ function bind_recur(el, e) { if (input_field.classList.contains('date-time')) { let date = input_field.querySelector('input[type=date]'); let time = input_field.querySelector('input[type=time]'); - } else if (e.classList.contains('input-list')) { + } else if (input_field.classList.contains('input-list')) { } else { + console.log(input_field); throw Error(); } } @@ -79,8 +86,8 @@ function bind_view(el, e) { function bind_wholeday(el, e) { - // let wholeday = popup.querySelector("input[name='wholeday']"); let popup = popup_from_event(el); + let wholeday = popup.querySelector("input[name='wholeday']"); wholeday.addEventListener('click', function (event) { for (let f of popup.querySelectorAll("input[type='time']")) { f.disabled = wholeday.checked; diff --git a/static/rrule.js b/static/rrule.js index 30bed919..8f3693a6 100644 --- a/static/rrule.js +++ b/static/rrule.js @@ -1,13 +1,23 @@ +function recur_xml_to_rrule(dom_element) { + let rr = new RRule; + for (let child of dom_element.children) { + let key = child.tagName; /* freq */ + let val = child.innerHTML; /* weekly */ + rr[key] = val; + } + return rr; +} + class RRule { /* direct access to fields is fine */ /* setting them however requires methods, since there might be listeners */ - const fields = ['freq', 'until', 'count', 'interval', - 'bysecond', 'byminute', 'byhour', - 'bymonthday', 'byyearday', 'byweekno', - 'bymonth', 'bysetpos', 'wkst'] + fields = ['freq', 'until', 'count', 'interval', + 'bysecond', 'byminute', 'byhour', + 'bymonthday', 'byyearday', 'byweekno', + 'bymonth', 'bysetpos', 'wkst'] constructor() { @@ -17,7 +27,7 @@ class RRule { this[f] = false; Object.defineProperty( this, f, { - get: () => this['_' + f]; + get: () => this['_' + f], set: (v) => { this['_' + f] = v for (let l of this.listeners[f]) { @@ -30,7 +40,7 @@ class RRule { } addListener(field, proc) { - this.listeners[field].append(proc); + this.listeners[field].push(proc); } asXcal() { diff --git a/static/script.js b/static/script.js index 133140d2..409359a7 100644 --- a/static/script.js +++ b/static/script.js @@ -436,10 +436,12 @@ function bind_properties (el, wide_event=false) { /* primary display tab */ let p; - for (let e of [...popup.querySelectorAll(".bind"), - ...el.querySelectorAll('.bind')]) { - if ((p = e.closest('[data-bindby=*]'))) { - p.dataset.bindby(el, e); + let lst = [...popup.querySelectorAll(".bind"), + ...el.querySelectorAll('.bind')]; + for (let e of lst) { + if ((p = e.closest('[data-bindby]'))) { + // console.log(p.dataset.bindby); + eval(p.dataset.bindby)(el, e); } else { let f = ((s, v) => s.innerHTML = v.format(s.dataset && s.dataset.fmt)); get_property(el, e.dataset.property).push([e, f]); @@ -528,8 +530,10 @@ function bind_properties (el, wide_event=false) { 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)`)) { + lst.push([s, (s, v) => { if (v instanceof Date) { if (v.isWholeDay) { @@ -540,14 +544,23 @@ function bind_properties (el, wide_event=false) { child.innerHTML = `${str}`; } } else if (v instanceof RRule) { - /* TODO also recalculate whenever any field changes */ child.innerHTML = v.asXcal(); } else { /* assume that type already is correct */ s.innerHTML = v; } }]); - el.properties["_value_" + field] = s.innerHTML; + + /* Binds value from XML-tree to javascript object + [parsedate] + */ + switch (field) { + case 'rrule': + el.properties['_value_rrule'] = recur_xml_to_rrule(s); + break; + default: + el.properties["_value_" + field] = s.innerHTML; + } } } @@ -584,6 +597,7 @@ function bind_properties (el, wide_event=false) { let end = parseDate(container.dataset.end); if (el.properties.dtstart) { + /* [parsedate] */ el.properties.dtstart = parseDate(el.properties.dtstart); get_property(el, 'dtstart').push( [el.style, (s, v) => @@ -601,6 +615,29 @@ function bind_properties (el, wide_event=false) { (s, v) => s[wide_event?'right':'bottom'] = 100 * (1 - (to_local(v)-start)/(end-start)) + "%"]); } + + /* Update XML on rrule field change */ + if (el.properties.rrule) { + for (let f of el.properties.rrule.fields) { + el.properties.rrule.addListener( + f, v => { + console.log(v); + let recur = el.querySelector('rrule recur'); + let field = recur.querySelector(f); + if (field) { + if (! v) { + field.remove(); + } else { + field.innerHTML = v; + } + } else { + if (v) recur.innerHTML += `<${f}>${v}`; + } + }); + } + } + + /* ---------- Calendar ------------------------------ */ if (! el.dataset.calendar) { -- cgit v1.2.3