diff --git a/README.md b/README.md index a737637..2f3d0b1 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,9 @@ fallback module is loaded and registered by calling the mvcct.enhancer method `a then Html5 fallback is automatically turned on. and all Html5 inputs that are not supported are transformed into text inputs and their content is converted into the current "locale" (this means, for instance, that dates are transformed from the date input ISO format into a format like mm/dd/yy). +Available, also a more complete fallback based on bootstrap widgets: [bootstrap-html5-fallback](https://github.com/MvcControlsToolkit/bootstrap-html5-fallback). +When `bootstrap.html5.fallback.js` is loaded after `mvcct.enhancer.input.basic.js` the `addBasicInput(Globalize)` +is updated to load also all bootstrap widgets. As a default the following [Globalize](https://github.com/jquery/globalize) "locale" formats are used: @@ -231,9 +234,9 @@ As a default the following [Globalize](https://github.com/jquery/globalize) "loc { dateFormat: { "date": "short" }, timeFormat: { "skeleton": "Hms" }, - timeFormat1: { "skeleton": "Hm" }, - datetimeFormat: { "skeleton": "yMdHms" }, - datetimeFormat1": { "skeleton": "yMdHm" }, + timeFormat1: { "skeleton": "Hms" }, + datetimeFormat: { "datetime": "short" }, + datetimeFormat1": { "datetime": "short" }, monthFormat: { "date": "short" }, weekFormat: { "date": "short" } }; @@ -310,14 +313,17 @@ when reading/setting input fields. In order to simplify input field access, when the Htm5 inputs support-detection and fallback module adds two helper methods to the enhancer object, namely: ``` -.format(type, value) -.parse(type, stringValue) +.format(type, value, [invariant]) +.parse(type, stringValue, [invariant]) ``` Both methods takes the type of the original Html5 input as first argument("date", "time", etc.). `format` takes a javascript object (date or number depending on the input time) and transforms it in a properly formatted string, while `parse` performs the inverse transformation. I case of fallback the formats specified in -`editFormats`(or their defaults) are used. +`editFormats`(or their defaults) are used. If the third optional argument is true parsing/formatting are +done using the invariant culture (the one used by native Html5 inputs), otherwise the right culture is auto-detected. +Forcing the invariant culture may be useful for some custom processing of the original input field (for instance +processing min/max or step attributes to set some fallback widget options). ## Adding widgets to Htm5 input fallback One may also add easily widgets(date, datetime, time pickers, siders, etc) to the basic input fallback, @@ -395,7 +401,8 @@ dependency(name,//string action: // invoked function function(targetNode, sourceNode) => void); ) ``` -`name` identifies the type of dependency. When the value of an input is changed programmatically, dependency propagation +`name` identifies the type of dependency. If you want your dependencies interact globally with all others, please set **name="main"**. +When the value of an input is changed programmatically, dependency propagation may be started by triggering the `"_enhancer.dependency."+name` event. **IMPORTANT!**, since mvcct.enhancer doesnt depend on jQuery all above events are not defined with jQuery. diff --git a/bower.json b/bower.json index ca21847..b15e3e1 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "mvcct-enhancer", - "version": "1.0.0-rc2", + "version": "1.0.0-rc3", "homepage": "https://github.com/MvcControlsToolkit/mvcct-enhancer", "description": "a javascript package to handle standard html enhancements", "main": [ diff --git a/enhancer-modules/mvcct.enhancer.input.basic.js b/enhancer-modules/mvcct.enhancer.input.basic.js index 31e6546..a8611bf 100644 --- a/enhancer-modules/mvcct.enhancer.input.basic.js +++ b/enhancer-modules/mvcct.enhancer.input.basic.js @@ -22,9 +22,9 @@ var defaults = { "dateFormat": { "date": "short" }, "timeFormat": { "skeleton": "Hms" }, - "timeFormat1": { "skeleton": "Hm" }, - "datetimeFormat": { "skeleton": "yMdHms" }, - "datetimeFormat1": { "skeleton": "yMdHm" }, + "timeFormat1": { "skeleton": "Hms" }, + "datetimeFormat": { "datetime": "short" }, + "datetimeFormat1": { "datetime": "short" }, "monthFormat": { "date": "short" }, "weekFormat": { "date": "short" } }; @@ -214,6 +214,15 @@ "date": support["date"]>2 ? neutralDateParser : localDateParser, "month": support["month"]>2 ? neutralMonthParser : localMonthParser, "week": support["week"]>2 ? getDateOfISOWeek : localWeekParser + }; + var dictI = { + "range": parseFloat, + "number": parseFloat, + "time": gtimeParser, + "datetime": gDatetimeParser, + "date": neutralDateParser, + "month": neutralMonthParser, + "week": getDateOfISOWeek }; var fdict = { "range": support["range"]>2 ? function(x){return x+"";} : numberFormatter, @@ -224,15 +233,24 @@ "month": support["month"]>2 ? neutralMonthFormatter : monthFormatter, "week": support["week"]>2 ? getIsoWeek : weekFormatter }; - Enhancer["format"]=function(type, val){ + var fdictI = { + "range": function(x){return x+"";}, + "number": function(x){return x+"";}, + "time": neutralTimeFormatter, + "datetime": neutralDateTimeFormatter, + "date": neutralDateFormatter, + "month": neutralMonthFormatter, + "week": getIsoWeek + }; + Enhancer["format"]=function(type, val, invariant){ if(!val && val !== 0 ) return ""; - var formatter = fdict[type]; + var formatter = (invariant ? fdictI : fdict)[type]; if(formatter) return formatter(val); else return val; } - Enhancer["parse"]=function(type, val){ + Enhancer["parse"]=function(type, val, invariant){ if(!val ) return null; - var parser = dict[type]; + var parser = (invariant ? dictI : dict)[type]; if(parser) return parser(val); else return parser; } diff --git a/enhancer-modules/mvcct.enhancer.input.basic.min.js b/enhancer-modules/mvcct.enhancer.input.basic.min.js index 21dbc8f..5f7946c 100644 --- a/enhancer-modules/mvcct.enhancer.input.basic.min.js +++ b/enhancer-modules/mvcct.enhancer.input.basic.min.js @@ -1,9 +1,10 @@ -(function(){(function(S){var l=this||(0,eval)("this");(function(d){if("function"===typeof define&&define.amd)define(["../mvcct.enhancer"],d);else if("object"===typeof exports&&"object"===typeof module)module.exports=d(require("mvcct-enhancer"));else{var m=l.mvcct=l.mvcct||{};d(m.enhancer,l.globalize)}})(function(d){function m(b){b=b.split("-W");b=new Date(Date.UTC(parseInt(b[0]),0,1+7*(parseInt(b[1])-1)));4>=b.getDay()?b.setDate(b.getDate()-b.getDay()+1):b.setDate(b.getDate()+8-b.getDay());return b} -function n(b){b=new Date(+b);b.setHours(0,0,0);b.setMilliseconds(0);b.setDate(b.getDate()+4-(b.getDay()||7));var c=Math.ceil(((b-new Date(b.getFullYear(),0,1))/864E5+1)/7),c=c+"";2>c.length&&(c="0"+c);for(b=b.getFullYear()+"";4>b.length;)b="0"+b;return b+"-W"+c}function p(b,c){function k(a){"text"==a.getAttribute("type")&&a.addEventListener("keypress",function(b){b=b||l.event;var c;var f=null==b.which?b.keyCode:0!=b.which&&0!=b.charCode?b.which:null;c=q.decimal;var e=q.plusSign,h=q.minusSign,d,k= -a.getAttribute("data-val-correcttype-type")||"3";d=parseInt(k);k=3==d;d=1!=d;var g=a.getAttribute("min");g||(g=a.getAttribute("data-val-range-min"));g&&0<=parseFloat(g)&&(d=!1);0==f||13==f||9==f||8==f||48<=f&&57>=f?c=!0:!d||f!=e.charCodeAt(0)&&f!=h.charCodeAt(0)?k&&f==c.charCodeAt(0)?(f=a.value,c=0>f.indexOf(c)):c=!1:(f=a.value,c=0>f.indexOf(e)&&0>f.indexOf(h));c||b.preventDefault()})}if(!D){d.Globalize=function(){return c};var a=b.editFormats||{},h;for(h in E)e[h]=a[h]===S?E[h]:a[h];var a=c.locale().attributes.language, -q=c.cldr.get("main/"+a).numbers["symbols-numberSystem-latn"];F=c.dateParser({raw:"HH:mm:ss"});G=c.dateParser({raw:"HH:mm"});r=function(a){return F(a)||G(a)};H=c.dateParser({raw:"yyyy-MM-ddTHH:mm:ss"});I=c.dateParser({raw:"yyyy-MM-ddTHH:mm"});t=function(a){return H(a)||I(a)};u=c.dateParser({raw:"yyyy-MM-dd"});v=c.dateParser({raw:"yyyy-MM"});J=c.dateFormatter({raw:"HH:mm:ss"});K=c.dateFormatter({raw:"yyyy-MM-ddTHH:mm:ss"});L=c.dateFormatter({raw:"yyyy-MM-dd"});M=c.dateFormatter({raw:"yyyy-MM"});w=c.numberParser(); -var n=c.dateParser(e.timeFormat),p=c.dateParser(e.timeFormat1);N=function(a){return n(a)||p(a)};var C=c.dateParser(e.datetimeFormat),T=c.dateParser(e.datetimeFormat1);O=function(a){return C(a)||T(a)};P=c.dateParser(e.dateFormat);Q=c.dateParser(e.weekFormat);R=c.dateParser(e.monthFormat);g=c.numberFormatter();x=c.dateFormatter(e.timeFormat);y=c.dateFormatter(e.datetimeFormat1);z=c.dateFormatter(e.dateFormat);A=c.dateFormatter(e.weekFormat);B=c.dateFormatter(e.monthFormat);b.browserSupport||(b.browserSupport= -{});b.browserSupport.fallbackHtml5=!0;a=b.browserSupport.fallbacks=b.browserSupport.fallbacks||{};a.number||(a.number={});a.number.type||(a.number.type=2);a.date||(a.date={});a.date.type||(a.date.type=2);a.datetime||(a.datetime={});a.datetime.type||(a.datetime.type=2);a.time||(a.time={});a.time.type||(a.time.type=2);a.week||(a.week={});a.week.type||(a.week.type=2);a.month||(a.month={});a.month.type||(a.month.type=2);(a=b.browserSupport.handlers)||(a=b.browserSupport.handlers={});a.enhance||(a.enhance= -{});a.enhance.number||(a.enhance.number=k);a.enhance.range||(a.enhance.range=k);if(!a.translateVal){var U={range:function(a){return a?g(parseFloat(a)):""},number:function(a){return a?g(parseFloat(a)):""},time:function(a){return a?x(r(a)):""},datetime:function(a){return a?y(t(a)):""},date:function(a){return a?z(u(a)):""},month:function(a){return a?B(v(a)):""},week:function(a){return A(m(a))}};a.translateVal=function(a,b,c){if(!a)return"";var d=U[b];return d&&"text"==c?d(a,b,c):a}}D=!0}}function C(){support= -d.getSupport().Html5InputSupport;var b={range:2=b.getDay()?b.setDate(b.getDate()-b.getDay()+1):b.setDate(b.getDate()+8-b.getDay());return b} +function n(b){b=new Date(+b);b.setHours(0,0,0);b.setMilliseconds(0);b.setDate(b.getDate()+4-(b.getDay()||7));var a=Math.ceil(((b-new Date(b.getFullYear(),0,1))/864E5+1)/7),a=a+"";2>a.length&&(a="0"+a);for(b=b.getFullYear()+"";4>b.length;)b="0"+b;return b+"-W"+a}function u(b,a){function H(h){"text"==h.getAttribute("type")&&h.addEventListener("keypress",function(b){b=b||m.event;var c;var a=null==b.which?b.keyCode:0!=b.which&&0!=b.charCode?b.which:null;c=v.decimal;var f=v.plusSign,e=v.minusSign,d,g= +h.getAttribute("data-val-correcttype-type")||"3";d=parseInt(g);g=3==d;d=1!=d;var k=h.getAttribute("min");k||(k=h.getAttribute("data-val-range-min"));k&&0<=parseFloat(k)&&(d=!1);0==a||13==a||9==a||8==a||48<=a&&57>=a?c=!0:!d||a!=f.charCodeAt(0)&&a!=e.charCodeAt(0)?g&&a==c.charCodeAt(0)?(a=h.value,c=0>a.indexOf(c)):c=!1:(a=h.value,c=0>a.indexOf(f)&&0>a.indexOf(e));c||b.preventDefault()})}if(!I){d.Globalize=function(){return a};var c=b.editFormats||{},f;for(f in J)e[f]=c[f]===T?J[f]:c[f];var c=a.locale().attributes.language, +v=a.cldr.get("main/"+c).numbers["symbols-numberSystem-latn"];K=a.dateParser({raw:"HH:mm:ss"});L=a.dateParser({raw:"HH:mm"});p=function(a){return K(a)||L(a)};M=a.dateParser({raw:"yyyy-MM-ddTHH:mm:ss"});N=a.dateParser({raw:"yyyy-MM-ddTHH:mm"});q=function(a){return M(a)||N(a)};r=a.dateParser({raw:"yyyy-MM-dd"});t=a.dateParser({raw:"yyyy-MM"});w=a.dateFormatter({raw:"HH:mm:ss"});x=a.dateFormatter({raw:"yyyy-MM-ddTHH:mm:ss"});y=a.dateFormatter({raw:"yyyy-MM-dd"});z=a.dateFormatter({raw:"yyyy-MM"});A=a.numberParser(); +var k=a.dateParser(e.timeFormat),n=a.dateParser(e.timeFormat1);O=function(a){return k(a)||n(a)};var u=a.dateParser(e.datetimeFormat),G=a.dateParser(e.datetimeFormat1);P=function(a){return u(a)||G(a)};Q=a.dateParser(e.dateFormat);R=a.dateParser(e.weekFormat);S=a.dateParser(e.monthFormat);l=a.numberFormatter();B=a.dateFormatter(e.timeFormat);C=a.dateFormatter(e.datetimeFormat1);D=a.dateFormatter(e.dateFormat);E=a.dateFormatter(e.weekFormat);F=a.dateFormatter(e.monthFormat);b.browserSupport||(b.browserSupport= +{});b.browserSupport.fallbackHtml5=!0;c=b.browserSupport.fallbacks=b.browserSupport.fallbacks||{};c.number||(c.number={});c.number.type||(c.number.type=2);c.date||(c.date={});c.date.type||(c.date.type=2);c.datetime||(c.datetime={});c.datetime.type||(c.datetime.type=2);c.time||(c.time={});c.time.type||(c.time.type=2);c.week||(c.week={});c.week.type||(c.week.type=2);c.month||(c.month={});c.month.type||(c.month.type=2);(c=b.browserSupport.handlers)||(c=b.browserSupport.handlers={});c.enhance||(c.enhance= +{});c.enhance.number||(c.enhance.number=H);c.enhance.range||(c.enhance.range=H);if(!c.translateVal){var U={range:function(a){return a?l(parseFloat(a)):""},number:function(a){return a?l(parseFloat(a)):""},time:function(a){return a?B(p(a)):""},datetime:function(a){return a?C(q(a)):""},date:function(a){return a?D(r(a)):""},month:function(a){return a?F(t(a)):""},week:function(a){return E(g(a))}};c.translateVal=function(a,b,c){if(!a)return"";var f=U[b];return f&&"text"==c?f(a,b,c):a}}I=!0}}function G(){support= +d.getSupport().Html5InputSupport;var b={range:2 void; - range?: (node: HTMLHtmlElement) => void; - date?: (node: HTMLHtmlElement) => void; - month?: (node: HTMLHtmlElement) => void; - week?: (node: HTMLHtmlElement) => void; - time?: (node: HTMLHtmlElement) => void; - datetime?: (node: HTMLHtmlElement) => void; - email?: (node: HTMLHtmlElement) => void; - search?: (node: HTMLHtmlElement) => void; - tel?: (node: HTMLHtmlElement) => void; - url?: (node: HTMLHtmlElement) => void; - color?: (node: HTMLHtmlElement) => void; + number?: (node: HTMLElement, originalNode: HTMLElement) => void; + range?: (node: HTMLElement, originalNode: HTMLElement) => void; + date?: (node: HTMLElement, originalNode: HTMLElement) => void; + month?: (node: HTMLElement, originalNode: HTMLElement) => void; + week?: (node: HTMLElement, originalNode: HTMLElement) => void; + time?: (node: HTMLElement, originalNode: HTMLElement) => void; + datetime?: (node: HTMLElement, originalNode: HTMLElement) => void; + email?: (node: HTMLElement, originalNode: HTMLElement) => void; + search?: (node: HTMLElement, originalNode: HTMLElement) => void; + tel?: (node: HTMLElement, originalNode: HTMLElement) => void; + url?: (node: HTMLElement, originalNode: HTMLElement) => void; + color?: (node: HTMLElement, originalNode: HTMLElement) => void; } export interface Html5FallbackHandler{ @@ -75,6 +75,20 @@ url: number; color: number; } + export interface Html5InputFallbackWidgetsOptions{ + number?: any; + range?: any; + date?: any; + month?: any; + week?: any; + time?: any; + datetime?: any; + email?: any; + search?: any; + tel?: any; + url?: any; + color?: any; + } export interface Formats{ dateFormat?: string; timeFormat?: string; @@ -86,6 +100,7 @@ } export interface Options { browserSupport?: BrowserSupportOptions; + html5FallbackWidgets?: Html5InputFallbackWidgetsOptions; editFormats?: Formats; runReady?: boolean; [propName: string]: any; @@ -113,8 +128,8 @@ export function removeDependency(handle: any): void; export function getSupport(): Html5Infos; export function addBasicInput(Globalize: any); - export function format(type: string, value: any): string; - export function parse(type: string, value: string): any; + export function format(type: string, value: any, invariant?: boolean): string; + export function parse(type: string, value: string, invariant?: boolean): any; export function Globalize(): any; } } diff --git a/mvcct.enhancer.js b/mvcct.enhancer.js index c4b37e1..c8197d1 100644 --- a/mvcct.enhancer.js +++ b/mvcct.enhancer.js @@ -278,7 +278,7 @@ if (!options["handlers"] || !options["handlers"]["replace"]) { html5ProcessInfos["handlers"]["replace"] = function (type, support) { - if (type == "number" || type == "date" || type == "datetime-local" || type == "month" || type == "time" || type == "week") + if (type == "number" || type == "date" || type == "datetime-local" || type == "month" || type == "time" || type == "week" || type == "color") return "text"; else if (type == "range") { if (support.range > 2 || support.number < 4) return "text"; @@ -322,10 +322,11 @@ input.setAttribute("type", replace); input.setAttribute("value", handlers["translateVal"](node.getAttribute("value"), stype, replace)); copyAttrs(node, input); + if(type == "range") input.setAttribute("data-is-range", "true"); node.parentNode.replaceChild(input, node); - if (handlers["enhance"] && handlers["enhance"][type]) handlers["enhance"][type](input); + if (handlers["enhance"] && handlers["enhance"][stype]) handlers["enhance"][stype](input, node); } - enhancer["register"](null, false, null, "html5 support", function (options) { options = options || {}; preProcessOptions(options["browserSupport"]) }); + enhancer["register"](null, false, function (options) { options = options || {}; preProcessOptions(options["browserSupport"]) }, "html5 support"); enhancer["register"](processAllNodes, true, function (options) { options = options || {}; processOptions(options["browserSupport"]) }, "html5 enhance"); }(enhancer)); diff --git a/mvcct.enhancer.min.js b/mvcct.enhancer.min.js index 515d118..b87e7a4 100644 --- a/mvcct.enhancer.min.js +++ b/mvcct.enhancer.min.js @@ -1,9 +1,10 @@ -(function(){(function(q){var p=this||(0,eval)("this");(function(g){if("function"===typeof define&&define.amd)define(["exports","require"],g);else if("object"===typeof exports&&"object"===typeof module)g(module.exports||exports);else{var m=p.mvcct=p.mvcct||{};g(m.enhancer={})}})(function(g){function m(c){for(var a=0;aa.o?"text":"number":b};l.handlers.translateVal=b.handlers&&b.handlers.translateVal?b.handlers.translateVal:function(b){return b};k=l.handlers;k.fullReplace=b&&b.handlers?b.handlers.fullReplace:null;k.enhance=b&&b.handlers?b.handlers.enhance:{};e()}function g(b){var a=b.getAttribute("type"),c="datetime-local"==a?"datetime":a;if(!(3b.o?"text":"number":a};l.handlers.translateVal=a.handlers&&a.handlers.translateVal?a.handlers.translateVal:function(a){return a};k=l.handlers;k.fullReplace=a&&a.handlers?a.handlers.fullReplace:null;k.enhance=a&&a.handlers?a.handlers.enhance:{};e()}function g(a){var b=a.getAttribute("type"),c="datetime-local"==b?"datetime":b;if(!(3