Not showing placeholder for input type=“date” field

爱⌒轻易说出口 提交于 2019-11-26 19:40:29

It may not be appropriate... but it helped me at last.

<input placeholder="Date" class="textbox-n" type="text" onfocus="(this.type='date')"  id="date"> 

If you use mvp's method but add the onblur event to change it back to a text field so the placeholder text appears again when the input field looses focus. It just makes the hack a little bit nicer.

<input placeholder="Date" class="textbox-n" type="text" onfocus="(this.type='date')" onblur="(this.type='text')" id="date">

Hope this helps.

I ended up using the following.

Regarding Firefox comment(s): Generally, Firefox will not show any text placeholder for inputs type date. But as this is a Cordova/PhoneGap question this should be of no concern (Unless you want to develop against FirefoxOS).

input[type="date"]:not(.has-value):before{
  color: lightgray;
  content: attr(placeholder);
}
<input type="date" placeholder="MY PLACEHOLDER" onchange="this.className=(this.value!=''?'has-value':'')">

I used this in my css:

input[type="date"]:before{
    color:lightgray;
    content:attr(placeholder);
}

input[type="date"].full:before {
    color:black;
    content:""!important;
}

and put somenthing like this into javascript:

$("#myel").on("input",function(){
    if($(this).val().length>0){
    $(this).addClass("full");
}
else{
   $(this).removeClass("full");
   }
 });

it works for me for mobile devices (Ios8 and android). But I used jquery inputmask for desktop with input text type. This solution it's a nice way if your code run on ie8.

As of today (2016), I have successfully used those 2 snippets (plus they work great with Bootstrap4).

Input data on the left, placeholder on the left

input[type=date] {
  text-align: right;
}

input[type="date"]:before {
  color: lightgrey;
  content: attr(placeholder) !important;
  margin-right: 0.5em;
}

Placeholder disappear when clicking

input[type="date"]:before {
  color: lightgrey;
  content: attr(placeholder) !important;
  margin-right: 0.5em;
}
input[type="date"]:focus:before {
  content: '' !important;
}
deadproxor

It works for me:

input[type='date']:after {
  content: attr(placeholder)
}

According to the HTML standard:

The following content attributes must not be specified and do not apply to the element: accept, alt, checked, dirname, formaction, formenctype, formmethod, formnovalidate, formtarget, height, inputmode, maxlength, minlength, multiple, pattern, placeholder, size, src, and width.

I used this whit jQuery: http://jsfiddle.net/daviderussoabram/65w1qhLz/

$('input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="month"], input[type="time"], input[type="week"]').each(function() {
    var el = this, type = $(el).attr('type');
    if ($(el).val() == '') $(el).attr('type', 'text');
    $(el).focus(function() {
        $(el).attr('type', type);
        el.click();
    });
    $(el).blur(function() {
        if ($(el).val() == '') $(el).attr('type', 'text');
    });
});

Based on deadproxor and Alessio answers, I would try only using CSS:

input[type="date"]::before{
    color: #999;
    content: attr(placeholder) ": ";
}
input[type="date"]:focus::before {
    content: "" !important;
}

And if you need to make the placeholder invisible after writing something in the input, we could try using the :valid and :invalid selectors, if your input is a required one.

EDIT

Here the code if you are using required in your input:

input[type="date"]::before {
	color: #999999;
	content: attr(placeholder);
}
input[type="date"] {
	color: #ffffff;
}
input[type="date"]:focus,
input[type="date"]:valid {
	color: #666666;
}
input[type="date"]:focus::before,
input[type="date"]:valid::before {
	content: "" !important;
}
<input type="date" placeholder="Date" required>
Kawaldeep Singh

Found a better way to solve your problem. I think this will help you. when focused out, the box will change type into text so it will show your placeholder. when focused in, its type changes into date so the calendar view will be shown.

<input placeholder="Date" class="textbox-n" type="text" onfocusin="(this.type='date')" onfocusout="(this.type='text')"  id="date"> 
ma90

Adressing the problem in the current correct answer "clicking the field shows the onscreen keyboard instead of the datepicker":

The problem is caused by the Browser behaving according to the type of input when clicking (=text). Therefore it is necessary to stop from focussing on the input element (blur) and then restart focus programmatically on the input element which was defined as type=date by JS in the first step. Keyboard displays in phonenumber-mode.

