[html] How do I simulate placeholder functionality on input date field?

It's impossible to use placeholder on date fields but I really need it.

I want two date inputs with texts "From" and "To" on each one as placeholders.

This question is related to html

The answer is


Got the most easiest hack for this problem-use this syntax in your HTML-input-tag

      <input type="text" id="my_element_id" placeholder="select a date" name="my_element_name" onfocus="(this.type='date')" />
      </div>

The input[type="date"] DOMElement only takes the following value: YYYY-MM-DD, any other format or text with be skipped.

Live Demo

HTML

<input type="text" placeholder="bingo" />
<input type="date" placeholder="2013-01-25" />

Pure JavaScript

window.onload = function () {
    /* Grab all elements with a placeholder attribute */
    var element = document.querySelectorAll('[placeholder]');

    /* Loop through each found elements */
    for (var i in element) {
        /* If the element is a DOMElement and has the nodeName "INPUT" */
        if (element[i].nodeType == 1 && element[i].nodeName == "INPUT") {

            /* We change the value of the element to its placeholder attr value */
            element[i].value = element[i].getAttribute('placeholder');
            /* We change its color to a light gray */
            element[i].style.color = "#777";

            /* When the input is selected/clicked on */
            element[i].onfocus = function (event) {
                /* If the value within it is the placeholder, we clear it */
                if (this.value == this.getAttribute('placeholder')) {
                    this.value = "";
                    /* Setting default text color */
                    this.style.color = "#000";
                };
            };

            /* We the input is left */
            element[i].onblur = function (event) {
                /* If the field is empty, we set its value to the placeholder */
                if (this.value == "") {
                    this.value = this.getAttribute('placeholder');
                    this.style.color = "#777";
                }
            };
        }
    }
}

Performance review

In this exact case, with 2 input elements, Pure JavaScript is ~40% ± 10% faster.

With 32 input elements, the difference remains the same (~43% ± 10% faster for Pure JS).


Try this:

Add a placeholder attribute to your field with the value you want, then add this jQuery:

$('[placeholder]').each(function(){
    $(this).val($(this).attr('placeholder'));
  }).focus(function(){
    if ($(this).val() == $(this).attr('placeholder')) { $(this).val(''); }
  }).blur(function(){
    if ($(this).val() == '') { $(this).val($(this).attr('placeholder')); }
  });

I've not tested it for fields that can't take placeholders but you shouldn't need to change anything in the code at all.

On another note, this code is also a great solution for browsers that don't support the placeholder attribute.


Using a jQuery (sure you can achieve this with Vanilla. This make sure the date format still the same.

_x000D_
_x000D_
$(function() {_x000D_
  $('.sdate').on('focus', function() {_x000D_
    $(this).attr('type', 'date');_x000D_
  });_x000D_
  $('.sdate').on('blur', function() {_x000D_
    if(!$(this).val()) { // important_x000D_
      $(this).attr('type', 'text');_x000D_
    }_x000D_
  });_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>_x000D_
_x000D_
<input type="text" class="sdate" placeholder="From">
_x000D_
_x000D_
_x000D_


use this input attribute events

onfocus="(this.type='date')" onblur="(this.type='text')"

_x000D_
_x000D_
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">_x000D_
_x000D_
<div class="container mt-3">_x000D_
  <label for="date">Date : </label>_x000D_
  <input placeholder="Your Date" class="form-control" type="text" onfocus="(this.type='date')" onblur="(this.type='text')" id="date">_x000D_
</div>
_x000D_
_x000D_
_x000D_


CSS

_x000D_
_x000D_
input[type="date"] {position: relative;}_x000D_
input[type="date"]:before {_x000D_
 position: absolute;left: 0px;top: 0px;_x000D_
 content: "Enter DOB";_x000D_
 color: #999;_x000D_
 width: 100%;line-height: 32px;_x000D_
}_x000D_
input[type="date"]:valid:before {display: none;}
_x000D_
<input type="date" required />
_x000D_
_x000D_
_x000D_


The HTML5 date input field actually does not support the attribute for placeholder. It will always be ignored by the browser, at least as per the current spec.

As noted here


You can use CSS's before pseudo.

_x000D_
_x000D_
.dateclass {
  width: 100%;
}

.dateclass.placeholderclass::before {
  width: 100%;
  content: attr(placeholder);
}

.dateclass.placeholderclass:hover::before {
  width: 0%;
  content: "";
}
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<input
  type="date"
  placeholder="Please specify a date"
  onClick="$(this).removeClass('placeholderclass')"
  class="dateclass placeholderclass">
_x000D_
_x000D_
_x000D_

FIDDLE


Ok, so this is what I have done:

$(document).on('change','#birthday',function(){
    if($('#birthday').val()!==''){
        $('#birthday').addClass('hasValue');
    }else{
        $('#birthday').removeClass('hasValue');
    }
})

This is to remove the placeholder when a value is given.

input[type="date"]:before {
  content: attr(placeholder) !important;
  color: #5C5C5C;
  margin-right: 0.5em;
}
input[type="date"]:focus:before,
input[type="date"].hasValue:before {
  content: "" !important;
  margin-right: 0;
}

On focus or if .hasValue, remove the placeholder and its margin.


I'm using this css method in order to simulate placeholder on the input date.

The only thing that need js is to setAttribute of the value, if using React, it works out of the box.

_x000D_
_x000D_
input[type="date"] {_x000D_
  position: relative;_x000D_
}_x000D_
_x000D_
input[type="date"]:before {_x000D_
  content: attr(placeholder);_x000D_
  position: absolute;_x000D_
  top: 0;_x000D_
  left: 0;_x000D_
  right: 0;_x000D_
  bottom: 0;_x000D_
  background: #fff;_x000D_
  color: rgba(0, 0, 0, 0.65);_x000D_
  pointer-events: none;_x000D_
  line-height: 1.5;_x000D_
  padding: 0 0.5rem;_x000D_
}_x000D_
_x000D_
input[type="date"]:focus:before,_x000D_
input[type="date"]:not([value=""]):before_x000D_
{_x000D_
  display: none;_x000D_
}
_x000D_
<input type="date" placeholder="Choose date" value="" onChange="this.setAttribute('value', this.value)" />
_x000D_
_x000D_
_x000D_


As mentionned here, I've made it work with some ":before" pseudo-class and a small bit of javascript. Here is the idea :

 #myInput:before{ content:"Date of birth"; width:100%; color:#AAA; } 
 #myInput:focus:before,
 #myInput.not_empty:before{ content:none }

Then in javascript, add the "not_empty" class depending on the value in the onChange and onKeyUp events.

You can even add all of this dynamically on every date fields. Check my answer on the other thread for the code.

It's not perfect but it's working well in Chrome and iOS7 webviews. Maybe it could help you.


As i mentioned here

initially set the field type to text.

on focus change it to type date


You can do something like this:

<input onfocus="(this.type='date')" class="js-form-control" placeholder="Enter Date">