3

我正在实施信用卡到期日验证,其中月份和年份位于单独的下拉列表中;它几乎就在那里,除了一个小的布局问题。

小提琴

HTML 如下所示:

<form id="myform">
<table>
<tr>
    <th colspan="2"><label class="secure-section-title" for="ccexp">Expiration date</label></th>
</tr>
<tr>
    <td><select id="ccexp" name="cc_exp_month" class="required creditcardexpiry">
        <option value="01">01</option> ... <option value="12">12</option>
      </select> / <select name="cc_exp_year" class="required creditcardexpiry">
        <option value="2012">12</option> ... <option value="2021">21</option>
    </select></td>
    <td></td>
</tr>
</table>
</form>​

执行验证的 JavaScript 在这里:

$('#myform').validate({
    errorPlacement: function(error, element) {
        element
            .closest('tr') // take closest parent
            .prev('tr')
            .find('> th')
            .append(error)
        },
        groups: {
            creditcardexpiry: 'cc_exp_month cc_exp_year'
        }
    });

$.validator
    .addMethod('creditcardexpiry', function(value, element) {
        var form = element.form,
        expiry = form['cc_exp_year'].value + form['cc_exp_month'].value,
        date = new Date(),
        month = date.getMonth() + 1,
        now = '' + date.getFullYear() + (month < 10 ? '0' + month : month);

        return expiry > now;
    });

它基本上仅在到期日是未来一个月的情况下才有效(未来 10 年的最大值受下拉列表的限制)。

问题场景是这样的:

  1. 输入过去的日期;将显示错误消息并且下拉菜单为红色

  2. 通过将年份增加到 2014 来修复错误;错误消息消失

问题是月份下拉菜单仍然是红色的,直到再次点击!这些字段是分组的,所以我希望在解决无效条目时两个下拉菜单都会被清除。

我在这里忽略了一些明显的东西还是这是一个错误?

更新

这并不是关于groups属性的真正错误,因为这只是确保两个字段中的错误不会导致两条消息。

4

2 回答 2

3

显然,下拉菜单通过触发点击事件来重新验证(默认情况下)。所以我的解决方案是在两个下拉菜单的选择值发生变化时触发它们之间的点击。

var $expiryFields = form.find('.creditcardexpiry');

$expiryFields.on('change', function() {
    // trigger click on the other field to force revalidation
    $expiryFields.not(this).trigger('click');
});

我对这个修复不是很满意,所以我希望其他人能想出更好的东西。

演示

于 2012-12-05T04:43:34.580 回答
0

jQuery.validator.element可用于验证单个元素。实现稍微有点冗长,但更重要的是:

var $expiryFields = $form.find('.creditcardexpiry'),
    $validator = $form.validate();

$expiryFields.change(function() {
    $expiryFields.not(this).each(function () {$validator.element(this)});
});
于 2014-03-23T21:11:15.193 回答