<input placeholder="Date" type="text" onfocus="this.type='date';
                      this.setAttribute('onfocus','');this.blur();this.focus();">
Dally S

Took me a while figuring this one out, leave it as type="text", and add onfocus="(this.type='date')", just as shown above.

I even like the onBlur idea mentioned above

<input placeholder="Date" class="textbox-n" type="text" onfocus="(this.type='date')" onblur="(this.type='text')" id="date">

Hope this helps anyone who didn't quite gather whats going on above

To summarize the date inputs problem:

  • You have to display them (i.e. avoid display:none) otherwise the input UI will not be triggered ;
  • a placeholder is contradictory with them (as per the spec, and because they have to display a specific UI) ;
  • converting them to another input type for the unfocused time do allows placeholders, but focus then triggers the wrong input UI (keyboard), at least for a small time, because focus events cannot be cancelled.
  • inserting (before) or adding (after) content doesn't prevent the date input value to be displayed.

The solution I found to meet those requirements is to use the usual trick to style native form elements : ensure the element is displayed but not visible, and display its expected style through its associated label. Typically, the label will display as the input (including a placeholder), but over it.

So, an HTML like:

<div class="date-input>
  <input id="myInput" type="date"> 
  <label for="myInput"> 
    <span class="place-holder">Enter a date</span> 
  </label>
</div>

Could be styled as:

.date-input {
  display: inline-block;
  position: relative;
}
/* Fields overriding */
input[type=date] + label {
  position: absolute;  /* Same origin as the input, to display over it */
  background: white;   /* Opaque background to hide the input behind */
  left: 0;             /* Start at same x coordinate */
}

/* Common input styling */
input[type=date], label {  
  /* Must share same size to display properly (focus, etc.) */
  width: 15em;
  height: 1em;
  font-size: 1em;
}

Any event (click, focus) on such an associated label will be reflected on the field itself, and so trigger the date input UI.

Should you want to test such a solution live, you can run this Angular version from your tablet or mobile.

SO what i have decided to do finally is here and its working fine on all mobile browsers including iPhones and Androids.

$(document).ready(function(){

  $('input[type="date"]').each(function(e) {
    var $el = $(this), 
        $this_placeholder = $(this).closest('label').find('.custom-placeholder');
    $el.on('change',function(){
      if($el.val()){
        $this_placeholder.text('');
      }else {
        $this_placeholder.text($el.attr('placeholder'));
      }
    });
  });
  
});
label {
  position: relative;  
}
.custom-placeholder {
    #font > .proxima-nova-light(26px,40px);
    position: absolute;
    top: 0;
    left: 0;
    z-index: 10;
    color: #999;
}
<label>
  <input type="date" placeholder="Date">
  <span class="custom-placeholder">Date</span>
</label>

Date

Im working with ionicframework and solution provided by @Mumthezir is almost perfect. In case if somebody would have same problem as me(after change, input is still focused and when scrolling, value simply dissapears) So I added onchange to make input.blur()

<input placeholder="Date" class="textbox-n" type="text" onfocus=" (this.type='date')" onchange="this.blur();"  id="date"> 

You can

  1. set it as type text
  2. convert to date on focus
  3. make click on it
  4. ...let user check date
  5. on change store the value
  6. set input to type text
  7. set text type input value to the stored value

like this...

$("#dateplaceholder").change(function(evt) {
  var date = new Date($("#dateplaceholder").val());
  $("#dateplaceholder").attr("type", "text");
  $("#dateplaceholder").val(date.getDate() + "/" + (date.getMonth() + 1) + "/" + date.getFullYear());
});
$("#dateplaceholder").focus(function(evt) {
  $("#dateplaceholder").attr("type", "date");
  setTimeout('$("#dateplaceholder").click();', 500);
});
$("#dateplaceholder").attr("type", "text");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<input type="date" id="dateplaceholder" placeholder="Set the date" />

From Angular point of view I managed to put a placeholder in input type date element.

First of all I defined the following css:

.placeholder {
    color: $text-grey;
  }

  input[type='date']::before {
    content: attr(placeholder);
  }

  input::-webkit-input-placeholder {
    color: $text-grey;
  }

