Skip to content

Commit f90993b

Browse files
committed
Adds partial support for typing text fields.
1 parent 10781c8 commit f90993b

File tree

1 file changed

+158
-15
lines changed

1 file changed

+158
-15
lines changed

jquery.timeInput.js

+158-15
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,62 @@ function strtodate (str, now) {
834834
}
835835

836836
var _cfn = {
837-
837+
a: _c_dayOfWeek,
838+
A: _c_dayOfWeek,
839+
d: 'setDate',
840+
e: 'setDate',
841+
j: _c_dayOfYear,
842+
u: 'setDate',
843+
w: 'setDate',
844+
b: 'setMonth',
845+
B: 'setMonth',
846+
h: 'setMonth',
847+
m: 'setMonth',
848+
C: _c_century,
849+
g: _c_2year,
850+
G: 'setFullYear',
851+
y: _c_2year,
852+
Y: 'setFullYear',
853+
H: 'setHours',
854+
I: _c_12hour,
855+
l: _c_12hour,
856+
p: _c_meridian,
857+
P: _c_meridian,
858+
M: 'setMinutes',
859+
S: 'setSeconds',
860+
s: 'setSeconds'
861+
}
862+
863+
function _c_century(date,tokenVal) {
864+
return date;
865+
}
866+
function _c_2year(date,tokenVal) {
867+
return date;
868+
}
869+
function _c_12hour(date,tokenVal) {
870+
return date;
871+
}
872+
function _c_meridian(date,tokenVal) {
873+
// 0= am, 1= pm
874+
var ret = new Date(date);
875+
if(tokenVal) {
876+
if(date.getHours() <12)
877+
ret.setHours(ret.getHours()+12);
878+
} else {
879+
if(date.getHours() >=12)
880+
ret.setHours(ret.getHours()-12);
881+
}
882+
return ret;
883+
}
884+
function _c_dayOfWeek(date,tokenVal) {
885+
var c= tokenVal-date.getDay();
886+
if(tokenVal-c <0)
887+
c+=7;
888+
return new Date(date.getTime()+c*86400000);
889+
}
890+
891+
function _c_dayOfYear(date,tokenVal) {
892+
return date;
838893
}
839894

