title: ExtJS Having More Than One vType Applied To A Field
body: <p>I have seen examples that use built-in vTypes and custom ones for a field, but never a custom and built-in vType together. For example, here is one I am currently using in my code which I have found from the Sencha examples and forums (many thanks):</p>
  
  <pre><code>//Add the additional 'advanced' VTypes
  Ext.apply(Ext.form.VTypes, {
      daterange : function(val, field) {
          var date = field.parseDate(val);
  
          if(!date){
              return false;
          }
          if (field.startDateField) {
              var start = Ext.getCmp(field.startDateField);
              if (!start.maxValue || (date.getTime() != start.maxValue.getTime())) {
                  start.setMaxValue(date);
                  start.validate();
              }
          }
          else if (field.endDateField) {
              var end = Ext.getCmp(field.endDateField);
              if (!end.minValue || (date.getTime() != end.minValue.getTime())) {
                  end.setMinValue(date);
                  end.validate();
              }
          }
          /*
           * Always return true since we're only using this vtype to set the
           * min/max allowed values (these are tested for after the vtype test)
           */
              return true;
          }
  
  });
  </code></pre>
  
  <p>Although this prevents the users from picking start and end dates that are not chronologically correct and quite nicely I might add, it overrides the default which checks that the user entered a date in correct format. Any way to have both the advanced vType and the default working at the same time? Now users can simply put letters in these fields or incorrect date formats and there answers will be submitted with no error checking!  If something already exists for me to have multiple vTypes, I don't want to have to rewrite what is already written and reinvent the wheel. </p>
  
  <p>Thanks for your time,</p>
  
  <p>elshae </p>
  
  <p><strong>EDIT</strong>
  I am adding more of the form code by request.  It's very long, so I have cut some of it out.  I hope this will be enough...</p>
  
  <pre><code>this.captchaURL = "captcha/CaptchaSecurityImages.php?width=160&amp;height=80&amp;characters=4&amp;t=";
  
  var boxCaptcha =    new Ext.BoxComponent({
      columnWidth:.35,    
      autoEl: {
                  tag:'img'
                  ,id: 'activateCodeImg'
                  ,src:this.captchaURL+new Date().getTime()
              }
  });
  
  boxCaptcha.on('render',function (){
  var curr = Ext.get('activateCodeImg');
  curr.on('click',this.onCapthaChange,this);
  },this);
  
  function onCapthaChange(){
      var captchaURL = this.captchaURL;
      var curr = Ext.get('activateCodeImg');
      curr.slideOut('b', {callback: function(){
                  Ext.get( 'activateCodeImg' ).dom.src= captchaURL+new Date().getTime();
                  curr.slideIn('t');      
      }},this);
  }
  
  function getLang(){
       // decode language passed in url
     var locale = window.location.search 
                  ? Ext.urlDecode(window.location.search.substring(1))
                  : '';
     return locale['lang'];
  }//end getLang()
  
  var form;
  
  var lang = getLang();
  var languageFile;
  var localeFile;
  
  
  if (lang == 'chn'){
      languageFile = 'chinese.json'; 
      localeFile = '../ext-3.3.1/src/locale/ext-lang-zh_CN.js';
  }
  else if (lang == 'eng'){
      languageFile = 'english.json';
  }
  else if (lang == 'tib'){
      languageFile = 'tibetan.json'; 
      localeFile = '../ext-3.3.1/src/locale/ext-lang-zh_CN.js';
  }
  
  
  $.getScript(localeFile, function(){ 
  
  var i18n = {};
  
      $.getJSON(languageFile, i18n, function(data) { i18n = data.i18n; 
  
  
  Ext.BLANK_IMAGE_URL = '../ext-3.3.1/resources/images/default/s.gif';
  
  //Add the additional 'advanced' VTypes
  Ext.apply(Ext.form.VTypes, {
      daterange : function(val, field) {
          var date = field.parseDate(val);
  
          if(!date){
              return false;
          }
          if (field.startDateField) {
              var start = Ext.getCmp(field.startDateField);
              if (!start.maxValue || (date.getTime() != start.maxValue.getTime())) {
                  start.setMaxValue(date);
                  start.validate();
              }
          }
          else if (field.endDateField) {
              var end = Ext.getCmp(field.endDateField);
              if (!end.minValue || (date.getTime() != end.minValue.getTime())) {
                  end.setMinValue(date);
                  end.validate();
              }
          }
          /*
           * Always return true since we're only using this vtype to set the
           * min/max allowed values (these are tested for after the vtype test)
           */
          return true;
      }
  });
  
  Ext.onReady(function(){
      Ext.QuickTips.init();
  
          form = new Ext.form.FormPanel({
          id: 'scholarshipForm',
          //labelWidth: 200, // label settings here cascade unless overridden
          url:'scholarshipSubmit.php',
          method: 'POST',
          frame:true,
          layout: 'form',
          title: i18n.Apply,
          bodyStyle:'padding:10px 10px 0',
          width: 610,
          itemCls: 'formStyle',
          items: [{
              xtype:'fieldset',
              checkboxToggle:false,
              labelWidth: 200,
              title: i18n.Student_Information,
              autoHeight:true,
              layout: 'form',
              defaults: {width: 210},
              collapsed: false,
              items :[{
                      xtype: 'textfield',
                      fieldLabel: i18n.First_Name,
                      allowBlank:false,
                      name: 'first', 
                      maskRe: /([a-zA-Z\s]+)$/,
                      msgTarget: 'side'
                  },{
                      xtype: 'textfield',
                      fieldLabel: i18n.Last_Name,
                      allowBlank:false,
                      msgTarget: 'side',
                      name: 'last',
                      maskRe: /([a-zA-Z\s]+)$/
                  },{
                      xtype: 'radiogroup',
                      fieldLabel: i18n.Gender,
                      name: 'gender',
                      columns: 1,
                      rows: 2,
                      allowBlank:false,
                      msgTarget: 'side',
                      items: [
                              {boxLabel: i18n.Male, name: 'sex', inputValue: i18n.Male},
                              {boxLabel: i18n.Female, name: 'sex', inputValue: i18n.Female}
                              ]
                  },{
                      xtype: 'datefield',
                      fieldLabel: i18n.Date_of_Birth,
                      name: 'birthdate',
                      id: 'birthdate',
                      allowBlank:false,
                      msgTarget: 'side',
                      minValue: '02/24/1950',
                      maxValue: '02/24/1990',
                      //width: 210
                  },{
                      xtype: 'textfield',
                      fieldLabel: i18n.Place_of_Birth,
                      allowBlank:false,
                      name: 'pob',
                      msgTarget: 'side'
                  },/*{
                      xtype: 'compositefield',
                      fieldLabel: 'Phone',
                      // anchor    : '-20',
                      // anchor    : null,
                      msgTarget: 'under',
                      items: [
                          {xtype: 'displayfield', value: '('},
                          {xtype: 'textfield',    name: 'phone1', width: 29, allowBlank: false},
                          {xtype: 'displayfield', value: ')'},
                          {xtype: 'textfield',    name: 'phone2', width: 29, allowBlank: false, margins: '0 5 0 0'},
                          {xtype: 'textfield',    name: 'phone3', width: 48, allowBlank: false}
                      ]
                  }*/{
                      xtype: 'textfield',
                      fieldLabel: i18n.Phone,
                      msgTarget: 'under',
                      name: 'phone',
                      allowBlank: false,
                      maskRe: /[0-9]/,
                      msgTarget: 'side'
                  },{
                      xtype: 'textfield',
                      fieldLabel: i18n.Email,
                      name: 'email',
                      vtype:'email',
                      msgTarget: 'under',
                      allowBlank: false
                  },{
                      xtype: 'fieldset',
                      fieldLabel: i18n.Instant_Messaging + '1 '.sup(),
                      name: 'IM',
                      labelWidth: 50,
                      defaults: {width: 120},
                  items:[{
                      xtype: 'textfield',
                      fieldLabel: 'MSN',
                      name: 'msn'
                  },{
                      xtype: 'textfield',
                      fieldLabel: 'Skype',
                      name: 'skype'
                  }]}  
              ]
          },{
              xtype:'fieldset',
              title: i18n.Previous_Schooling + '2 '.sup(),
              collapsible: false,
              autoHeight:true,
              labelWidth: 150,
             // defaultType: 'textfield',
              items :[{xtype: 'tabpanel',
                  activeTab: 0,
                  width: 550,
                  defaults:{autoHeight:true, bodyStyle:'padding:10px'}, 
                  title:'Previous Schooling',
                  items :[{
                      title: i18n.School + ' 1',
                      layout:'form',
                      defaults: {width: 250},
                      items: [{
                      xtype: 'textfield',
                      fieldLabel: i18n.School_Name,
                      allowBlank:false,
                      //width: 250,
                      name: 'nos1',
                      msgTarget: 'side',
                      maskRe: /([a-zA-Z0-9\s]+)$/
                  },{
                      xtype:'fieldset',
                      title: i18n.Language_Medium + '3 '.sup(),
                      collapsible: false,
                      width: 400,
                      autoHeight:true,
                      labelWidth: 50,
                      items :[{
                      xtype: 'radiogroup',
                      fieldLabel: i18n.Tibetan,
                      name: 'Tibetan1',
                      labelWidth: 100,
                      columns: [110, 60, 70, 50],
                      rows: 1,
                      itemCls: 'x-check-group-alt',
                      width: 300,
                      //defaults: {width: 200},
                      allowBlank:false,
                      msgTarget: 'side',
                      //vertical: true,
                     // cls: 'languages',
                      items: [
                              {boxLabel: i18n.Mother_Tongue, name: 'tibetan1', inputValue: i18n.Mother_Tongue},
                              {boxLabel: i18n.Fluent, name: 'tibetan1', inputValue: i18n.Fluent},
                              {boxLabel: i18n.Scholar, name: 'tibetan1', inputValue: i18n.Scholar},
                              {boxLabel: i18n.None, name: 'tibetan1', inputValue: i18n.None}
                              ]
                  },{
                      xtype: 'radiogroup',
                      fieldLabel: i18n.Chinese,
                      name: 'Chinese1',
                      columns: [110, 60, 70, 50],
                      rows: 1,
                      width: 300,
                      itemCls: 'x-check-group-alt',
                      allowBlank:false,
                      msgTarget: 'side',
                      items: [
                              {boxLabel: i18n.Mother_Tongue, name: 'chinese1', inputValue: i18n.Mother_Tongue},
                              {boxLabel: i18n.Fluent, name: 'chinese1', inputValue: i18n.Fluent},
                              {boxLabel: i18n.Scholar, name: 'chinese1', inputValue: i18n.Scholar},
                              {boxLabel: i18n.None, name: 'chinese1', inputValue: i18n.None}
                              ]
                  },{
                      xtype: 'radiogroup',
                      fieldLabel: i18n.English,
                      name: 'English1',
                      width: 300,
                      columns: [110, 60, 70, 50],
                      rows: 1,
                      itemCls: 'x-check-group-alt',
                      allowBlank:false,
                      msgTarget: 'side',
                      items: [
                              {boxLabel: i18n.Mother_Tongue, name: 'english1', inputValue: i18n.Mother_Tongue},
                              {boxLabel: i18n.Fluent, name: 'english1', inputValue: i18n.Fluent},
                              {boxLabel: i18n.Scholar, name: 'english1', inputValue: i18n.Scholar},
                              {boxLabel: i18n.None, name: 'english1', inputValue: i18n.None}
                              ]
                  },{
  
                      xtype: 'textfield',
                      fieldLabel: i18n.Other,
                      width: 250,
                      emptyText: i18n.Type_Lang,
                      itemCls: 'x-check-group-alt',
                      name: 'other1text',
                      id: 'other1text',
                      maskRe: /([a-zA-Z\s]+)$/
                  },{
                      xtype: 'radiogroup',
                      name: 'Other1',
                      columns: [110, 60, 70, 50],
                      rows: 1,
                      width: 300,
                      itemCls: 'x-check-group-alt',
                      msgTarget: 'side',
                      items: [
                              {boxLabel: i18n.Mother_Tongue, name: 'other1', inputValue: i18n.Mother_Tongue},
                              {boxLabel: i18n.Fluent, name: 'other1', inputValue: i18n.Fluent},
                              {boxLabel: i18n.Scholar, name: 'other1', inputValue: i18n.Scholar},
                              {boxLabel: i18n.None, name: 'other1', inputValue: i18n.None}
                              ]
                  }]},{
                      xtype: 'datefield',
                      fieldLabel: i18n.Enrollment_Start,
                      allowBlank:false,
                      msgTarget: 'side',
                      name: 'enrollStart1',
                      id: 'enrollStart1',
                      vtype: 'daterange',
                      //width: 250,
                      endDateField: 'enrollEnd1'
                   // minValue: '02/24/1950'
                  },{
                      xtype: 'datefield',
                      fieldLabel: i18n.Enrollment_End,
                      allowBlank:false,
                      msgTarget: 'side',
                      name: 'enrollEnd1',
                      id: 'enrollEnd1',
                      vtype: 'daterange',
                     // width: 250,
                      startDateField: 'enrollStart1'
                  },{
                      xtype: 'textfield',
                      fieldLabel: i18n.Degree,
                      allowBlank:false,
                      name: 'degree1',
                      msgTarget: 'side',
                      //width: 250,
                      maskRe: /([a-zA-Z0-9\s]+)$/
                  }]},{
                  title: i18n.School + ' 2',
                  layout:'form',
                  defaults: {width: 250},
                  items: [{
                      xtype: 'textfield',
                      fieldLabel: i18n.School_Name,
                     // allowBlank:false,
                      name: 'nos2',
                      msgTarget: 'side',
                      maskRe: /([a-zA-Z0-9\s]+)$/
                  },{
  
  ...
  ...
  ...
  
   buttons: [{
              text: i18n.Submit,
              handler: function(){
  
                      form.getForm().submit({
                          params:{lang: lang},
                          success: function(form, action) {
                                 Ext.Msg.alert(i18n.Success, action.result.msg);
                          },
                          failure: function(form, action) {
                              switch (action.failureType) {
                                  case Ext.form.Action.CLIENT_INVALID:
                                      Ext.Msg.alert(i18n.Failure, i18n.Client_Error);
                                      break;
                                  case Ext.form.Action.CONNECT_FAILURE:
                                      Ext.Msg.alert(i18n.Failure, i18n.Ajax_Error);
                                      break;
                                  case Ext.form.Action.SERVER_INVALID:
                                      Ext.Msg.alert(i18n.Failure, action.result.msg);
                                  }//end switch
                          }
  
                      });
              }
          },{
              text: i18n.Reset,
              handler: function(){
                  form.getForm().reset();
              }
          }]
      });
  
          form.render(document.body);
  
      }); //End Ext.onReady
  });//End $.getJSON
  });//End $.getScript
  </code></pre>