branch feature/component_choice_editor updated (2e8ad60 -> 42a357e)
This is an automated email from the git hooks/post-receive script. New change to branch feature/component_choice_editor in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git omits 2e8ad60 debut du composant d'édition de choix adds adcf381 style de l'entête du pied et de l'ecran d'acceuille adds 12e321d Adaptation de l'écran de création de sondage adds 8031085 Merge branch 'feature/small-screen' into 'develop' new c302749 debut du composant d'édition de choix new 42a357e - ajout du type datetime dans le modele pour les choix - utilisation du composant de choix dans le formulaire - utilisation des input de type date et time quand supportés This update added new revisions after undoing existing revisions. That is to say, some revisions that were in the old version of the branch are not in the new version. This situation occurs when a user --force pushes a change and generates a repository containing something like this: * -- * -- B -- O -- O -- O (2e8ad60) \ N -- N -- N refs/heads/feature/component_choice_editor (42a357e) You should already have received notification emails for all of the O revisions, and so the following emails describe only the N revisions from the common base, B. Any revisions marked "omits" are not gone; other references still refer to them. Any revisions marked "discards" are gone forever. The 2 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 42a357e4169e3aed74c4ec06038e94762d098d60 Author: Kevin Morin <morin@codelutin.com> Date: Tue Mar 7 18:13:40 2017 +0100 - ajout du type datetime dans le modele pour les choix - utilisation du composant de choix dans le formulaire - utilisation des input de type date et time quand supportés commit c302749af39b6f1bcdf00edad40ca671e720a559 Author: Kevin Morin <morin@codelutin.com> Date: Thu Mar 2 18:29:54 2017 +0100 debut du composant d'édition de choix Summary of changes: pollen-persistence/src/main/xmi/pollen.zargo | Bin 21327 -> 21426 bytes pollen-ui-riot-js/package.json | 1 + pollen-ui-riot-js/src/main/web/css/main.css | 62 +- pollen-ui-riot-js/src/main/web/i18n.json | 68 +- pollen-ui-riot-js/src/main/web/index.html | 2 + pollen-ui-riot-js/src/main/web/js/I18nHelper.js | 4 +- pollen-ui-riot-js/src/main/web/js/PollForm.js | 108 +-- pollen-ui-riot-js/src/main/web/js/Session.js | 15 + pollen-ui-riot-js/src/main/web/tag/Footer.tag.html | 7 +- pollen-ui-riot-js/src/main/web/tag/Header.tag.html | 112 +-- .../src/main/web/tag/HeaderI18n.tag.html | 6 +- pollen-ui-riot-js/src/main/web/tag/Home.tag.html | 50 +- pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 2 +- .../main/web/tag/components/date-picker.tag.html | 230 +++++ .../main/web/tag/components/time-picker.tag.html | 240 ++++++ .../src/main/web/tag/poll/Choice.tag.html | 194 +++++ .../src/main/web/tag/poll/ChoiceImage.tag.html | 77 -- .../src/main/web/tag/poll/ChoiceText.tag.html | 176 ---- .../src/main/web/tag/poll/Choices.tag.html | 331 +------ .../src/main/web/tag/poll/CreatePoll.tag.html | 216 ++--- .../src/main/web/tag/poll/Description.tag.html | 91 +- .../src/main/web/tag/poll/Settings.tag.html | 950 ++++++--------------- .../src/main/web/tag/poll/Voters.tag.html | 217 ++--- pollen-ui-riot-js/webpack.config.js | 3 +- 24 files changed, 1378 insertions(+), 1784 deletions(-) create mode 100644 pollen-ui-riot-js/src/main/web/tag/components/date-picker.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/components/time-picker.tag.html create mode 100644 pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html delete mode 100644 pollen-ui-riot-js/src/main/web/tag/poll/ChoiceImage.tag.html delete mode 100644 pollen-ui-riot-js/src/main/web/tag/poll/ChoiceText.tag.html -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/component_choice_editor in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit c302749af39b6f1bcdf00edad40ca671e720a559 Author: Kevin Morin <morin@codelutin.com> Date: Thu Mar 2 18:29:54 2017 +0100 debut du composant d'édition de choix --- pollen-ui-riot-js/src/main/web/css/main.css | 3 +- .../src/main/web/tag/poll/ChoiceImage.tag.html | 77 ++++++++++++++++++++++ .../src/main/web/tag/poll/Choices.tag.html | 1 + 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/pollen-ui-riot-js/src/main/web/css/main.css b/pollen-ui-riot-js/src/main/web/css/main.css index 0032f71..d51671a 100644 --- a/pollen-ui-riot-js/src/main/web/css/main.css +++ b/pollen-ui-riot-js/src/main/web/css/main.css @@ -62,8 +62,7 @@ input, textarea { .body-container { display: flex; - flex-flow: row wrap; - flex-direction: column; + flex-flow: column wrap; margin-left: auto; diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceImage.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceImage.tag.html new file mode 100644 index 0000000..cd180bc --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceImage.tag.html @@ -0,0 +1,77 @@ +<ChoiceImage> + <div id="choice-container"> + <span class="button" alt="texte" onclick="{setTextType}"><i class="fa fa-pencil" aria-hidden="true"/></span><input type="text" class="{choiceType === 'text' ? 'selected' : ''}"/> + <span class="button" alt="image" onclick="{setImageType}"><i class="fa fa-image" aria-hidden="true"/></span><input type="file" class="{choiceType === 'image' ? 'selected' : ''}"/> + <span class="button" alt="date" onclick="{setDateType}"><i class="fa fa-calendar" aria-hidden="true"/></span><input type="date" class="{choiceType.startsWith('date') ? 'selected' : ''}"/> + <span class="button {!choiceType.startsWith('date') ? 'hidden' : ''}" alt="heure" onclick="{toggleTime}"><i class="fa fa-clock-o" aria-hidden="true"/></span><input type="text" class="{choiceType === 'datetime' ? 'selected' : ''}"/> + </div> + + <script type="es6"> + this.choiceType = "text"; + + this.setTextType = () => { + this.choiceType = "text"; + }; + + this.setImageType = () => { + this.choiceType = "image"; + }; + + this.setDateType = () => { + if (!this.choiceType.startsWith("date")) { + this.choiceType = "date"; + } + }; + + this.toggleTime = () => { + if (this.choiceType === "date") { + this.choiceType = "datetime"; + } else if (this.choiceType === "datetime") { + this.choiceType = "date"; + } + }; + + </script> + + <style> + + #choice-container { + display: flex; + flex-flow: row nowrap; + } + + .button { + width:auto; + opacity: 1; + margin: 0 10px 10px 10px; + transition: opacity 0.3s ease-in-out 0s, width 0s linear 0.5s; + } + + .hidden { + visibility: hidden; + opacity: 0; + width: 0; + } + + input { + display: inline-block; + visibility: hidden; + width: 0; + height: auto; + flex-grow: 0; + margin: 0; + padding: 0; + transition: width 0.5s ease-in-out 0s, + flex-grow 0s linear 0.5s, + visibility 0.5s ease-in-out 0s; + } + + .selected { + visibility: visible; + width: 100%; + flex-grow: 1; + padding: 10px; + } + + </style> +</ChoiceImage> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Choices.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Choices.tag.html index 73ee64c..5e71e43 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Choices.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Choices.tag.html @@ -1,6 +1,7 @@ require("./ChoiceText.tag.html"); require("./ChoiceText.tag.html"); require("./ChoiceDate.tag.html"); +require("./ChoiceImage.tag.html"); <Choices> <div each={choice, index in form.choices} class="o-form-element" -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/component_choice_editor in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 42a357e4169e3aed74c4ec06038e94762d098d60 Author: Kevin Morin <morin@codelutin.com> Date: Tue Mar 7 18:13:40 2017 +0100 - ajout du type datetime dans le modele pour les choix - utilisation du composant de choix dans le formulaire - utilisation des input de type date et time quand supportés --- pollen-persistence/src/main/xmi/pollen.zargo | Bin 21327 -> 21426 bytes pollen-ui-riot-js/src/main/web/css/main.css | 2 - pollen-ui-riot-js/src/main/web/i18n.json | 4 +- pollen-ui-riot-js/src/main/web/js/I18nHelper.js | 4 +- pollen-ui-riot-js/src/main/web/js/PollForm.js | 57 +---- pollen-ui-riot-js/src/main/web/js/Session.js | 15 ++ .../main/web/tag/components/date-picker.tag.html | 230 ++++++++++++++++++++ .../main/web/tag/components/time-picker.tag.html | 240 +++++++++++++++++++++ .../src/main/web/tag/poll/Choice.tag.html | 194 +++++++++++++++++ .../src/main/web/tag/poll/ChoiceImage.tag.html | 77 ------- .../src/main/web/tag/poll/ChoiceText.tag.html | 176 --------------- .../src/main/web/tag/poll/Choices.tag.html | 16 +- 12 files changed, 690 insertions(+), 325 deletions(-) diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index a5d88ed..b2357c4 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-ui-riot-js/src/main/web/css/main.css b/pollen-ui-riot-js/src/main/web/css/main.css index d51671a..11b8a33 100644 --- a/pollen-ui-riot-js/src/main/web/css/main.css +++ b/pollen-ui-riot-js/src/main/web/css/main.css @@ -94,8 +94,6 @@ a { .container { margin: 0 5px; } - - } form .actions { diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index e818347..f4a8488 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -229,7 +229,7 @@ "users_VALIDATION": "En cours de validation", "users_DISABLED": "Désactivé", "users_BANNED": "Banni", - "": "" + "date-picker_today": "Aujourd'hui" }, "en": { "pagination_page": "Page", @@ -454,6 +454,6 @@ "users_VALIDATION": "Account validation", "users_DISABLED": "Account disabled", "users_BANNED": "Account banned", - "": "" + "date-picker_today": "Today" } } diff --git a/pollen-ui-riot-js/src/main/web/js/I18nHelper.js b/pollen-ui-riot-js/src/main/web/js/I18nHelper.js index 40b4d91..f0eab00 100644 --- a/pollen-ui-riot-js/src/main/web/js/I18nHelper.js +++ b/pollen-ui-riot-js/src/main/web/js/I18nHelper.js @@ -54,10 +54,10 @@ module.exports = { }, _l(key, ...params) { - return this.format(this.__[key], ...params); + return this.i18nformat(this.__[key], ...params); }, - format(value, params) { + i18nformat(value, params) { if (!params) { return value; } diff --git a/pollen-ui-riot-js/src/main/web/js/PollForm.js b/pollen-ui-riot-js/src/main/web/js/PollForm.js index c14546c..3b4ea42 100644 --- a/pollen-ui-riot-js/src/main/web/js/PollForm.js +++ b/pollen-ui-riot-js/src/main/web/js/PollForm.js @@ -113,6 +113,7 @@ class PollForm { previousStep() { console.info("previousStep:: " + this.step); + console.log (this.choices); this.setStep(this.step - 1); } @@ -160,62 +161,6 @@ class PollForm { this.choices.splice(index, 1); } - fromDomToChoices(form) { - let choices = []; - - let map = {}; - let count = 0; - Array.prototype.forEach.call(form.elements, (e) => { - if (e.name && e.value) { - if (e.name.indexOf("choice") === 0) { - map[e.name] = e.value; - count++; - } - if (e.name.indexOf("description") === 0) { - map[e.name] = e.value; - } - if (e.name.indexOf("id") === 0) { - map[e.name] = e.value; - } - } - }); - - for (let i = 0; i < count; i++) { - let text = map["choice" + i]; - let description = map["description" + i]; - let id = map["id" + i]; - if (this.type !== "add" || !id) { - choices.push(new Choice(this.model.choiceType, text, description, id)); - } - } - console.info("FromTextChoices"); - console.info(choices); - this.choices = choices; - } - - getTextChoice(form, index) { - let map = {}; - - Array.prototype.forEach.call(form.elements, (e) => { - if (e.name && e.value) { - if (e.name.indexOf("choice") === 0) { - map[e.name] = e.value; - } - if (e.name.indexOf("description") === 0) { - map[e.name] = e.value; - } - if (e.name.indexOf("id") === 0) { - map[e.name] = e.value; - } - } - }); - - let text = map["choice" + index]; - let description = map["description" + index]; - let id = map["id" + index]; - return new Choice(this.model.choiceType, text, description, id); - } - setStep(step) { console.info("setStep:: " + step); this.step = Math.min(this.steps.length, Math.max(0, step)); diff --git a/pollen-ui-riot-js/src/main/web/js/Session.js b/pollen-ui-riot-js/src/main/web/js/Session.js index 9bfbc03..8664e47 100644 --- a/pollen-ui-riot-js/src/main/web/js/Session.js +++ b/pollen-ui-riot-js/src/main/web/js/Session.js @@ -47,6 +47,21 @@ class Session { this.locale = "fr"; } + let input = document.createElement("input"); + let notADateValue = "not-a-date-nor-time"; + + input.setAttribute("type", "date"); + input.setAttribute("value", notADateValue); + this.dateInputSupported = (input.value !== notADateValue); + + input.setAttribute("type", "time"); + input.setAttribute("value", notADateValue); + this.timeInputSupported = (input.value !== notADateValue); + + input.setAttribute("type", "datetime"); + input.setAttribute("value", notADateValue); + this.datetimeInputSupported = (input.value !== notADateValue); + this.onUnauthorize(() => { this.user = null; }); diff --git a/pollen-ui-riot-js/src/main/web/tag/components/date-picker.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/date-picker.tag.html new file mode 100644 index 0000000..7c2d35a --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/components/date-picker.tag.html @@ -0,0 +1,230 @@ +<date-picker> + <input type="date" class="calendar-field" onclick="{open}" value="{opts.date.date.format(format)}" readonly="{!session.dateInputSupported}" /> + + <div class="c-calendar c-calendar--higher" if="{opts.date.isvisible && !session.dateInputSupported}"> + <button type="button" class="c-calendar__control" disabled="{ opts.date.min && opts.date.min.isSame(opts.date.date, 'year') }" onclick="{ prevYear }">‹</button> + <div class="c-calendar__header">{ opts.date.date.format(yearFormat) }</div> + <button type="button" class="c-calendar__control" disabled="{ opts.date.max && opts.date.max.isSame(opts.date.date, 'year') }" onclick="{ nextYear }">›</button> + + <button type="button" class="c-calendar__control" disabled="{ opts.date.min && opts.date.min.isSame(opts.date.date, 'month') }" onclick="{ prevMonth }">‹</button> + <div class="c-calendar__header">{ opts.date.date.format(monthFormat) }</div> + <button type="button" class="c-calendar__control" disabled="{ opts.date.max && opts.date.max.isSame(opts.date.date, 'month') }" onclick="{ nextMonth }">›</button> + + <div class="c-calendar__day">{moment.weekdaysMin(1)}</div> + <div class="c-calendar__day">{moment.weekdaysMin(2)}</div> + <div class="c-calendar__day">{moment.weekdaysMin(3)}</div> + <div class="c-calendar__day">{moment.weekdaysMin(4)}</div> + <div class="c-calendar__day">{moment.weekdaysMin(5)}</div> + <div class="c-calendar__day">{moment.weekdaysMin(6)}</div> + <div class="c-calendar__day">{moment.weekdaysMin(0)}</div> + + <button type="button" class="c-calendar__date { 'c-calendar__date--selected': day.selected, 'c-calendar__date--today': day.today }" disabled="{ day.disabled }" each="{ day in startBuffer }" onclick="{ select }">{ day.date.format(dayFormat) }</button> + <button type="button" class="c-calendar__date c-calendar__date--in-month { 'c-calendar__date--selected': day.selected, 'c-calendar__date--today': day.today }" disabled="{ day.disabled }" each="{ day in days }" onclick="{ select }">{ day.date.format(dayFormat) }</button> + <button type="button" class="c-calendar__date { 'c-calendar__date--selected': day.selected, 'c-calendar__date--today': day.today }" disabled="{ day.disabled }" each="{ day in endBuffer }" onclick="{ select }">{ day.date.format(dayFormat) }</button> + + <button type="button" class="c-button c-button--block c-button--primary" disabled="{ opts.date.min && opts.date.min.isAfter(moment(), "day") || opts.date.max && opts.date.max.isBefore(moment(), "day") }" onclick="{ setToday }">{__.today}</button> + </div> + + <script type="es6"> + + this.session = require("../../js/Session"); + + this.moment = require("moment"); + this.moment.locale(this.session.locale); + + this.installBundle(this.session, "date-picker", locale => { + this.opts.date.date.locale(locale); + this.moment.locale(locale); + }); + + let toMoment = d => { + if (!this.moment.isMoment(d)) { + d = this.moment(d); + } + if (d.isValid()) { + return d; + } + return this.moment(); + }; + + let handleClickOutside = e => { + if (!this.root.contains(e.target)) { + this.close(); + } + this.update(); + }; + + let dayObj = dayDate => { + const dateObj = dayDate || this.moment(); + + return { + date: dateObj, + selected: opts.date.date.isSame(dayDate, "day"), + today: this.moment().isSame(dayDate, "day"), + disabled: ( + opts.date.min && opts.date.min.isAfter(dayDate) || + opts.date.max && opts.date.max.isBefore(dayDate) + ) + }; + }; + + let buildCalendar = () => { + this.format = "LL"; + this.yearFormat = "YYYY"; + this.monthFormat = "MMMM"; + this.dayFormat = "DD"; + + this.days = []; + this.startBuffer = []; + this.endBuffer = []; + + const begin = this.moment(opts.date.date).startOf("month"); + const daysInMonth = this.moment(opts.date.date).daysInMonth(); + const end = this.moment(opts.date.date).endOf("month"); + + for (let i = begin.isoWeekday() - 1; i > 0; i -= 1) { + const d = this.moment(begin).subtract(i, "days"); + this.startBuffer.push(dayObj(d)); + } + + for (let i = 0; i < daysInMonth; i++) { + const current = this.moment(begin).add(i, "days"); + this.days.push(dayObj(current)); + } + + for (let i = end.isoWeekday() + 1; i <= 7; i++) { + const d = this.moment(end).add(i - end.isoWeekday(), "days"); + this.endBuffer.push(dayObj(d)); + } + }; + + this.on("mount", () => { + if (!opts.date) { + opts.date = {date: this.moment()}; + } + if (!opts.date.date) { + opts.date.date = this.moment(); + } + opts.date.date = toMoment(opts.date.date); + + if (opts.date.min) { + opts.date.min = toMoment(opts.date.min); + + if (opts.date.min.isAfter(this.moment(), "day")) { + opts.date.date = this.moment(opts.date.min); + } + } + + if (opts.date.max) { + opts.date.max = toMoment(opts.date.max); + + if (opts.date.max.isBefore(this.moment(), "day")) { + opts.date.date = this.moment(opts.date.max); + } + } + + this.on("update", () => { + opts.date.date = toMoment(opts.date.date); + buildCalendar(); + positionDropdown(); + }); + document.addEventListener("click", handleClickOutside); + this.update(); + }); + + this.on("unmount", () => { + document.removeEventListener("click", handleClickOutside); + }); + + this.open = () => { + opts.date.isvisible = true; + this.trigger("open"); + }; + + this.close = () => { + if (opts.date.isvisible) { + opts.date.isvisible = false; + this.trigger("close"); + } + }; + + this.select = e => { + opts.date.date = e.item.day.date; + this.trigger('select', opts.date.date); + }; + + this.setToday = () => { + opts.date.date = this.moment(); + this.trigger("select", opts.date.date); + }; + + this.prevYear = () => { + opts.date.date = opts.date.date.subtract(1, "year"); + }; + + this.nextYear = () => { + opts.date.date = opts.date.date.add(1, "year"); + }; + + this.prevMonth = () => { + opts.date.date = opts.date.date.subtract(1, "month"); + }; + + this.nextMonth = () => { + opts.date.date = opts.date.date.add(1, "month"); + }; + + function getWindowDimensions() { + var w = window, + d = document, + e = d.documentElement, + g = d.getElementsByTagName("body")[0], + x = w.innerWidth || e.clientWidth || g.clientWidth, + y = w.innerHeight || e.clientHeight || g.clientHeight; + return { width: x, height: y }; + }; + + const positionDropdown = () => { + const w = getWindowDimensions(); + const m = this.root.querySelector(".calendar"); + if (!m) { + return; + } + if (!opts.date.isvisible) { + // Reset position + m.style.marginTop = ""; + m.style.marginLeft = ""; + return; + } + const pos = m.getBoundingClientRect(); + if (w.width < pos.left + pos.width) { + // menu is off the right hand of the page + m.style.marginLeft = (w.width - (pos.left + pos.width) - 20) + "px"; + } + if (pos.left < 0) { + // menu is off the right hand of the page + m.style.marginLeft = "20px"; + } + if (w.height < pos.top + pos.height) { + // Popup is off the bottom of the page + m.style.marginTop = (w.height - (pos.top + pos.height) - 20) + "px"; + } + }; + </script> + + <style scoped> + date-picker { + position: relative; + display: inline-block; + cursor: pointer; + } + + .c-calendar { + position: absolute; + min-width: 300px; + margin-top: .5em; + left: 0; + } + </style> + +</date-picker> diff --git a/pollen-ui-riot-js/src/main/web/tag/components/time-picker.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/time-picker.tag.html new file mode 100644 index 0000000..8c9f9d1 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/components/time-picker.tag.html @@ -0,0 +1,240 @@ +<time-picker> + <input type="time" class="calendar-field" onclick="{open}" value="{opts.time.time.format('HH:mm')}" readonly="{!session.timeInputSupported}" /> + + <div class="c-calendar c-calendar--higher" if="{opts.time.isvisible && !session.timeInputSupported}"> + + <div class="time"> + <div class="prev action-prev" onclick={nextHour}></div> + <div class="ti_tx"><input class="timepicki-input" type="text" value="{opts.time.time.format('HH')}"></div> + <div class="next action-next" onclick={prevHour}></div> + </div> + <div class="colon"> + <div class="colon_tx">:</div> + </div> + <div class="mins"> + <div class="prev action-prev" onclick={nextMinute}></div> + <div class="mi_tx"><input class="timepicki-input" type="text" value="{opts.time.time.format('mm')}"></div> + <div class="next action-next" onclick={prevMinute}></div> + </div> + + </div> + + <script type="es6"> + let session = require("../../js/Session"); + + this.moment = require("moment"); + this.moment.locale(session.locale); + + this.installBundle(session, "time-picker", locale => { + this.opts.time.time.locale(locale); + this.moment.locale(locale); + }); + + let toMoment = d => { + if (!this.moment.isMoment(d)) { + d = this.moment(d); + } + if (d.isValid()) { + return d; + } + return this.moment(); + }; + + let handleClickOutside = e => { + if (!this.root.contains(e.target)) { + this.close(); + } + this.update(); + }; + + this.on("mount", () => { + if (!opts.time) { + opts.time = {time: this.moment()}; + } + if (!opts.time.time) { + opts.time.time = this.moment(); + } + opts.time.time = toMoment(opts.time); + + document.addEventListener("click", handleClickOutside); + }); + + this.on("unmount", () => { + document.removeEventListener("click", handleClickOutside); + }); + + this.open = () => { + opts.time.isvisible = true; + this.trigger("open"); + }; + + this.close = () => { + if (opts.time.isvisible) { + opts.time.isvisible = false; + this.trigger("close"); + } + }; + + this.select = e => { + opts.time.time = e.item.day.date; + this.trigger('select', opts.time.time); + }; + + this.prevHour = () => { + opts.time.time = opts.time.time.subtract(1, "hour"); + }; + + this.nextHour = () => { + opts.time.time = opts.time.time.add(1, "hour"); + }; + + this.prevMinute = () => { + opts.time.time = opts.time.time.subtract(1, "minute"); + }; + + this.nextMinute = () => { + opts.time.time = opts.time.time.add(1, "minute"); + }; + + function getWindowDimensions() { + var w = window, + d = document, + e = d.documentElement, + g = d.getElementsByTagName("body")[0], + x = w.innerWidth || e.clientWidth || g.clientWidth, + y = w.innerHeight || e.clientHeight || g.clientHeight; + return { width: x, height: y }; + }; + + const positionDropdown = () => { + const w = getWindowDimensions(); + const m = this.root.querySelector(".calendar"); + if (!m) { + return; + } + if (!opts.time.isvisible) { + // Reset position + m.style.marginTop = ""; + m.style.marginLeft = ""; + return; + } + const pos = m.getBoundingClientRect(); + if (w.width < pos.left + pos.width) { + // menu is off the right hand of the page + m.style.marginLeft = (w.width - (pos.left + pos.width) - 20) + "px"; + } + if (pos.left < 0) { + // menu is off the right hand of the page + m.style.marginLeft = "20px"; + } + if (w.height < pos.top + pos.height) { + // Popup is off the bottom of the page + m.style.marginTop = (w.height - (pos.top + pos.height) - 20) + "px"; + } + }; + </script> + + <style scoped> + time-picker { + position: relative; + display: inline-block; + cursor: pointer; + } + + .c-calendar { + position: absolute; + margin-top: .5em; + left: 0; + } + + + /* + Created on: 17 Sep, 2014, 4:29:37 PM + Author: senthil + */ + + .ti_tx, + .colon_tx, + .mi_tx { + width: 100%; + text-align: center; + margin: 10px 0; + } + + .time, + .colon, + .mins { + float: left; + margin: 0 10px; + font-size: 20px; + color: #2d2e2e; + font-family: arial; + font-weight: 700; + } + + .time, + .mins { + width: 60px; + } + + .prev, + .next { + cursor: pointer; + padding: 18px; + width: 28%; + border: 1px solid #ccc; + margin: auto; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAA4CAYAAAD959hAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJk [...] + border-radius: 5px; + } + + .prev:hover, + .next:hover { + background-color: #ccc; + } + + .next { + background-position: 50% 150%; + } + + .prev { + background-position: 50% -50%; + } + + .time_pick { + position: relative; + } + + .timepicker_wrap { + padding: 10px; + border-radius: 5px; + z-index: 998; + display: none; + box-shadow: 2px 2px 5px 0 rgba(50,50,50,0.35); + background: #f6f6f6; + border: 1px solid #ccc; + float: left; + position: absolute; + top: 27px; + left: 0; + } + + input.timepicki-input { + background: none repeat scroll 0 0 #FFFFFF; + border: 1px solid #CCCCCC; + border-radius: 5px 5px 5px 5px; + float: none; + margin: 0; + text-align: center; + width: 70%; + } + + a.reset_time { + float: left; + margin-top: 5px; + color: #000; + } + + </style> + +</time-picker> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html new file mode 100644 index 0000000..22a40b1 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html @@ -0,0 +1,194 @@ +require("../components/date-picker.tag.html"); +require("../components/time-picker.tag.html"); +<Choice> + <div class="choice-container"> + <button type="button" class="c-button fa fa-pencil" alt="texte" onclick="{setTextType}"/> + <input type="text" ref="choiceText" class="{choiceType === 'TEXT' ? 'selected' : 'hidden'}" value="{choiceType === 'TEXT' ? choice.choiceValue : null}"/> + + <button type="button" class="c-button fa fa-image" alt="image" onclick="{setImageType}"/> + <input type="file" ref="choiceImage" class="{choiceType === 'RESOURCE' ? 'selected' : 'hidden'}"/> + + <button type="button" class="c-button fa fa-calendar" alt="date" onclick="{setDateType}"/> + <date-picker ref="choiceDate" class="{choiceType.startsWith('DATE') ? 'selected' : 'hidden'}" date="{date}"/> + + <button type="button" class="c-button fa fa-clock-o {!choiceType.startsWith('DATE') ? 'hidden' : ''}" alt="heure" onclick="{toggleTime}"/> + <time-picker ref="choiceTime" class="{choiceType === 'DATETIME' ? 'selected' : 'hidden'}" time="{time}"/> + + <input type="hidden" ref="description" value="{choice.description}"/> + </div> + + <script type="es6"> + let session = require("../../js/Session"); + let moment = require("moment"); + moment.locale(session.locale); + let Choice = require("../../js/Choice"); + + this.installBundle(session, "choice", locale => { + moment.locale(locale); + }); + + this.number = parseInt(this.opts.number, 10); + this.mode = this.opts.mode; + this.edit = this.opts.mode === "create" || this.opts.mode === "edit"; + + if (this.opts.choiceType) { + this.choiceType = this.opts.choiceType; + } else { + this.choiceType = "TEXT"; + } + Object.assign(this.choice = {}, this.opts.choice); + if (this.choiceType === "DATE") { + this.date = { + date: moment(this.opts.choice.choiceValue) + }; + this.time = { + time: moment() + }; + } else if (this.choiceType === "DATETIME") { + this.time = { + time: moment(this.opts.choice.choiceValue) + }; + this.date = { + date: moment() + }; + } else { + this.date = { + date: moment() + }; + this.time = { + time: moment() + }; + } + + this.on("mount", () => { + if (this.number === 0 || this.mode === "edit") { + //this.refs.choice.required = "required"; + } + if (this.mode === "edit") { + //this.refs.edit_choice.classList.add("choice-view"); + } + }); + + this.setTextType = () => { + this.choiceType = "TEXT"; + }; + + this.setImageType = () => { + this.choiceType = "RESOURCE"; + }; + + this.setDateType = () => { + if (!this.choiceType.startsWith("DATE")) { + this.choiceType = "DATE"; + } + }; + + this.toggleTime = () => { + if (this.choiceType === "DATE") { + this.choiceType = "DATETIME"; + } else if (this.choiceType === "DATETIME") { + this.choiceType = "DATE"; + } + }; + + this.getValue = () => { + let choiceValue = {}; + if (this.choiceType === "TEXT") { + console.log("TEXT"); + choiceValue = this.refs.choiceText.value; + } else if (this.choiceType.startsWith("DATE")) { + choiceValue = this.refs.choiceDate.value; + } + console.log(choiceValue); + return new Choice(this.choiceType, choiceValue, this.refs.description.value, this.choice.id); + }; + + /*this.onEditChoice = () => { + this.editing = true; + let ref = this.refs.edit_choice; + ref.classList.add("choice-edit"); + ref.classList.remove("choice-view"); + this.trigger("editChoice", this.number); + Object.assign(this.$choice = {}, this.choice); + // console.info(this.$choice); + }; + + this.cancelEditChoice = () => { + if (this.editing) { + let ref = this.refs.edit_choice; + ref.classList.remove("choice-edit"); + ref.classList.add("choice-view"); + Object.assign(this.choice, this.$choice); + // console.info(this.choice); + this.refs.choice.value = this.choice.choiceValue; + this.refs.description.value = this.choice.description; + + } + this.editing = false; + this.trigger("cancelEditChoice", this.number); + }; + + this.deleteChoice = () => { + if (confirm("Delete choice?")) { + this.trigger("deleteChoice", this.number); + } + };*/ + + </script> + + <style> + + .choice-container { + display: flex; + flex-flow: row nowrap; + } + + .button { + width:auto; + opacity: 1; + margin: 0 10px 10px 10px; + transition: opacity 0.3s ease-in-out 0s, width 0s linear 0.5s; + } + + .choice-container > .hidden { + visibility: hidden; + opacity: 0; + width: 0; + border: none; + } + + .choice-container > input, + .choice-container date-picker, + .choice-container time-picker { + display: inline-block; + opacity: 1; + height: auto; + flex-grow: 0; + margin: 0; + padding: 0; + transition: width 0.5s ease-in-out 0s, + flex-grow 0s linear 0.5s, + visibility 0.5s ease-in-out 0s, + border 0s linear 0s; + } + + .choice-container > .selected { + visibility: visible; + width: 100%; + flex-grow: 1; + } + + .choice-container > input.selected, + .choice-container date-picker.selected .calendar-field, + .choice-container time-picker.selected .calendar-field { + width: 100%; + padding: 10px; + } + + time-picker { + max-width: 100px; + } + + </style> + +</Choice> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceImage.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceImage.tag.html deleted file mode 100644 index cd180bc..0000000 --- a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceImage.tag.html +++ /dev/null @@ -1,77 +0,0 @@ -<ChoiceImage> - <div id="choice-container"> - <span class="button" alt="texte" onclick="{setTextType}"><i class="fa fa-pencil" aria-hidden="true"/></span><input type="text" class="{choiceType === 'text' ? 'selected' : ''}"/> - <span class="button" alt="image" onclick="{setImageType}"><i class="fa fa-image" aria-hidden="true"/></span><input type="file" class="{choiceType === 'image' ? 'selected' : ''}"/> - <span class="button" alt="date" onclick="{setDateType}"><i class="fa fa-calendar" aria-hidden="true"/></span><input type="date" class="{choiceType.startsWith('date') ? 'selected' : ''}"/> - <span class="button {!choiceType.startsWith('date') ? 'hidden' : ''}" alt="heure" onclick="{toggleTime}"><i class="fa fa-clock-o" aria-hidden="true"/></span><input type="text" class="{choiceType === 'datetime' ? 'selected' : ''}"/> - </div> - - <script type="es6"> - this.choiceType = "text"; - - this.setTextType = () => { - this.choiceType = "text"; - }; - - this.setImageType = () => { - this.choiceType = "image"; - }; - - this.setDateType = () => { - if (!this.choiceType.startsWith("date")) { - this.choiceType = "date"; - } - }; - - this.toggleTime = () => { - if (this.choiceType === "date") { - this.choiceType = "datetime"; - } else if (this.choiceType === "datetime") { - this.choiceType = "date"; - } - }; - - </script> - - <style> - - #choice-container { - display: flex; - flex-flow: row nowrap; - } - - .button { - width:auto; - opacity: 1; - margin: 0 10px 10px 10px; - transition: opacity 0.3s ease-in-out 0s, width 0s linear 0.5s; - } - - .hidden { - visibility: hidden; - opacity: 0; - width: 0; - } - - input { - display: inline-block; - visibility: hidden; - width: 0; - height: auto; - flex-grow: 0; - margin: 0; - padding: 0; - transition: width 0.5s ease-in-out 0s, - flex-grow 0s linear 0.5s, - visibility 0.5s ease-in-out 0s; - } - - .selected { - visibility: visible; - width: 100%; - flex-grow: 1; - padding: 10px; - } - - </style> -</ChoiceImage> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceText.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceText.tag.html deleted file mode 100644 index 475df0c..0000000 --- a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceText.tag.html +++ /dev/null @@ -1,176 +0,0 @@ -/*- -* #%L -* Pollen :: UI (Riot Js) -* %% -* Copyright (C) 2009 - 2017 CodeLutin -* %% -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License as published by -* the Free Software Foundation, either version 3 of the License, or -* (at your option) any later version. -* -* This program 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 General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* #L% -*/ -<ChoiceText> - - <div class="choice-body"> - - <div class="choice-actions"> - <div show="{mode =='edit' && !editing}" id="{choice.id}"> - <a onclick="{deleteChoice}"><i class="fa fa-trash danger fa-15x"/></a> - <a onclick="{onEditChoice}"><i class="fa fa-pencil-square-o fa-15x"/></a> - </div> - <div show="{editing}"> - <a onclick="{cancelEditChoice}" class="danger"> - <i class="fa fa-remove fa-15x"/> - </a> - <button class="icon" type="submit" onclick="{prepareSave}"> - <i class="fa fa-check fa-15x"/> - </button> - </div> - </div> - <div ref="edit_choice" id="edit_choice_{number}" class="choice-container"> - <div class="choice-container-child"> - <label class="choice-wide" for="choice{number}">{__.label} {number + 1}</label> - <label class="choice-wider" if="{number == 0}">{__.description}</label> - <label class="choice-wider" if="{number > 0}"/> - </div> - <div class="choice-container-child"> - <input type="hidden" name="id{number}" value="{choice.id}"> - <div class="choice-inputs"> - <input type="text" ref="choice" name="choice{number}" value="{choice.choiceValue}" - disabled="{!edit || (mode==='edit' && !editing && choice.choiceValue)?'disabled':''}" - class="choice-wide" id="choice{number}"> - <input type="text" ref="description" name="description{number}" value="{choice.description}" - disabled="{!edit || (mode==='edit' && !editing && choice.choiceValue)?'disabled':''}" - class="choice-wider"> - </div> - </div> - </div> - </div> - - <script type="es6"> - this.installBundle(this.opts.session, "poll_choices"); - this.number = parseInt(this.opts.number, 10); - this.mode = this.opts.mode; - this.edit = this.opts.mode === "create" || this.opts.mode === "edit"; - this.choice = this.opts.choice; - this.on("mount", () => { - if (this.number === 0 || this.mode === "edit") { - this.refs.choice.required = "required"; - } - if (this.mode === "edit") { - this.refs.edit_choice.classList.add("choice-view"); - } - }); - - this.prepareSave = () => { - this.$choice = { - choiceValue: this.refs.choice.value, - description: this.refs.description.value - }; - }; - this.onEditChoice = () => { - this.editing = true; - let ref = this.refs.edit_choice; - ref.classList.add("choice-edit"); - ref.classList.remove("choice-view"); - this.trigger("editChoice", this.number); - Object.assign(this.$choice = {}, this.choice); - // console.info(this.$choice); - }; - - this.cancelEditChoice = () => { - if (this.editing) { - let ref = this.refs.edit_choice; - ref.classList.remove("choice-edit"); - ref.classList.add("choice-view"); - Object.assign(this.choice, this.$choice); - // console.info(this.choice); - this.refs.choice.value = this.choice.choiceValue; - this.refs.description.value = this.choice.description; - - } - this.editing = false; - this.trigger("cancelEditChoice", this.number); - }; - - this.deleteChoice = () => { - if (confirm("Delete choice?")) { - this.trigger("deleteChoice", this.number); - } - }; - - </script> - - <style> - - .icon { - border-style: none; - background-color: white; - cursor: pointer; - color: #13a2ff; - } - - .danger { - color: red; - } - - .choice-wide { - width: 440px; - } - - .choice-wider { - width: 640px; - } - - .choice-actions { - padding-right: 5px; - } - - .choice-body { - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: center; - } - - .choice-container { - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - } - - .choice-container-child { - display: flex; - } - - .choice-inputs { - display: flex; - flex-direction: row; - justify-content: flex-start; - align-items: center; - } - - .choice-edit { - border: 2px solid #13a2ff; - } - - .choice-view { - border: 2px solid white; - } - - input[disabled=disabled] { - cursor: not-allowed; - } - - </style> -</ChoiceText> diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Choices.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Choices.tag.html index 5e71e43..c13fd0c 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Choices.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Choices.tag.html @@ -1,7 +1,4 @@ -require("./ChoiceText.tag.html"); -require("./ChoiceText.tag.html"); -require("./ChoiceDate.tag.html"); -require("./ChoiceImage.tag.html"); +require("./Choice.tag.html"); <Choices> <div each={choice, index in form.choices} class="o-form-element" @@ -9,11 +6,10 @@ require("./ChoiceImage.tag.html"); <div class="c-input-group c-input-group--rounded-left"> <div class="o-field o-field--icon-left"> <i class="c-icon">{index + 1}</i> - <input ref={"choice" + index} + <Choice ref={"choice" + index} class="c-field" - type="text" - name="name" - value="{choice.choiceValue}"> + name={"choice" + index} + choice="{choice}"/> </div> <button type="button" class="c-button c-button--ghost-error" @@ -42,10 +38,10 @@ require("./ChoiceImage.tag.html"); this.submit = () => { this.form.choices.forEach((choice, index) => { - choice.choiceValue = this.refs["choice" + index].value; + let editedChoice = this.refs["choice" + index].getValue(); + Object.assign(choice, editedChoice); }); }; - </script> <style> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm