Dziwię się, że istnieje tylko jedna odpowiedź z podejściem podobnym do tego, którego użyłem.
Inspirację zaczerpnąłem z komentarza @ Dtipson na temat odpowiedzi @Mumthezir VP.
Używam do tego dwóch wejść, jedno to fałszywe wejście, type="text"
na którym ustawiam symbol zastępczy, drugie to prawdziwe pole type="date"
.
W mouseenter
przypadku wydarzenia na ich kontenerze ukrywam fałszywe dane wejściowe i pokazuję prawdziwe, a na mouseleave
wydarzeniu robię odwrotnie . Oczywiście pozostawiam widoczne wejście rzeczywiste, jeśli ma ustawioną wartość.
Napisałem kod, aby używać czystego Javascript, ale jeśli używasz jQuery (tak), bardzo łatwo jest go „przekonwertować”.
// "isMobile" function taken from this reply:
// https://stackoverflow.com/a/20293441/3514976
function isMobile() {
try { document.createEvent("TouchEvent"); return true; }
catch(e) { return false; }
}
var deviceIsMobile = isMobile();
function mouseEnterListener(event) {
var realDate = this.querySelector('.real-date');
// if it has a value it's already visible.
if(!realDate.value) {
this.querySelector('.fake-date').style.display = 'none';
realDate.style.display = 'block';
}
}
function mouseLeaveListener(event) {
var realDate = this.querySelector('.real-date');
// hide it if it doesn't have focus (except
// on mobile devices) and has no value.
if((deviceIsMobile || document.activeElement !== realDate) && !realDate.value) {
realDate.style.display = 'none';
this.querySelector('.fake-date').style.display = 'block';
}
}
function fakeFieldActionListener(event) {
event.preventDefault();
this.parentElement.dispatchEvent(new Event('mouseenter'));
var realDate = this.parentElement.querySelector('.real-date');
// to open the datepicker on mobile devices
// I need to focus and then click on the field.
realDate.focus();
realDate.click();
}
var containers = document.getElementsByClassName('date-container');
for(var i = 0; i < containers.length; ++i) {
var container = containers[i];
container.addEventListener('mouseenter', mouseEnterListener);
container.addEventListener('mouseleave', mouseLeaveListener);
var fakeDate = container.querySelector('.fake-date');
// for mobile devices, clicking (tapping)
// on the fake input must show the real one.
fakeDate.addEventListener('click', fakeFieldActionListener);
// let's also listen to the "focus" event
// in case it's selected using a keyboard.
fakeDate.addEventListener('focus', fakeFieldActionListener);
var realDate = container.querySelector('.real-date');
// trigger the "mouseleave" event on the
// container when the value changes.
realDate.addEventListener('change', function() {
container.dispatchEvent(new Event('mouseleave'));
});
// also trigger the "mouseleave" event on
// the container when the input loses focus.
realDate.addEventListener('blur', function() {
container.dispatchEvent(new Event('mouseleave'));
});
}
.real-date {
display: none;
}
/* a simple example of css to make
them look like it's the same element */
.real-date,
.fake-date {
width: 200px;
height: 20px;
padding: 0px;
}
<div class="date-container">
<input type="text" class="fake-date" placeholder="Insert date">
<input type="date" class="real-date">
</div>
Przetestowałem to również na telefonie z Androidem i działa, gdy użytkownik dotknie pola, pojawi się datapicker. Jedyną rzeczą jest to, że jeśli rzeczywiste dane wejściowe nie mają wartości, a użytkownik zamyka DatePicker bez wybierania daty, dane wejściowe pozostaną widoczne, dopóki nie dotkną poza nim. Nie ma żadnego wydarzenia, którego można by słuchać, aby wiedzieć, kiedy datapicker zostanie zamknięty, więc nie wiem, jak to rozwiązać.
Nie mam urządzenia z systemem iOS, na którym mogę to przetestować.