Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add support for html5 native time-related widgets #142

Merged
merged 8 commits into from

5 participants

@lmctv
  • for the DateInputWidget, the .datepicker interfered with
    the native widget shown on field enter

    • the DateTimeInputWidget's template defined the input field as being of type "text" instead of "datetime"; therefore, the native datitime widget was never shown

To enable the correct behaviour, the jqueryui datepicker will be
activated only after detecting the native support for the respective
input type is missing via a custom generated modernizr.js.

The installed version of modernizr.js was generated enabling only detection
of input types and attributes; this way, the filesize is just 2394 bytes,
instead of 15483 of the full minified distribution.

I'm attaching the screenshots I've taken both from desktop chrome:

chrome/desktop, date input: both native and jquery "enhanced" visible
chrome-both-native-and-jquery-date

chrome/desktop, date input: correct behaviour: only native visible
chrome-native-date-ok

chrome/android, date input: both native and jquery "enhanced" visible
date-android-both-native-and-jqueryui

chrome/android, date input: correct behaviour: only native visible
date-android-native

chrome/android, datetime input: only jquery dialog visible
datetime-android-no-native

chrome/android, datetime input: correct behaviour: only native visible
datetime-android-native

lmctv added some commits
@lmctv lmctv Add support for html5 native time-related widgets
  * for the DateInputWidget, the .datepicker interfered with
    the native widget shown on field enter

  * the DateTimeInputWidget's template defined the input field
    as being of type "text" instead of "datetime"; therefore,
    the native datitime widget was never shown

To enable the correct behaviour, the jqueryui datepicker will be
activated only after detecting the native support for the respective
input type is missing via a custom generated modernizr.js.

The installed version of modernizr.js was generated enabling only detection
of input types and attributes; this way, the filesize is just 2394 bytes,
instead of 15483 of the full minified distribution.
76a6749
@lmctv lmctv Let the user set rendering preferences
for both DateInputWidget and DateTimeInputWidget:

 * default rendering as html5 input with jquery fall-back
 * if prefer_jquery is set, render as jquery-enhanced text input
f3a76cd
@lmctv

@kiorky, @rbu, @tonthon would you mind taking a look at these changes?

@lmctv lmctv Define a "prefer_html5" attribute for all widgets
and use that preference to enable native rendering of date and datetime
b01718e
deform/templates/dateinput.pt
@@ -14,8 +16,10 @@
<script type="text/javascript">
deform.addCallback(
'${oid}',
- function(oid) {
- $('#' + oid).datepicker(${options});
+ function(oid) {<span tal:condition="prefer_html5" tal:omit-tag="">
@tseaver Owner
tseaver added a note

Rather than using an actual tag, and then suppressing it with 'tal:omit-tag', a clearer spelling is to use a synthetic tag in the 'tal:' namespace. E.g.:

function(oid){<tal:if tal:condition="prefer_html5">
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@lmctv

At least in the chrome for android case, correct handling of html datetime input depends on
Pylons/colander#79 "Iso8601 truncation".

@lmctv

I've added two new views to my fork of deformdemo to show the native widgets in action. While I'm not doing a pull request for the changes before this one gets integrated, the changes are at https://github.com/lmctv/deformdemo/branches/test_jquery_replace_for_html5 .

@mcdonc
Owner

For the record, I took a look at this branch recently (while onsite at a customer gig, because we need the functionality). I'm not sure I can give very actionable feedback because I was (and am) in a hurry, but I know that I'm maybe not a fan of the conditionals in "if prefer_html5" sections in the code.

It feels like deform should just render html5 widgets by default except for cases where browser support is all over the map (like datetime and date, are there others that have spotty/weird support amongst browsers?).

Any thoughts?

@mcdonc
Owner

Uh crap I probably attached that comment to the wrong issue, given that this one is just about datetime support. And maybe I'm misremembering, but it seemed like when I looked the code anticipated "prefer_html5" for all widgets.

@lmctv

No, no, the issue is the right one... I just thought adding an opt-in functionality would have been the path of least resistence for adding html5 widgets one by one; if you prefer so, I could very well drop the conditional, but I fear possible browser compatibility problems, and the risk to have deform create FrankenForms, that could fail validation for any and all html versions...

@chrisrossi
Owner

I'll weigh in in support of @mcdonc. It would discourage use of 'prefer_html5' and rely on modernizr to do the right thing. Is there ever a time when being able to turn off html5 would be necessary?

@lmctv

With many thanks to @chrisrossi... no more "prefer_html5" pollution; let those who really want to avoid native widgets just tell it to the renderer by explicitly asking for a type_name != 'date' or 'datetime' on widget instantiation.

@mcdonc mcdonc merged commit e21f9ae into Pylons:master
@mcdonc
Owner

Woo hoo! Merged. Thanks @lmctv for the patch and thanks to @ppaez for doing some testing before the merge.

@lei12

I'm facing the non-displaying Datepicker widget issue in Firefox, and the js script related to this Deform date field fails with

ReferenceError: Modernizr is not defined

I installed Deform 2 months ago, so what should I do about it ?

@lmctv

@lei12 are you sure you are correctly exposing the deform/static/ path to your web client? the required modernizr implementation is in static/scripts/modernizr.custom.input-types-and-atts.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 11, 2013
  1. @lmctv

    Add support for html5 native time-related widgets

    lmctv authored
      * for the DateInputWidget, the .datepicker interfered with
        the native widget shown on field enter
    
      * the DateTimeInputWidget's template defined the input field
        as being of type "text" instead of "datetime"; therefore,
        the native datitime widget was never shown
    
    To enable the correct behaviour, the jqueryui datepicker will be
    activated only after detecting the native support for the respective
    input type is missing via a custom generated modernizr.js.
    
    The installed version of modernizr.js was generated enabling only detection
    of input types and attributes; this way, the filesize is just 2394 bytes,
    instead of 15483 of the full minified distribution.
  2. @lmctv

    Let the user set rendering preferences

    lmctv authored
    for both DateInputWidget and DateTimeInputWidget:
    
     * default rendering as html5 input with jquery fall-back
     * if prefer_jquery is set, render as jquery-enhanced text input
Commits on Jan 12, 2013
  1. @lmctv

    Define a "prefer_html5" attribute for all widgets

    lmctv authored
    and use that preference to enable native rendering of date and datetime
Commits on Jan 29, 2013
  1. @lmctv

    Replace <span tal:omit-tag=""> with <tal:if...>

    lmctv authored
    As suggested by @tseaver in his comment on Pylons#142.
  2. @lmctv

    Add myself to CONTRIBUTORS.txt

    lmctv authored
Commits on Mar 19, 2013
  1. @lmctv
  2. @lmctv

    Let the caller force html4+jquery rendering

    lmctv authored
    instead of native html5
  3. @lmctv

    Update docstrings.

    lmctv authored
This page is out of date. Refresh to see the latest.
View
1  CONTRIBUTORS.txt
@@ -113,3 +113,4 @@ Contributors
- Daniel Nouri, 2012/03/30
- Sam Brauer, 2012/09/15
- Domen Kožar, 2012/09/23
+- Lorenzo M. Catucci, 2013/01/29
View
4 deform/static/scripts/modernizr.custom.input-types-and-atts.js
@@ -0,0 +1,4 @@
+/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
+ * Build: http://modernizr.com/download/#-input-inputtypes
+ */
+;window.Modernizr=function(a,b,c){function u(a){i.cssText=a}function v(a,b){return u(prefixes.join(a+";")+(b||""))}function w(a,b){return typeof a===b}function x(a,b){return!!~(""+a).indexOf(b)}function y(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:w(f,"function")?f.bind(d||b):f}return!1}function z(){e.input=function(c){for(var d=0,e=c.length;d<e;d++)o[c[d]]=c[d]in j;return o.list&&(o.list=!!b.createElement("datalist")&&!!a.HTMLDataListElement),o}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,g,h,i=a.length;d<i;d++)j.setAttribute("type",g=a[d]),e=j.type!=="text",e&&(j.value=k,j.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(g)&&j.style.WebkitAppearance!==c?(f.appendChild(j),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(j,null).WebkitAppearance!=="textfield"&&j.offsetHeight!==0,f.removeChild(j)):/^(search|tel)$/.test(g)||(/^(url|email)$/.test(g)?e=j.checkValidity&&j.checkValidity()===!1:e=j.value!=k)),n[a[d]]=!!e;return n}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d="2.6.2",e={},f=b.documentElement,g="modernizr",h=b.createElement(g),i=h.style,j=b.createElement("input"),k=":)",l={}.toString,m={},n={},o={},p=[],q=p.slice,r,s={}.hasOwnProperty,t;!w(s,"undefined")&&!w(s.call,"undefined")?t=function(a,b){return s.call(a,b)}:t=function(a,b){return b in a&&w(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=q.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(q.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(q.call(arguments)))};return e});for(var A in m)t(m,A)&&(r=A.toLowerCase(),e[r]=m[A](),p.push((e[r]?"":"no-")+r));return e.input||z(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)t(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof enableClasses!="undefined"&&enableClasses&&(f.className+=" "+(b?"":"no-")+a),e[a]=b}return e},u(""),h=j=null,e._version=d,e}(this,this.document);
View
10 deform/templates/dateinput.pt
@@ -2,9 +2,10 @@
css_class css_class|field.widget.css_class;
name name|field.name;
oid oid|field.oid;
- style style|field.widget.style|None"
+ style style|field.widget.style|None;
+ type_name type_name|field.widget.type_name;"
tal:omit-tag="">
- <input type="date"
+ <input type="${type_name}"
name="${name}"
value="${cstruct}"
tal:attributes="size size;
@@ -15,7 +16,10 @@
deform.addCallback(
'${oid}',
function(oid) {
- $('#' + oid).datepicker(${options});
+ if (!Modernizr.inputtypes['date'] ||
+ "${type_name}" != "date"){
+ $('#' + oid).datepicker(${options});
+ }
}
);
</script>
View
10 deform/templates/datetimeinput.pt
@@ -2,9 +2,10 @@
css_class css_class|field.widget.css_class;
name name|field.name;
oid oid|field.oid;
- style style|field.widget.style|None"
+ style style|field.widget.style|None;
+ type_name type_name|field.widget.type_name;"
tal:omit-tag="">
- <input type="text"
+ <input type="${type_name}"
name="${name}"
value="${cstruct}"
tal:attributes="size size; class css_class; style style"
@@ -13,7 +14,10 @@
deform.addCallback(
'${oid}',
function(oid) {
- $('#' + oid).datetimepicker(${options});
+ if (!Modernizr.inputtypes['datetime'] ||
+ "${type_name}" != "datetime"){
+ $('#' + oid).datetimepicker(${options});
+ }
}
);
</script>
View
31 deform/widget.py
@@ -127,6 +127,7 @@ class Widget(object):
error_class = 'error'
css_class = None
requirements = ()
+ type_name = ''
def __init__(self, **kw):
self.__dict__.update(kw)
@@ -473,10 +474,13 @@ def deserialize(self, field, pstruct):
class DateInputWidget(Widget):
"""
+ Renders a date picker widget.
- Renders a JQuery UI date picker widget
- (http://jqueryui.com/demos/datepicker/). Most useful when the
- schema node is a ``colander.Date`` object.
+ The default rendering is as a native HTML5 date input widget,
+ falling back to JQuery UI date picker widget
+ (http://jqueryui.com/demos/datepicker/).
+
+ Most useful when the schema node is a ``colander.Date`` object.
**Attributes/Arguments**
@@ -503,9 +507,10 @@ class DateInputWidget(Widget):
"""
template = 'dateinput'
readonly_template = 'readonly/textinput'
+ type_name = 'date'
size = None
style = None
- requirements = ( ('jqueryui', None), )
+ requirements = ( ('modernizr', None), ('jqueryui', None) )
default_options = (('dateFormat', 'yy-mm-dd'),)
def __init__(self, *args, **kwargs):
@@ -528,9 +533,13 @@ def deserialize(self, field, pstruct):
class DateTimeInputWidget(DateInputWidget):
"""
- Renders a a jQuery UI date picker with a JQuery Timepicker add-on
- (http://trentrichardson.com/examples/timepicker/). Used for
- ``colander.DateTime`` schema nodes.
+ Renders a datetime picker widget.
+
+ The default rendering is as a native HTML5 datetime input widget,
+ falling back to jQuery UI date picker with a JQuery Timepicker add-on
+ (http://trentrichardson.com/examples/timepicker/).
+
+ Used for ``colander.DateTime`` schema nodes.
**Attributes/Arguments**
@@ -557,9 +566,10 @@ class DateTimeInputWidget(DateInputWidget):
"""
template = 'datetimeinput'
readonly_template = 'readonly/textinput'
+ type_name = 'datetime'
size = None
style = None
- requirements = ( ('jqueryui', None), ('datetimepicker', None), )
+ requirements = ( ('modernizr', None), ('jqueryui', None), ('datetimepicker', None), )
default_options = (DateInputWidget.default_options +
(('timeFormat', 'hh:mm:ss'),
('separator', ' ')))
@@ -1825,6 +1835,11 @@ def __call__(self, requirements):
'js':'tinymce/jscripts/tiny_mce/tiny_mce.js',
},
},
+ 'modernizr': {
+ None:{
+ 'js':('scripts/modernizr.custom.input-types-and-atts.js',),
+ },
+ },
}
default_resource_registry = ResourceRegistry()
Something went wrong with that request. Please try again.