The reason why this is neccessary is that if css3 content has different color that the normal placeholder, so I had to use a common one.

<input #birthDate
         class="birthDate placeholder"
         type="date"
         formControlName="birthDate"
         placeholder="{{getBirthDatePlaceholder() | translate}}"
         [class.error]="!onboardingForm.controls.birthDate.valid && onboardingForm.controls.birthDate.dirty"
         autocomplete="off"
         >

Then in the template used a viewchild birthDate attribute, to be able to access this input from the component. And defined an angular expression on the placeholder attribute, which will decide if we show the placeholder or not. This is the major drawback of the solution, is that you have to manage the visibility of the placeholder.

@ViewChild('birthDate') birthDate;

getBirthDatePlaceholder() {
  if (!this.birthDate) {
    return;
  } else {
    return this.birthDate.nativeElement.value === '' ?
    'ONBOARDING_FORM_COMPONENT.HINT_BIRTH_DATE' :
    '';
  }
}

Found a better way to handle user basic comprehension with mouseover and opening datepicker on click :

<input type="text" onfocus="(this.type='date')" onmouseover="(this.type = 'date')" onblur="(this.value ? this.type = 'date' : this.type = 'text')" id="date_start" placeholder="Date">

Also hide webkit arrow and make it 100% wide to cover the click :

input[type="date"] {
    position: relative;
}
input[type="date"]::-webkit-calendar-picker-indicator {
  position: absolute;
  height: 100%;
  width: 100%;
  opacity: 0;
  left: 0;
  right: 0;
  top:0;
  bottom: 0;
}

try my solution. I use 'required' attribute to get know whether input is filled and if not I show the text from attribute 'placeholder'

//HTML
<input required placeholder="Date" class="textbox-n" type="date" id="date">

//CSS
input[type="date"]:not(:valid):before {
   content: attr(placeholder);
   // style it like it real placeholder
}

I took jbarlow idea, but I added an if in the onblur function so the fields only change its type if the value is empty

<input placeholder="Date" class="textbox-n" type="text" onfocus="(this.type='date')" onblur="(this.value == '' ? this.type='text' : this.type='date')" id="date">

Expanding on @mvp's solution with unobtrusive javascript in mind, here's the approach:

HTML:

<input type="text" placeholder="Date" class="js-text-date-toggle">

Javascript:

$('.js-text-date-toggle').on('focus', function() {
  $(this).attr('type', 'date') }
).on('blur', function() {
  $(this).attr('type'), 'text') }
)

I think all you have to do is change the model to say the date field is nullable and then put [Required] on it if it is required. If you do this the placeholder text does appear.

Hey so I ran into the same issue last night and figured out a combination of all of your answer and some sparkling magic are doing a good job:

The HTML:

<input type="date"  name="flb5" placeholder="Datum"     class="datePickerPlaceHolder"/>

The CSS:

@media(max-width: 1024px) {
   input.datePickerPlaceHolder:before {
      color: #A5A5A5; //here you have to match the placeholder color of other inputs
      content: attr(placeholder) !important;
   }
}

The jQuery:

$(document).ready(function() {
    $('input[type="date"]').change(function(){
            if($(this).val().length < 1) {
                $(this).addClass('datePickerPlaceHolder');
            } else {
                $(this).removeClass('datePickerPlaceHolder');
            }
    });
});

Explanation: So, what is happening here, first of all in the HTML, this is pretty straight forward just doing a basic HMTL5-date-input and set a placeholder. Next stop: CSS, we are setting a :before-pseudo-element to fake our placeholder, it just takes the placeholder's attribute from the input itself. I made this only available down from a viewport width of 1024px - why im going to tell later. And now the jQuery, after refactoring a couple of times I came up with this bit of code which will check on every change if there is a value set or not, if its not it will (re-)add the class, vice-versa.

KNOW ISSUES:

  • there is a problem in chrome with its default date-picker, thats what the media-query is for. It will add the placeholder infront of the default 'dd.mm.yyyy'-thing. You could also set the placeholder of the date-input to 'date: ' and adjust the color incase of no value inside the input...for me this resulted in some other smaller issues so i went with just not showing it on 'bigger' screens

hope that helps! cheerio!

<input placeholder="Date" type="text" onMouseOver="(this.type='date')" onMouseOut="(this.type='text')"  id="date" class="form-control">

