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 d94a8fac7409b17638c0ef37ac1aa2f1d5bce0b2 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 494447a..7d7b0f8 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -228,7 +228,7 @@ "users_VALIDATION": "En cours de validation", "users_DISABLED": "Désactivé", "users_BANNED": "Banni", - "": "" + "date-picker_today": "Aujourd'hui" }, "en": { "pagination_page": "Page", @@ -453,6 +453,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 d0d9b5c..6306730 100644 --- a/pollen-ui-riot-js/src/main/web/js/Session.js +++ b/pollen-ui-riot-js/src/main/web/js/Session.js @@ -52,6 +52,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>.