Thursday, 27 November 2008

Hack on FormCheck : Union Validate with Lock

上一篇中,描述了如何用自定义validate函数,进行多个INPUT元素的联合检查。

在那里,是把myvalidate设置在多个INPUT中的某个元素上。这样的做法,是为了避免出现validate的递归调用,导致无限循环。但在实际应用的过程中,用户的实际使用体验,并不是最好的,因为实际的错误提示,总是出现在那一个INPUT元素上,而不是最近输入元素。

要想获得更好的用户体验,又要避免“死循环”的出现,可以使用“锁”的机制。下面介绍一个实际使用“锁”的例子。

在页面上,有两个INPUT元素,分别是最小值和最大值。正常的逻辑,最小值不能大于最大值,最大值不能小于最小值。这项检查,由自定义validate函数avOrder()来完成。

   1: <label><span>Minimum:</span>
   2: <input type="text" name="minValue" class="validate['required','digit','~avOrder']" /></label>
   3: <label><span>Maximum:</span>
   4: <input type="text" name="maxValue" class="validate['required','digit','~avOrder']" /></label>
   5:  
   6: <input type="submit" class="validate['submit']" value="Validate" />

相应的JavaScript Code:

   1: window.addEvent('domready', pageInitial);
   2:  
   3: var avLockCheck = null;
   4:  
   5: function pageInitial() {
   6:   avLockCheck = new FormCheck('avLockForm');
   7: }
   8:  
   9: var avlock = false;
  10: function avOrder(el) {
  11:   if( avlock )  return true;
  12:   avlock = true;
  13:  
  14:   var elParent = el.getParent('p');
  15:  
  16:   var minEl = elParent.getElement("[name^=min]");
  17:   var maxEl = elParent.getElement("[name^=max]");
  18:  
  19:   if( avLockCheck.validate( minEl ) && avLockCheck.validate( maxEl ) &&
  20:                          Number(minEl.value) > Number(maxEl.value) ) {
  21:       var errorMsg = (el == minEl ?
  22:                      "This value is great than maximum." :
  23:                      "This value is less than minimum." );
  24:       el.errors.push( errorMsg );
  25:  
  26:       avlock = false;
  27:       return false;
  28:   }
  29:  
  30:   avlock = false;
  31:   return true;
  32: }

在这段Code中,设置了一个“锁”变量avlock。进入avOrder(),检查“锁”状态,然后上“锁”。在退出avOrder()的时候,解“锁”。

在20行,实际隐含了一个迭代检查过程。利用“锁”机制,有效地防止了“死循环”的出现。

21行,针对不同的INPUT元素,给出相应的出错提示信息。

avOrder()中的16、17行,没有指定元素的具体tag,实际可以用来处理<INPUT>和<SELECT>标签。

通过minElmaxEl的获取方式,可以知道,<p>在这里被用作了分组标签。如果页面上有多组类似的,需要比较最大值和最小值的INPUT元素,avOrder()能够利用<p>进行分组,自动匹配对应的最大值、最小值元素。

页面上的INPUT元素,都附加了avOrder()检查,也都会给出相应提示。

0 Comments:

Post a Comment

<< Home