Revised code of mumthezir

If you're only concerned with mobile:

input[type="date"]:invalid:before{
    color: rgb(117, 117, 117);
    content: attr(placeholder);
}
Or Choban

HTML:

<div>
    <input class="ui-btn ui-btn-icon-right ui-corner-all ui-icon-calendar ui-shadow" id="inputDate" type="date"/>
    <h3 id="placeholder-inputDate">Date Text</h3>
</div>

JavaScript:

$('#inputDate').ready(function () {
$('#placeholder-inputDate').attr('style'
    , 'top: ' + ($('#placeholder-inputDate').parent().position().top + 10)
    + 'px; left: ' + ($('#placeholder-inputDate').parent().position().left + 0) + 'px; position: absolute;');
$('#inputDate').attr('style'
    , 'width: ' + ($('#placeholder-inputDate').width() + 32) + 'px;');
});

Here is another possible hack not using js and still using css content. Note that as :after is not supported on some browser for inputs, we need to select the input in another way, same for content attr('')

input[type=date]:invalid+span:after {
  content:"Birthday";
  position:absolute;
  left:0;
  top:0;
}

input[type=date]:focus:invalid+span:after {
  display:none;
}

input:not(:focus):invalid {
  color:transparent;
}

label.wrapper {
	position:relative;
}
<label class="wrapper">
	<input
 	  type="date"
  	  required="required" 
	/>
	<span></span>
</label>

This works for me using this as input element:

<input name="birthdate" class="" class="wpcf7-form-control wpcf7-date 
 wpcf7-validates-as-required wpcf7-validates-as-date birthdate" value="" 
 aria-required="true" aria-invalid="false" placeholder="birthdate *" 
 type="date">

This CSS shows a permanent placeholder. The selected value is shown after the placeholder.

input[type="date"]:before {
    content: attr(placeholder) !important;
    margin-right: 0.5em;
    display: block;
}
/* only for FF */
@-moz-document url-prefix() {
    input[type="date"]:before {
        content: attr(placeholder) !important;
        margin-right: 0.5em;
        display: block;
        position: absolute;
        left: 200px; /* please adopt */
    }
}

I use this solution for a Wordpress form with contact-form-7 plugin.

None of the solutions were working correctly for me on Chrome in iOS 12 and most of them are not tailored to cope with possible multiple date inputs on a page. I did the following, which basically creates a fake label over the date input and removes it on tap. I am also removing the fake label if viewport width is beyond 992px.

JS:

function addMobileDatePlaceholder() {
    if (window.matchMedia("(min-width: 992px)").matches) {
        $('input[type="date"]').next("span.date-label").remove();
        return false;
    }

    $('input[type="date"]').after('<span class="date-label" />');

    $('span.date-label').each(function() {
        var $placeholderText = $(this).prev('input[type="date"]').attr('placeholder');
        $(this).text($placeholderText);
    });

    $('input[type="date"]').on("click", function() {
        $(this).next("span.date-label").remove();
    });
}

CSS:

@media (max-width: 991px) {
    input[type="date"] {
        padding-left: calc(50% - 45px);
    }

    span.date-label {
        pointer-events: none;
        position: absolute;
        top: 2px;
        left: 50%;
        transform: translateX(-50%);
        text-align: center;
        height: 27px;
        width: 70%;
        padding-top: 5px;
    }
}

Extension of Mumthezir's version that works better on iOS, based on Mathijs Segers' comment:

(Uses some AngularJS but hopefully you get the idea.)

<label style='position:relative'>
    <input type="date" 
           name="dateField" 
           onfocus="(this.type='date')"
           ng-focus="dateFocus=true" ng-blur="dateFocus=false" />
    <span ng-if='!dateFocus && !form.date' class='date-placeholder'>
        Enter date
    </span>
</label>

Because it's all wrapped in a label, clicking the span automatically focuses the input.

CSS:

.date-placeholder {
    display: inline-block;
    position: absolute;
    text-align: left;
    color: #aaa;
    background-color: white;
    cursor: text;
    /* Customize this stuff based on your styles */
    top: 4px;
    left: 4px;
    right: 4px;
    bottom: 4px;
    line-height: 32px;
    padding-left: 12px;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!