98

this is how i'm trying

<script type="text/javascript">
  $(document).ready(function(){
    $('#dateIn,#dateOut').click(function(e){
      e.preventDefault();
    }); 
  });
</script>

but the input stills 'launching' iphone's keyboard

ps: i want to do this because i'm using datepicker plugin for date

Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378

9 Answers9

244

By adding the attribute readonly (or readonly="readonly") to the input field you should prevent anyone typing anything in it, but still be able to launch a click event on it.

This is also usefull in non-mobile devices as you use a date/time picker

Jacopo Pace
  • 460
  • 7
  • 14
Rene Pot
  • 24,681
  • 7
  • 68
  • 92
57

inputmode attribute

<input inputmode='none'>

The inputmode global attribute is an enumerated attribute that hints at the type of data that might be entered by the user while editing the element or its contents. It can have the following values:

none - No virtual keyboard. For when the page implements its own keyboard input control.


I am using this successfully (Tested on Chrome/Android)

CSS-Tricks: Everything You Ever Wanted to Know About inputmode

vsync
  • 118,978
  • 58
  • 307
  • 400
  • 3
    This is the correct solution to question, not readonly option – Benjamin Mar 07 '21 at 17:52
  • +1 This is a much better solution, particularly on an ASP.Net web app. Readonly happens to be a control property, so entering in readonly='readonly' causes validation errors. – Probably Apr 20 '21 at 20:04
  • So funny how on the [the other question](https://stackoverflow.com/a/67908134/10892722) with the same semantic meaning, the same thing happened. The right answer was only added way after the question, and it has way fewer upvotes – Zachiah Sep 24 '22 at 17:40
  • 2
    I don't understand why people say this is a better solution than readonly if Safari will still pop up a numeric keyboard. Doesn't sound like a solution to me. – Tom Davenport Oct 07 '22 at 15:17
  • I don't know about iOS, but in my use case of only needing to support Chrome on Android, this is the answer I was looking for. I was nearly going to implement my own on-screen keyboard to work around it by disabling the Android keyboard entirely (lol). – Siimo Raba Dec 30 '22 at 12:13
  • I found that this works on iOS Safari - tested with version 15. The docs say that iOS Safari has supported this as of version 12.2 - https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode – skwidbreth May 10 '23 at 14:10
  • Testing in Chrome 114.0.5735.57 in Android 11, this isn't working unfortunately. Edit, doesn't work for `type="number"`, works for `type="text"` – hackerl33t Jun 05 '23 at 05:47
  • 1
    Thanks a lot! I searched off the whole internet and tried so many things, but this did the trick! – Takkie253 Jun 28 '23 at 07:44
  • This still works on Android 13 on every browser I tested it on. Perfect for a scanner web app where you still need to be able to enter data without the keyboard popping up. – justdoingmyjob Aug 09 '23 at 19:56
12

You can add a callback function to your DatePicker to tell it to blur the input field before showing the DatePicker.

$('.selector').datepicker({
   beforeShow: function(){$('input').blur();}
});

Note: The iOS keyboard will appear for a fraction of a second and then hide.

nachomaans
  • 457
  • 4
  • 7
4

Below code works for me:

<input id="myDatePicker" class="readonlyjm"/>


$('#myDatePicker').datepicker({
/* options */
});

$('.readonlyjm').on('focus',function(){
$(this).trigger('blur');
});
swiftBoy
  • 35,607
  • 26
  • 136
  • 135
3

I asked a similar question here and got a fantastic answer - use the iPhone native datepicker - it's great.

How to turn off iPhone keypad for a specified input field on web page

Synopsis / pseudo-code:

if small screen mobile device 

  set field type to "date" - e.g. document.getElementById('my_field').type = "date";
  // input fields of type "date" invoke the iPhone datepicker.

else

  init datepicker - e.g. $("#my_field").datepicker();

The reason for dynamically setting the field type to "date" is that Opera will pop up its own native datepicker otherwise, and I'm assuming you want to show the datepicker consistently on desktop browsers.

Community
  • 1
  • 1
John Vance
  • 532
  • 4
  • 15
2

Best way to solve this as per my opinion is Using "ignoreReadonly".

First make the input field readonly then add ignoreReadonly:true. This will make sure that even if the text field is readonly , popup will show.

$('#txtStartDate').datetimepicker({
            locale: "da",
            format: "DD/MM/YYYY",
            ignoreReadonly: true
        });
        $('#txtEndDate').datetimepicker({
            locale: "da",
            useCurrent: false,
            format: "DD/MM/YYYY",
            ignoreReadonly: true
        });
});
Akbar Badhusha
  • 2,415
  • 18
  • 30
