Javascript 依赖于ExtJs的字段验证

Javascript 依赖于ExtJs的字段验证,javascript,validation,extjs,Javascript,Validation,Extjs,如何验证依赖于另一个字段的字段 { xtype: 'textfield', name: 'name2', vtype: 'type', // how to write the validation code for this if it // depends on the value of another field? allowBlank:

如何验证依赖于另一个字段的字段

{
  xtype:          'textfield',
  name:           'name2',
  vtype:          'type',      // how to write the validation code for this if it 
                               // depends on the value of another field?
  allowBlank:     false
}

通过添加您自己的自定义验证器并在其中执行验证

var field_one = new Ext.form.TextField({
    name: 'field_one',
    fieldLabel: 'Field one'
});

var field_two = new Ext.form.TextField({
    name: 'field_two',
    fieldLabel: 'Field two',
    validator: function(value){
        if(field_one.getValue() != value) {
            return 'Error! Value not identical to field one';
        } else {
            return true;
        }
    }
});
字段定义:

....
monitorValid:     true,
....
}, {
  xtype:          'textfield',
  name:           'name1',
  ref:            'name1',

}, {
  xtype:          'textfield',
  name:           'name2',
  ref:            'name2',
  allowBlank:     false,
....
initComponent中的下一步(或侦听器,如果您预先提供):

并在FormPanel中定义处理程序:

this._validate_name2: function ( ) {
   if ( this.name1.getValue () == this.name2.getValue () ) {
      this.name2.markInvalid ( 'field does not match name1' );
      this.name2.setValue ( null );
   }
}
“如果值未通过验证,则markInvalid()方法不会导致字段的validate方法返回false。因此,仅将字段标记为无效不会阻止提交随Ext.form.Action.Submit.clientValidation选项集一起提交的表单。”


由于这个原因,allowBlank和setValue(null)的组合将破坏验证

我在Ext JS 5.1中模拟了一个如何使用组合框实现这一点的示例。。。它很容易移植到ext4代码,您只需使用
initComponent
而不是ViewController的
init
。以下是代码(和):

Ext.application({
名字:“小提琴”,
启动:函数(){
Ext.define('MyComboViewController'{
扩展:“Ext.app.ViewController”,
别名:“controller.mycombo”,
init:function(){
this.getView().setStore(this.createStore());
},
createStore:function(){
var store=Ext.create('Ext.data.store'{
字段:[
{name:'disp',type:'string'},
{name:'val',type:'int'}
],
数据:[
{disp:'One',val:1},
{disp:'Two',val:2},
{disp:'3',val:3},
{disp:'Four',val:4},
{disp:'5',val:5}
],
代理:{
键入:“内存”
}
});
退货店;
}
});
Ext.define('MyCombo'{
扩展:“Ext.form.field.ComboBox”,
xtype:'myCombo',
控制员:“mycombo”,
显示字段:“disp”,
valueField:'val',
labelAlign:“顶部”,
更改:错误,
是的,
queryMode:“本地”
});
Ext.define('MyCombosContainerViewController'{
扩展:“Ext.app.ViewController”,
别名:“controller.mycomboscontainer”,
init:function(){
var startCombo=this.lookupReference('startCombo');
var endCombo=this.lookupReference('endCombo');
startCombo.validator=Ext.bind(this.comboValidator,this[startCombo,endCombo]);
endCombo.validator=Ext.bind(this.comboValidator,this[startCombo,endCombo]);
},
组合验证器:函数(startCombo、endCombo){
返回startCombo.getValue()
为了验证链接字段,我通常会创建一个函数(我将它添加到我的
Ext.lib.Validators
类中,这样我就可以在整个应用程序中调用它),该函数返回一个具有预配置作用域和验证逻辑的匿名函数(这样我就可以在整个应用程序中多次使用它)

以下是一个例子:

myValidator: function (firstFieldSelector, secondFieldSelector, thirdFieldSelector) {
    return function () {
        var firstField = Ext.ComponentQuery.query(firstFieldSelector)[0],
            secondField= Ext.ComponentQuery.query(secondFieldSelector)[0],
            thirdField= Ext.ComponentQuery.query(thirdFieldSelector)[0];

        if (firstField && secondField && thirdField) {
            // Validation logic here...
            if( true ) {
                return true;
            } else {
                return 'Error text here...';
            }
        } else {
            // Validator incorrectly configured, do not validate with it
            return true;
        }
    }
}

这里是一个带有时间跨度的选择。

一般来说,我建议在所有需要交叉验证的字段上连接更改事件侦听器。在ChangeEventHandler中,我们需要在需要修改字段进行验证的每个其他字段上触发验证。当你有一个表单,并且有很多字段和很多验证需要完成时,这种方法非常有效。

回答得好,但是如何在其他地方执行验证,例如在另一个按钮的操作侦听器中。这也是可能的,但你必须通过作用域或
Ext.getCmp()获取对元素的引用
如果您在按钮处理程序中。然后执行验证并使用
field手动将字段标记为无效。对于@ChrisR有关获取引用的注释,标记无效(“…”)
。很可能您的字段在同一个容器中。因此,您可以很容易地获得对验证器函数中其他字段的引用
该函数中的
是验证程序配置的文本字段。使用以下命令获取对其他字段的引用:
var otherField=this.up().down('field[name=field\u one]')
(ExtJS 4)次要注意:通常在调用
Ext.application
Ext.application({
  name: 'Fiddle',

  launch: function() {
    Ext.define('MyComboViewController', {
      extend: 'Ext.app.ViewController',
      alias: 'controller.mycombo',
      init: function() {
        this.getView().setStore(this.createStore());
      },
      createStore: function() {
        var store = Ext.create('Ext.data.Store', {
          fields: [
            {name: 'disp', type: 'string'},
            {name: 'val', type: 'int'}
          ],
          data: [
            {disp: 'One', val: 1},
            {disp: 'Two', val: 2},
            {disp: 'Three', val: 3},
            {disp: 'Four', val: 4},
            {disp: 'Five', val: 5}
          ],
          proxy: {
            type: 'memory'
          }
        });
        return store;
      }
    });

    Ext.define('MyCombo', {
      extend: 'Ext.form.field.ComboBox',
      xtype: 'myCombo',
      controller: 'mycombo',
      displayField: 'disp',
      valueField: 'val',
      labelAlign: 'top',
      validateOnChange: false,
      typeAhead: true,
      queryMode: 'local'
    });

    Ext.define('MyCombosContainerViewController', {
      extend: 'Ext.app.ViewController',
      alias: 'controller.mycomboscontainer',
      init: function() {
        var startCombo = this.lookupReference('startCombo');
        var endCombo = this.lookupReference('endCombo');
        startCombo.validator = Ext.bind(this.comboValidator, this, [startCombo, endCombo]);
        endCombo.validator = Ext.bind(this.comboValidator, this, [startCombo, endCombo]);
      },
      comboValidator: function(startCombo, endCombo) {
        return startCombo.getValue() < endCombo.getValue();
      },
      onSelectComboBox: function(combo) {
        var startCombo = this.lookupReference('startCombo');
        var endCombo = this.lookupReference('endCombo');
        startCombo.validate();
        endCombo.validate();
      }
    });

    Ext.define('MyCombosContainer', {
      extend: 'Ext.form.FieldContainer',
      controller: 'mycomboscontainer',
      layout: {
        type: 'hbox',
        align: 'stretch'
      },
      items: [{
        xtype: 'myCombo',
        reference: 'startCombo',
        fieldLabel: 'Start',
        listeners: {
          select: 'onSelectComboBox'
        }
      }, {
        xtype: 'myCombo',
        reference: 'endCombo',
        fieldLabel: 'End',
        listeners: {
          select: 'onSelectComboBox'
        }
      }]
    });

    Ext.create('MyCombosContainer', {
      renderTo: Ext.getBody()
    });
  }
});
myValidator: function (firstFieldSelector, secondFieldSelector, thirdFieldSelector) {
    return function () {
        var firstField = Ext.ComponentQuery.query(firstFieldSelector)[0],
            secondField= Ext.ComponentQuery.query(secondFieldSelector)[0],
            thirdField= Ext.ComponentQuery.query(thirdFieldSelector)[0];

        if (firstField && secondField && thirdField) {
            // Validation logic here...
            if( true ) {
                return true;
            } else {
                return 'Error text here...';
            }
        } else {
            // Validator incorrectly configured, do not validate with it
            return true;
        }
    }
}