做軟件產品有時會遇到一個困惑,那就是如何樣式化(格式化)用戶的不規則輸入。以日期/時間的輸入爲例,前些年比較通用的做法是寫一段js代碼來判斷用戶的輸入是否正確,如果不正確就提示要以某某格式錄入,這種方式不僅費時費力,而且頗有馬後炮之嫌。如何能夠引導客戶按照正確的格式填寫我們所需的內容?我的看法是,可以剝奪用戶手動輸入的權利,只允許其在運行的範圍內選擇和調整。
我的初步設想是,對於一個用來進行時間輸入的文本框,當鼠標移入時,如果文本框爲空,則自動顯示0:00這一基準時間以供調整。當鼠標指向小時部分,向上轉動鼠標滾輪或按鍵盤的向上方向鍵,則小時數值增加,向下轉動鼠標滾輪或按鍵盤的向下方向鍵,則小時數值增加。同樣,也可以使用鼠標滾輪或者鍵盤方向鍵調整分鐘數值。此外,使用鍵盤的左右方向鍵可以在小時和分鐘兩部分之間切換。
爲此,寫了一堆js代碼來實現設想的功能,最終效果如下。
但是,麻煩很快就再次拜訪了。爲了使用這個功能,必須每次都爲該文本框添加onmouseover等很多事件,太煩。怎麼才能讓這個功能可方便的複用?HTC應該會是個好的主意。
有關HTML Component(HTC)的介紹可參見http://www.blueidea.com/tech/web/2003/1227.asp,藍色理想的這篇文章是我HTC入門的好導師,再此多謝了~~
使用了HTC後,頁面代碼得到了極大的簡化,只需引用樣式表dateinput.css併爲需要使用時間控件的文本框指定class爲dateinput即可。以下是dateinput.htm的內容。
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<link href="dateinput.css" rel="stylesheet" type="text/css">
</HEAD>
<BODY>
<INPUT TYPE="text" NAME="minute" value="" class="dateinput" readonly>
可以使用方向鍵或鼠標滾輪調整時間,呵呵
</BODY>
</HTML>
以下是dateinput.css的內容。
behavior:url(dateinput.htc)
}
以下是dateinput.htc的內容。
<PUBLIC:ATTACH EVENT="onmousewheel" oNEVENT="setTime()"/>
<PUBLIC:ATTACH EVENT="onkeydown" oNEVENT="setTimeByKB()"/>
<PUBLIC:ATTACH EVENT="onmouseout" oNEVENT="unselTime()"/>
<PUBLIC:METHOD NAME="regainTimeObj"/>
<PUBLIC:METHOD NAME="setObjValue"/>
<script language="javascript">
var h, m;
var sel;
var iValue;
function selTime(){
if(element.value == "")
element.value = "0:00";
var bdy = document.body;
regainTimeObj();
var baseLeft = bdy.leftMargin * 1 + element.offsetParent.offsetLeft * 1;
var hLeft = baseLeft + h.offsetLeft * 1;
var hRight = hLeft + h.boundingWidth;
var mLeft = baseLeft + m.offsetLeft * 1;
var mRight = mLeft + m.boundingWidth;
var mouseX = window.event.clientX;
if (mouseX >= hLeft && mouseX <= hRight){
h.select();
sel = 1;
}
if (mouseX >= mLeft && mouseX <= mRight){
m.select();
sel = 2;
}
}
function unselTime(){
h = null;
m = null;
sel = -1;
}
function setTime(){
var step = parseInt(event.wheelDelta / 120, 10);
switch(sel){
case 1:
setObjValue(h, step);
break;
case 2:
setObjValue(m, step);
break;
}
//return false;
}
function setTimeByKB(){
var kc = event.keyCode;
switch(kc){
case 37: //left
switch(sel){
case 2:
h.select();
sel--;
break;
default:
break;
}
break;
case 38: //up
switch(sel){
case 1:
setObjValue(h, 1);
break;
case 2:
setObjValue(m, 1);
break;
default:
break;
}
break;
case 39: //right
switch(sel){
case 1:
m.select();
sel++;
break;
default:
break;
}
break;
case 40: //down
switch(sel){
case 1:
setObjValue(h, -1);
break;
case 2:
setObjValue(m, -1);
break;
default:
break;
}
break;
default:
alert("請使用方向鍵或鼠標滾輪調整數字大小。");
break;
}
return false;
}
function regainTimeObj(){
var wholeText = element.value;
if(!wholeText || wholeText == "")
wholeText = "0:00";
var pos = wholeText.indexOf(":");
var length = wholeText.length;
h = element.createTextRange();
m = element.createTextRange();
h.moveEnd("character", pos - length);
m.moveStart("character", pos + 1);
switch(sel){
case 1:
h.select();
break;
case 2:
m.select();
break;
}
}
function setObjValue(obj, step){
iValue = parseInt(obj.text, 10) + step;
var maxValue = 59;
var addZero = false;
switch(obj){
case h:
maxValue = 23;
addZero = false;
break;
case m:
maxValue = 59;
addZero = true;
break;
default:
}
if(iValue > maxValue)
iValue = 0;
if(iValue < 0)
iValue = maxValue;
if(addZero){
if(iValue.toString().length == 1)
iValue = "0" + iValue;
}
obj.text = iValue.toString();
regainTimeObj();
}
</script>