This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit f3b7d92b6aeef037b64e07d075c62d6736f7eaac Author: Kevin Morin <morin@codelutin.com> Date: Tue May 30 11:58:43 2017 +0200 use a datetime component for the browsers which do not support datetime inputs --- pollen-ui-riot-js/src/main/web/i18n.json | 22 +++--- pollen-ui-riot-js/src/main/web/js/UIHelper.js | 2 +- .../main/web/tag/components/date-picker.tag.html | 37 +++++++--- .../web/tag/components/date-time-picker.tag.html | 78 ++++++++++++++++++++++ .../main/web/tag/components/time-picker.tag.html | 67 ++++++++++++------- .../src/main/web/tag/poll/Settings.tag.html | 67 +++++++++---------- 6 files changed, 195 insertions(+), 78 deletions(-) diff --git a/pollen-ui-riot-js/src/main/web/i18n.json b/pollen-ui-riot-js/src/main/web/i18n.json index 96af58c..73fb377 100644 --- a/pollen-ui-riot-js/src/main/web/i18n.json +++ b/pollen-ui-riot-js/src/main/web/i18n.json @@ -120,7 +120,7 @@ "signup_email": "Email", "signup_email_placeholder": "Entrez votre adresse email", "signup_name": "Nom", - "signup_name_placeholder": "Entrez votre nom d'utilisateur", + "signup_name_placeholder": "Entrez votre nom", "signup_password": "Mot de passe", "signup_password_placeholder": "Entrez votre mot de passe", "signup_repeat_password": "Confirmation du mot de passe", @@ -136,7 +136,7 @@ "resendvalidation_title": "Renvoyer un courriel de validation de compte", "resendvalidation_cancel": "Annuler", "resendvalidation_action": "Envoyer", - "resendvalidation_placeholder": "Entrer votre courriel", + "resendvalidation_placeholder": "Entrez votre courriel", "resendvalidation_sent": "Un nouveau courriel d'invitation a été envoyé", "resendvalidation_error_emailNotFound": "Le courriel n'a pas été trouvé", "signcheck_title": "Validation de votre compte", @@ -148,15 +148,15 @@ "signcheck_validating_success": "Votre compte a été validé. Vous pouvez vous connecter.", "signin_title": "Connexion", "signin_login": "Email", - "signin_login_placeholder": "Entrer l'email", + "signin_login_placeholder": "Entrez votre email", "signin_password": "Mot de passe", - "signin_password_placeholder": "Entrer le mot de passe", + "signin_password_placeholder": "Entrez votre mot de passe", "signin_lostpassword": "Mot de passe perdu ?", "signin_connexion": "Se connecter", "signin_error_signin": "Courriel ou de mot de passe invalide", "newpassword_title": "Obtenir un nouveau mot de passe", "newpassword_action": "Envoyer", - "newpassword_placeholder": "Entrer votre courriel", + "newpassword_placeholder": "Entrez votre courriel", "newpassword_error_emailNotFound": "Le courriel n'a pas été trouvé", "newpassword_sent": "Un nouveau mot de passe vient d'être envoyé", "footer_doc": "Pollen 3.0", @@ -338,6 +338,8 @@ "userProfile_savePassword": "Enregistrer", "choice_description_placeholder": "Vous pouvez saisir une description", "date-picker_today": "Aujourd'hui", + "date-picker_dateplaceholder": "Date", + "time-picker_timeplaceholder": "Heure", "choice_text": "Renseignez un text", "choice_text_placeholder": "Renseignez un text ou sélectionnez un autre type", "choice_ressource": "Utiliser une image", @@ -552,7 +554,7 @@ "signup_email": "Email", "signup_email_placeholder": "Enter your email", "signup_name": "User name", - "signup_name_placeholder": "Entrer your user name", + "signup_name_placeholder": "Enter your name", "signup_password": "Password", "signup_password_placeholder": "Enter you password", "signup_repeat_password": "Password confirmation", @@ -580,9 +582,9 @@ "resendvalidation_error_emailNotFound": "Your email was not found", "signin_title": "Connexion", "signin_login": "Email", - "signin_login_placeholder": "Entrer your email", + "signin_login_placeholder": "Enter your email", "signin_password": "Password", - "signin_password_placeholder": "Entrer your password", + "signin_password_placeholder": "Enter your password", "signin_lostpassword": "Lost password?", "signin_connexion": "Connect", "signin_error_signin": "Email or password invalid", @@ -742,7 +744,7 @@ "userProfile_title": "My profile", "userProfile_identity": "Identity", "userProfile_name": "Name", - "userProfile_name_placeholder": "Entrer your user name", + "userProfile_name_placeholder": "Enter your user name", "userProfile_email": "Email", "userProfile_email_placeholder": "Enter your email", "userProfile_emailValidate": "Validate", @@ -760,6 +762,8 @@ "userProfile_savePassword": "Save", "choice_description_placeholder": "You can enter a description", "date-picker_today": "Today", + "date-picker_dateplaceholder": "Date", + "time-picker_timeplaceholder": "Time", "choice_text": "Set a text", "choice_ressource": "Use image", "choice_addFile": "Add image", diff --git a/pollen-ui-riot-js/src/main/web/js/UIHelper.js b/pollen-ui-riot-js/src/main/web/js/UIHelper.js index 91aa645..ff0c963 100644 --- a/pollen-ui-riot-js/src/main/web/js/UIHelper.js +++ b/pollen-ui-riot-js/src/main/web/js/UIHelper.js @@ -47,7 +47,7 @@ module.exports = { return ""; }, - formatDateForInput(date) { + formatDateTimeForInput(date) { return this.formatDate(date, "YYYY-MM-DDTHH:mm"); }, 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 index de149ab..baaf0a2 100644 --- 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 @@ -1,18 +1,21 @@ <date-picker> + <i if={opts.iconleftclass} class="fa fa-fw fa-{opts.iconleftclass} c-icon"></i> <input type="date" - class="calendar-field" + class="calendar-field {opts.inputclass}" required={opts.required} onclick="{open}" - value={opts.date.date.format(session.dateInputSupported ? "YYYY-MM-DD" : format)} + value={opts.date.date ? opts.date.date.format(session.dateInputSupported ? "YYYY-MM-DD" : format) : undefined} + placeholder="{__.dateplaceholder}" readonly="{!session.dateInputSupported}" + disabled={opts.disabled} onchange={onDateChange}/> <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> + <div class="c-calendar__header">{ opts.date.date ? opts.date.date.format(yearFormat) : moment().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> + <div class="c-calendar__header">{ opts.date.date ? opts.date.date.format(monthFormat) : moment().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> @@ -38,11 +41,16 @@ this.moment.locale(this.session.locale); this.installBundle(this.session, "date-picker", locale => { - this.opts.date.date.locale(locale); + if (this.opts.date.date) { + this.opts.date.date.locale(locale); + } this.moment.locale(locale); }); let toMoment = d => { + if (!d) { + return undefined; + } if (!this.moment.isMoment(d)) { d = this.moment(d); } @@ -64,7 +72,7 @@ return { date: dateObj, - selected: this.opts.date.date.isSame(dayDate, "day"), + selected: this.opts.date.date && this.opts.date.date.isSame(dayDate, "day"), today: this.moment().isSame(dayDate, "day"), disabled: ( this.opts.date.min && this.opts.date.min.isAfter(dayDate) || @@ -105,9 +113,9 @@ this.on("mount", () => { if (!this.opts.date) { - this.opts.date = {date: this.moment()}; + this.opts.date = {}; } - if (!this.opts.date.date) { + if (!this.opts.date.date && this.opts.required) { this.opts.date.date = this.moment(); } this.opts.date.date = toMoment(this.opts.date.date); @@ -164,23 +172,36 @@ }; this.prevYear = () => { + this.initDate(); this.opts.date.date = this.opts.date.date.subtract(1, "year"); }; this.nextYear = () => { + this.initDate(); this.opts.date.date = this.opts.date.date.add(1, "year"); }; this.prevMonth = () => { + this.initDate(); this.opts.date.date = this.opts.date.date.subtract(1, "month"); }; this.nextMonth = () => { + this.initDate(); this.opts.date.date = this.opts.date.date.add(1, "month"); }; this.onDateChange = (e) => { this.opts.date.date = toMoment(e.currentTarget.valueAsNumber); + if (this.opts.onchange) { + this.opts.onchange(e); + } + }; + + this.initDate = () => { + if (!this.opts.date.date) { + this.opts.date.date = this.moment(); + } }; </script> diff --git a/pollen-ui-riot-js/src/main/web/tag/components/date-time-picker.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/date-time-picker.tag.html new file mode 100644 index 0000000..489fee0 --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/components/date-time-picker.tag.html @@ -0,0 +1,78 @@ +require("./date-picker.tag.html"); +require("./time-picker.tag.html"); + +<date-time-picker> + <div if={!session.dateInputSupported} class="c-input-group"> + <date-picker class="o-field o-field--icon-left" + inputclass="c-field o-field--icon-left" + iconleftclass="calendar" + required={opts.required} + disabled={opts.disabled} + date="{date}" + onchange="{opts.onchange}"> + </date-picker> + <time-picker class="o-field o-field--icon-left" + inputclass="c-field" + iconleftclass="clock-o" + required={opts.required} + disabled={opts.disabled} + time="{time}" + onchange="{opts.onchange}"/> + <button if="{!opts.required}" + class="c-button c-button--brand input-right-button" + disabled={opts.disabled} + onclick="{reset}"> + <i class="fa fa-fw fa-times"></i> + </button> + </div> + <input if={session.dateInputSupported} + class="c-field" + ref="dateInputSupportedField" + value="{dateTime}" + type="datetime-local" + required={opts.required} + disabled={opts.disabled} + pattern={DATETIME_INPUT_PATTERN} + min={opts.min} + max={opts.max} + /> + + <script type="es6"> + this.session = require("../../js/Session"); + let moment = require("moment"); + moment.locale(this.session.locale); + this.dateTime = this.formatDateTimeForInput(this.opts.datetime); + var timestamp =this.opts.datetime; + this.date = {date: this.opts.datetime ? moment(timestamp) : undefined}; + this.time = {time: this.opts.datetime ? moment(timestamp) : undefined}; + + this.getValue = () => { + if (this.session.dateInputSupported) { + return this.refs.dateInputSupportedField.value; + } + if (!this.date.date || !this.time.time) { + return null; + } + let selectedMoment = moment({ + year: this.date.date.year(), + month: this.date.date.month(), + day: this.date.date.date(), + hour: this.time.time.hour(), + minute: this.time.time.minute() + }); + return this.formatDateTimeForInput(selectedMoment.valueOf()); + }; + + this.reset = () => { + this.date.date = undefined; + this.time.time = undefined; + }; + </script> + + <style scoped> + .input-right-button { + padding: 0; + } + </style> + +</date-time-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 index 4e5c9dc..0e0e13f 100644 --- 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 @@ -1,16 +1,19 @@ <time-picker> + <i if={opts.iconleftclass} class="fa fa-fw fa-{opts.iconleftclass} c-icon"></i> <input type="time" - class="calendar-field" + class="calendar-field {opts.inputclass}" onclick="{open}" - value="{opts.time.time.format('LT')}" + value="{opts.time.time ? opts.time.time.format('LT') : undefined}" + placeholder="{__.timeplaceholder}" readonly="{!session.timeInputSupported}" + disabled={opts.disabled} required={opts.required} onblur={onTimeChange}/> <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="ti_tx"><input class="timepicki-input" type="text" readonly value="{opts.time.time ? opts.time.time.format('HH') : moment().format('HH')}"></div> <div class="next action-next" onclick={prevHour}></div> </div> <div class="colon"> @@ -18,7 +21,7 @@ </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="mi_tx"><input class="timepicki-input" type="text" readonly value="{opts.time.time ? opts.time.time.format('mm') : moment().format('mm')}"></div> <div class="next action-next" onclick={prevMinute}></div> </div> @@ -30,11 +33,16 @@ this.moment.locale(this.session.locale); this.installBundle(this.session, "time-picker", locale => { - this.opts.time.time.locale(locale); + if (this.opts.time.time) { + this.opts.time.time.locale(locale); + } this.moment.locale(locale); }); let toMoment = d => { + if (!d) { + return undefined; + } if (!this.moment.isMoment(d)) { d = this.moment(d); } @@ -53,9 +61,9 @@ this.on("mount", () => { if (!this.opts.time) { - this.opts.time = {time: this.moment()}; + this.opts.time = {}; } - if (!this.opts.time.time) { + if (!this.opts.time.time && this.opts.required) { this.opts.time.time = this.moment(); } this.opts.time.time = toMoment(this.opts.time.time); @@ -82,47 +90,59 @@ this.opts.time.isVisible = false; this.trigger("close"); } - }; - - this.select = e => { - this.opts.time.time = e.item.day.date; - this.trigger("select", this.opts.time.time); + if (this.opts.onchange) { + this.opts.onchange(); + } }; this.prevHour = () => { + this.initTime(); this.opts.time.time = this.opts.time.time.subtract(1, "hour"); }; this.nextHour = () => { + this.initTime(); this.opts.time.time = this.opts.time.time.add(1, "hour"); }; this.prevMinute = () => { + this.initTime(); this.opts.time.time = this.opts.time.time.subtract(1, "minute"); }; this.nextMinute = () => { + this.initTime(); this.opts.time.time = this.opts.time.time.add(1, "minute"); }; this.onTimeChange = e => { - var time = this.moment(e.currentTarget.value, "HH:mm"); - this.opts.time.time.set({hour: time.hour(), minute: time.minute()}); + if (e.currentTarget.value) { + var time = this.moment(e.currentTarget.value, "HH:mm"); + this.initTime(); + this.opts.time.time.set({hour: time.hour(), minute: time.minute()}); + } + }; + + this.initTime = () => { + if (!this.opts.time.time) { + this.opts.time.time = this.moment(); + } }; </script> <style scoped> time-picker { - position: relative; - display: inline-block; - cursor: pointer; + position: relative; + display: inline-block; + cursor: pointer; } .c-calendar { - position: absolute; - margin-top: .5em; - left: 0; + position: absolute; + margin-top: .5em; + left: 0; + min-width: 205px; } @@ -198,13 +218,14 @@ } input.timepicki-input { - background: none repeat scroll 0 0 #FFFFFF; - border: 1px solid #CCCCCC; - border-radius: 5px 5px 5px 5px; + background: none repeat scroll 0 0 #FFFFFF; + border: none; float: none; margin: 0; text-align: center; width: 70%; + outline: 0; + font-size: 1em; } a.reset_time { diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html index 4714775..30680c3 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Settings.tag.html @@ -18,6 +18,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ +require("../components/date-time-picker.tag.html"); + <Settings> <div class="form-section" show={form.creation}> @@ -105,27 +107,21 @@ <label class="c-label" for="beginChoiceDate"> {__.beginChoiceDate} </label> - <input ref="beginChoiceDate" - name="beginChoiceDate" - id="beginChoiceDate" - class="c-field" - disabled={form.hasVotes || opts.form.model.isClosed} - value={form.model.beginChoiceDate} - type="datetime-local" - pattern={DATETIME_INPUT_PATTERN}> + <date-time-picker ref="beginChoiceDate" + name="beginChoiceDate" + id="beginChoiceDate" + datetime={form.model.beginChoiceDate} + disabled={form.hasVotes || opts.form.model.isClosed}/> </div> <div class="o-form-element"> <label class="c-label" for="endChoiceDate"> {__.endChoiceDate} </label> - <input ref="endChoiceDate" - name="endChoiceDate" - id="endChoiceDate" - class="c-field" - disabled={form.hasVotes || opts.form.model.isClosed} - value={form.model.endChoiceDate} - type="datetime-local" - pattern={DATETIME_INPUT_PATTERN}> + <date-time-picker ref="endChoiceDate" + name="endChoiceDate" + id="endChoiceDate" + datetime={form.model.endChoiceDate} + disabled={form.hasVotes || opts.form.model.isClosed}/> </div> </div> <div show="{canLimitNumberOfChoices}" class="o-form-element"> @@ -171,7 +167,7 @@ name="votePeriod" id="votePeriod" ref="votePeriod" - checked={form.model.beginDate || form.model.endDate} + checked={form.model.votePeriod} disabled={opts.form.model.isClosed} onclick="{toggleVotePeriod}"> <div class="c-toggle__track"> @@ -184,28 +180,23 @@ <label class="c-label" for="beginDate"> {__.beginDate} </label> - <input ref="beginDate" + <date-time-picker ref="beginDate" name="beginDate" id="beginDate" - disabled={!form.hasVotes || opts.form.model.isClosed} - value={formatDateForInput(form.model.beginDate)} - class="c-field" - type="datetime-local" - pattern={DATETIME_INPUT_PATTERN}> + disabled={form.hasVotes || opts.form.model.isClosed} + datetime={form.model.beginDate}/> </div> <div class="o-form-element"> <label class="c-label" for="endDate"> {__.endDate} </label> - <input ref="endDate" - name="endDate" - id="endDate" - value={formatDateForInput(form.model.endDate)} - disabled={opts.form.model.isClosed} - class="c-field" - type="datetime-local" - pattern={DATETIME_INPUT_PATTERN} - onchange="{onEndDateChanged}"> + <date-time-picker ref="endDate" + name="endDate" + id="endDate" + datetime={form.model.endDate} + disabled={opts.form.model.isClosed} + min={refs.beginDate.value} + onchange="{onEndDateChanged}"/> </div> </div> <div class="o-form-element"> @@ -371,8 +362,9 @@ }; this.updateDisableNotifyMeBeforePollEnds = () => { - this.disableNotifyMeBeforePollEnds = !this.form.model.creatorEmail || !this.form.model.votePeriod || !this.refs.endDate.value; + this.disableNotifyMeBeforePollEnds = !this.form.model.creatorEmail || !this.form.model.votePeriod || !this.refs.endDate.getValue(); this.notifyMeBeforePollEnds &= !this.disableNotifyMeBeforePollEnds; + this.update(); }; this.toggleChoiceAddAllowed = () => { @@ -426,25 +418,26 @@ }; this.submit = () => { + if (!this.showOptions && this.form.creation) { this.form.setSettingsDefault(); } else { if (!this.form.hasVotes) { this.form.model.addChoices = this.refs.addChoices.checked; - this.form.model.beginChoiceDate = this.refs.addChoices.checked ? this.refs.beginChoiceDate.value : undefined; - this.form.model.endChoiceDate = this.refs.addChoices.checked ? this.refs.endChoiceDate.value : undefined; + this.form.model.beginChoiceDate = this.refs.addChoices.checked ? this.refs.beginChoiceDate.getValue() : undefined; + this.form.model.endChoiceDate = this.refs.addChoices.checked ? this.refs.endChoiceDate.getValue() : undefined; this.form.model.maxChoiceNumber = this.refs.limitChoices.checked ? this.refs.maxChoiceNumber.value : undefined; this.form.model.voteCountingType = this.refs.voteCountingType.value; - this.form.model.beginDate = this.refs.votePeriod.checked ? this.refs.beginDate.value : undefined; + this.form.model.beginDate = this.refs.votePeriod.checked ? this.refs.beginDate.getValue() : undefined; this.form.model.voteVisibility = this.refs.voteVisibility.value; this.form.model.anonymousVoteAllowed = this.refs.anonymousVote.checked; this.form.model.resultVisibility = this.refs.resultVisibility.value; this.form.model.commentVisibility = this.refs.commentVisibility.value; } - this.form.model.endDate = this.refs.votePeriod.checked ? this.refs.endDate.value : undefined; + this.form.model.endDate = this.refs.votePeriod.checked ? this.refs.endDate.getValue() : undefined; this.form.model.continuousResults = this.refs.continuousResults.checked; this.form.model.voteNotification = this.refs.voteNotification.value; -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.