2

Since I can't comment on the top comment, I'm forced to submit an "answer."

The problem with the selected answer is that setting the field to readonly takes the field out of the tab order on the iPhone. So if you like entering forms by hitting "next", you'll skip right over the field.

John Vance
  • 532
  • 4
  • 15
  • 1
    It makes sense, readonly won't let user change value (only javascript) so i guess is natural taht it skips it – Toni Michel Caubet Mar 22 '12 at 08:23
  • 1
    However, on the desktop browsers I've tested - including Safari/mac - tabbing takes you to the readonly field. – John Vance Mar 23 '12 at 17:16
  • 1
    @JohnVance Is this true even if the tab-index attribute is set? Or would that override the effect? (I'm asking because I don't have an iPhone, but would appreciate the knowledge) – Fernando Silva Jan 28 '14 at 23:39
  • 1
    @FernandoSilva I've tested this on iPhone Safari, with tab-index you'll still skip the field. – Betty Dec 12 '14 at 03:04
0

So here is my solution (similar to John Vance's answer):

First go here and get a function to detect mobile browsers.

http://detectmobilebrowsers.com/

They have a lot of different ways to detect if you are on mobile, so find one that works with what you are using.

Your HTML page (pseudo code):

If Mobile Then
    <input id="selling-date" type="date" placeholder="YYYY-MM-DD" max="2999-12-31" min="2010-01-01" value="2015-01-01" />
else
    <input id="selling-date" type="text" class="date-picker" readonly="readonly" placeholder="YYYY-MM-DD" max="2999-12-31" min="2010-01-01" value="2015-01-01" />

JQuery:

$( ".date-picker" ).each(function() {
    var min = $( this ).attr("min");
    var max = $( this ).attr("max");
    $( this ).datepicker({ 
        dateFormat: "yy-mm-dd",  
        minDate: min,  
        maxDate: max  
    });
});

This way you can still use native date selectors in mobile while still setting the min and max dates either way.

The field for non mobile should be read only because if a mobile browser like chrome for ios "requests desktop version" then they can get around the mobile check and you still want to prevent the keyboard from showing up.

However if the field is read only it could look to a user like they cant change the field. You could fix this by changing the CSS to make it look like it isn't read only (ie change border-color to black) but unless you are changing the CSS for all input tags you will find it hard to keep the look consistent across browsers.

To get arround that I just add a calendar image button to the date picker. Just change your JQuery code a bit:

$( ".date-picker" ).each(function() {
    var min = $( this ).attr("min");
    var max = $( this ).attr("max");
    $( this ).datepicker({ 
        dateFormat: "yy-mm-dd",  
        minDate: min,  
        maxDate: max,
        showOn: "both",
        buttonImage: "images/calendar.gif",
        buttonImageOnly: true,
        buttonText: "Select date"
    });
});

Note: you will have to find a suitable image.

Curtis
  • 3,170
  • 7
  • 28
  • 44
-1

I have a little generic "no keyboard" script - works for me with Android and iPhone:

  $('.readonlyJim').on('focus', function () {
      $(this).trigger('blur')
  })

Simply attach add class readonlyJim to the input tag and voila.

(*Sorry too much StarTrek here)

BeNice
  • 2,165
  • 2
  • 23
  • 38