840895
function _m_day(data,inc) {
@@ -917,7 +972,6 @@ function strtodate (str, now) {
917972

918973

919974
function utcdate(format,dateObject,offset) {
920-
921975
var f =strftime(format,new Date(dateObject.getTime()+offset));
922976
return f;
923977
}
@@ -972,6 +1026,18 @@ function strtodate (str, now) {
9721026
setTimeout(function(){selectRange(data.element,currentCharIndex,endCharIndex)},0);
9731027
}
9741028

1029+
function selectPartialToken(data,currentToken,length) {
1030+
var currentCharIndex = 0;
1031+
for(var i=0; i<currentToken;i++) {
1032+
currentCharIndex+=(data.tokens[i].r?utcdate("%"+data.tokens[i].v,data.ds,data.timezoneOffset).trim():data.tokens[i].v).length
1033+
}
1034+
if(currentToken <0 || currentToken >= data.tokens.length)
1035+
return false;
1036+
var tokenValue = data.tokens[i].v;
1037+
var endCharIndex = currentCharIndex+length;
1038+
setTimeout(function(){selectRange(data.element,currentCharIndex,endCharIndex)},0);
1039+
}
1040+
9751041

9761042
function findTokenAtCursor(Self,position) {
9771043
var currentCharIndex = 0;
@@ -1091,19 +1157,83 @@ function strtodate (str, now) {
10911157
Self.element.size = Self.val().length;
10921158
}
10931159
}
1094-
/*
1160+
1161+
/**
1162+
* Handles inputting a character on a given token.
1163+
* We want to "change" a token within a current context, eg, hours within a day,
1164+
* days within a week, months within a year. We aren't incrementing or
1165+
* decrementing, only changing.
1166+
*/
10951167
function inputCharacter(Self,char) {
10961168
var data = Self.data('timeInput');
1097-
if( data.currentInput.length ) {
1098-
var check = data.currentInput+char
1099-
// if check matches a valid value for the given token, allow it.
1100-
if(data.selectedToken && _lc_time[ data.tokens[data.selectedToken] ] ) {
1101-
var avail = _lc_time[ data.tokens[data.selectedToken] ];
1169+
if( ! data.currentInput )
1170+
data.currentInput = "";
1171+
var iCheck = data.currentInput+char;
1172+
1173+
/* only days of the week and month names will show up in this list */
1174+
if(data.currentToken>=0 && _lc_time[ data.tokens[data.currentToken].v ] ) {
1175+
var c = 0, v=0, f=null;
1176+
1177+
$.each(_lc_time[ data.tokens[data.currentToken].v ],function(i,e){
1178+
if( (e.toLowerCase()+'').indexOf(iCheck.toLowerCase(),0)===0 ) {
1179+
if(f===null)
1180+
f=i;
1181+
c++;
1182+
}
1183+
});
1184+
1185+
if(c==0) {
1186+
if(data.currentInput.length)
1187+
selectPartialToken(data,data.currentToken,data.currentInput.length);
1188+
else
1189+
selectToken(data,data.currentToken);
1190+
} else if (c==1) {
1191+
// set and move on.
1192+
if(inputSet(Self,data.tokens[data.currentToken].v,f)) {
1193+
data.currentInput = "";
1194+
Self.timeInput('updateDisplay');
1195+
if(data.currentToken == data.tokens.length-1) {
1196+
focusNextElement(Self.element);
1197+
} else if(selectNextToken(Self)){
1198+
selectToken(data,data.currentToken);
1199+
}
1200+
}
1201+
Self.trigger('change');
1202+
} else {
1203+
// set and update selection.
11021204

1205+
if(inputSet(Self,data.tokens[data.currentToken].v,f)) {
1206+
Self.timeInput('updateDisplay');
1207+
selectPartialToken(data,data.currentToken,iCheck.length);
1208+
data.currentInput = iCheck;
1209+
}
1210+
Self.trigger('change');
11031211
}
1212+
1213+
} else {
1214+
// might be numeric?
11041215
}
11051216
}
1106-
*/
1217+
// tokenVal is %M or similar, resultVal is a month's number to set.
1218+
function inputSet(Self,tokenVal,resultVal) {
1219+
if(typeof _cfn[tokenVal] === 'function') {
1220+
Self.data('timeInput').ds = _cfn[tokenVal].call(Self,Self.data('timeInput').ds,resultVal);
1221+
return true;
1222+
}else if(Date.prototype[ _cfn[tokenVal] ] ) {
1223+
var d = new Date(Self.data('timeInput').ds.getTime()+Self.data('timeInput').timezoneOffset);
1224+
d[ _cfn[tokenVal] ].call(d,resultVal);
1225+
Self.data('timeInput').ds = d;
1226+
return true;
1227+
}
1228+
return false;
1229+
}
1230+
function focusNextElement(ele) {
1231+
var fc = $(":focusable");
1232+
var current = fc.index(ele);
1233+
var next = fc.eq(current+1).length ? fc.eq(current+1) : fc.eq(0);
1234+
setTimeout(function(){next.focus()},0);
1235+
}
1236+
11071237
var _current = new Date();
11081238

11091239
var methods = {
@@ -1272,7 +1402,6 @@ function strtodate (str, now) {
12721402
* Handle the element's keypress.
12731403
*/
12741404
keydown: function(event) {
1275-
12761405
var key = {left: 37, up: 38, right: 39, down: 40, tab:9, enter:13, backspace: 8 };
12771406
var data = $(this).data('timeInput');
12781407
switch(event.which) {
@@ -1308,19 +1437,24 @@ function strtodate (str, now) {
13081437
break;
13091438
case(key.enter):
13101439
if(data.returnCompletesInput) {
1311-
var fc = $(":focusable");
1312-
var current = fc.index(data.element);
1313-
var next = fc.eq(current+1).length ? fc.eq(current+1) : fc.eq(0);
1314-
setTimeout(function(){next.focus()},0);
1440+
focusNextElement(data.element);
13151441
}
13161442
return false;
13171443
break;
1444+
case(key.backspace):
1445+
if(data.currentInput.length)
1446+
data.currentInput = data.currentInput.substring(0,-1);
1447+
if(data.currentInput.length)
1448+
inputCharacter($(this),'');
1449+
else
1450+
selectToken(data,data.currentToken);
1451+
break;
13181452

13191453
}
13201454
/* okay, so we didn't match the special keys, so it might be a number/letter */
13211455
var code=String.fromCharCode(event.which);
13221456
if(code.match(/[\d\w]/)) {
1323-
//inputCharacter($(this),code);
1457+
inputCharacter($(this),code);
13241458
}
13251459
return false;
13261460
},
@@ -1351,12 +1485,21 @@ function strtodate (str, now) {
13511485
}
13521486
selectToken(data,data.currentToken);
13531487
},
1488+
1489+
/**
1490+
* Clean up input and such.
1491+
*/
13541492
blur: function(event) {
13551493
var Self = $(this),
13561494
data = Self.data('timeInput');
13571495
data.currentToken = -1;
13581496
data.clicked=false
1497+
data.currentInput = null;
13591498
},
1499+
1500+
/**
1501+
* Mousedown and mouseup are used to click into a selection.
1502+
*/
13601503
mousedown: function(event) {
13611504
clearSelection();
13621505
$(this).data('timeInput').mouseDown = true;

0 commit comments

Comments
 (0)