Alain HIRSCH:
This should be a standard feature of the vaadin component.
I hope it will be done in the future.
But if you want a quickly solution, i was working on this to train me on vaadin 10 and polymer.
i made a subclass to add the time feature to the vaadin date picker.
here is my code.
should work. But you will need to adapt for your use.
I used in french format (dd/mm/yyyy HH:mm)
client side :
<dom-module id="custom-date-picker">
<template>
</template>
<script>
class CustomDatePicker extends Vaadin.DatePickerElement {
static get is() { return 'custom-date-picker'}
static get template() {
return Vaadin.DatePickerElement.template;
}
static get observers() {
return [
'textUpdateEvent(_userInputValue)'
];
}
static get properties() {
return {
/**
* Set to false to disable this element.
*/
showTime: {
type: Boolean,
value: true,
reflectToAttribute: true
},
hour: {
type: String,
value: '00',
reflectToAttribute: true
},
minute: {
type: String,
value: '00',
reflectToAttribute: true
},
_saveSelectedDate: {
type: Date
},
_selectHour: {
type: Object
},
_selectMinute: {
type: Object
},
_lastTime: {
type: String
} ,
_oldValue: {
type: String
},
_changeTxtManual: {
type: Boolean,
value: false
}
}
}
_clear() {
this._saveSelectedDate = null;
super._clear();
}
ready(){
super.ready();
//French
super.set('i18n.firstDayOfWeek', 1);
super.set('i18n.monthNames', ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Aout', 'Septembre', 'Octobre', 'Novembre', 'Décembre']
);
super.set('i18n.week', 'semaine');
super.set('i18n.weekdays', ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi']
);
super.set('i18n.weekdaysShort', ['di','lu','ma','me','je','ve','sa']
);
super.set('i18n.calendar', 'calendrier');
super.set('i18n.clear', 'Effacer');
super.set('i18n.today', 'Aujourd\'hui');
super.set('i18n.cancel', 'Annuler');
}
_setTimeFeature(){
//Add time feature
var tmp = document.createElement('div');
//TODO Put style in template
tmp.innerHTML = '<div style="width: 120px;margin: auto;" class="cdp_TimeChooser"><select id="cdp_hour"></select>:<select id="cdp_minute"></select></div>';
Polymer.dom(this.root).querySelector("vaadin-date-picker-overlay").root.querySelector("vaadin-date-picker-overlay-content").root.appendChild(tmp);
this._selectHour = Polymer.dom(this.root).querySelector("vaadin-date-picker-overlay").root.querySelector("vaadin-date-picker-overlay-content").root.querySelector('#cdp_hour');
this._selectMinute = Polymer.dom(this.root).querySelector("vaadin-date-picker-overlay").root.querySelector("vaadin-date-picker-overlay-content").root.querySelector('#cdp_minute');
for(let i = 0; i < 24; i++){
var tmp_option = document.createElement('option');
tmp_option.innerHTML = '<option value="' + i + '">' + (i < 10 ? '0' + i : i) + '</option>';
this._selectHour.append(tmp_option);
}
for(let i = 0; i < 60; i++){
var tmp_option = document.createElement('option');
tmp_option.innerHTML = '<option value="' + i + '">' + (i < 10 ? '0' + i : i) + '</option>';
this._selectMinute.append(tmp_option);
}
//Events change
this._selectHour.addEventListener('change', this._onHourChange.bind(this));
this._selectMinute.addEventListener('change', this._onMinuteChange.bind(this));
}
_onHourChange(event){
if(! this._changeTxtManual){
this.hour = event.target.value;
if(this.showTime && super._userInputValue.length == 16){
super._userInputValue = super._userInputValue.substr(0, 11) + this.hour + ':' + super._userInputValue.substr(14,2);
}
}
}
_onMinuteChange(event){
if(! this._changeTxtManual){
this.minute = event.target.value;
if(this.showTime && super._userInputValue.length == 16){
super._userInputValue = super._userInputValue.substr(0, 14) + this.minute;
}
}
}
validate(value) {
value = value !== undefined ? value : this._inputValue;
if(value.length > 10){
value = value.substr(0, 10);
}
if(this._saveSelectedDate){
super._selectedDate = this._saveSelectedDate;
}
else{
//Need to parse date here.
}
return super.validate(value);
}
textUpdateEvent(_userInputValue){
//Time
if(this.showTime && _userInputValue.length == 10){
this._saveSelectedDate = super._selectedDate;
super._userInputValue = _userInputValue + ' ' + this.hour + ':' + this.minute;
}
if(this.showTime && super._userInputValue.length == 16 && (! this._lastTime || this._lastTime !== super._userInputValue)){
this._lastTime = super._userInputValue;
this.$server.clientSetDateTime(super._userInputValue);
this.updateSelectTime();
}
}
setDateTime(dateTime){
super._userInputValue = dateTime;
this.updateSelectTime();
}
updateSelectTime(){
this.hour = super._userInputValue.substr(11, 2);
this.minute = super._userInputValue.substr(14, 2);
var h = parseInt(this.hour);
var m = parseInt(this.minute);
this._changeTxtManual = true;
this._selectHour.options[h]
.selected = true;
this._selectMinute.options[m]
.selected = true;
this._changeTxtManual = false;
}
}
customElements.define(CustomDatePicker.is, CustomDatePicker);
```
server side :
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import com.vaadin.flow.component.ClientDelegate;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dependency.HtmlImport;
@Tag("custom-date-picker")
@HtmlImport("frontend://src/composants/CustomDatePicker.html")
public class CustomDatePicker extends DatePicker{
private static final long serialVersionUID = 1L;
public static String formatDay = "dd/MM/yyyy";
public static String formatDayHour = "dd/MM/yyyy HH:mm";
public static DateTimeFormatter patternDay = DateTimeFormatter.ofPattern(formatDay);
public static DateTimeFormatter patterDayHour = DateTimeFormatter.ofPattern(formatDayHour);
String dateTime = null;
boolean time;
public CustomDatePicker() {
this(false);
}
public CustomDatePicker(boolean time) {
setWidth("210px");
if(time){
this.getElement().callFunction("_setTimeFeature");
}
}
public void setDateTime(String dateTime){
setValue(LocalDate.parse(dateTime.substring(0, 10), patternDay));
if(dateTime.length() == formatDayHour.length()){
this.getElement().callFunction("setDateTime", dateTime);
}
this.dateTime = dateTime;
}
public void setDateTime(LocalDateTime dateTime){
setDateTime(dateTime.format(patterDayHour));
}
public String getDateTimeString(){
return dateTime;
}
public LocalDateTime getDateTime(){
return LocalDateTime.parse(dateTime, patterDayHour);
}
@ClientDelegate
private void clientSetDateTime(String time){
this.dateTime = time;
}
}
you can see the result in the attached image below
Time field not shown at all and I get this error in console:
Uncaught TypeError: Cannot read property ‘options’ of undefined
at HTMLElement.updateSelectTime (date-time-picker.html:188)
> this line: this._selectHour.options[h]
.selected = true;