2016-03-08 63 views
0

我試圖做一個「警告字段驗證程序」,其行爲與常規字段驗證程序類似,但不會使表單失效,只是在字段旁邊顯示帶有工具提示的警告圖標。如何在ExtJS6中創建警告表單字段驗證器?

我應該重寫哪些方法?我可能只是用一個字段旁邊的圖標打一個div,但是這樣做會乾淨利落,所以使用它作爲一個常規驗證器很方便?

+0

這是一個有點豬在一個穩健的方式重寫 - 你會得到更好的創建與驗證區分提交和驗證顯示(可以查找實際的目標字段的方法自定義表單他們關心手動)。 – Emissary

回答

2

我們可以通過覆蓋Ext.form.field.Base的validateValue來實現。

Ext.define('MyApp.overrides.form.field.Base', { 
    override: 'Ext.form.field.Base', 

    validateValue: function(value) { 
     // let validations run as usual. 
     var isValid = this.callParent(arguments); 

     // warnings related code begin here 
     // once the field is valid, then we check for warnings 
     if(isValid) { 
      var warnings = me.getWarnings(), 
       hasWarnings = Ext.isEmpty(warnings); 
      if(hasWarnings) { 
       me.showWarnings(warnings); 
      } 
      else { 
       me.clearWarnings(); 
      } 
     } 

     return isValid; 
    }, 

    getWarnings: function(value) { 
     // do all validations related to warnings. 
     // infact we can use the existing vtypes for doing this. 
     // i just altered this to support two types of configurations 
     // wtype or warnator (Function to Warnate) 

     value = arguments.length ? (value == null ? '' : value) : this.processRawValue(this.getRawValue()); 

     var me = this, 
      warnings = [], 
      warnator = me.warnator, // yeah sounds funnny right :D 
      wtype = me.wtype, 
      vtypes = Ext.form.field.VTypes 

     if (Ext.isFunction(warnator)) { 
      msg = warnator.call(me, value); 
      if (msg !== true) { 
       warnings.push(msg); 
      } 
     } 

     if (wtype) { 
      if (!vtypes[wtype](value, me)) { 
       warnings.push(me.wtypeText || vtypes[wtype +'Text']); 
      } 
     } 

     return warnings; 
    }, 

    showWarnings: functions(warnings) { 
     // show the warnings (similar to markInvalid function) 
     this.setActiveWarnings(Ext.Array.from(warnings)); 
    }, 

    clearWarnings: function() { 
     // clear the warnings (similar to clearInvalid function) 
     this.unsetActiveWarning(); 
    } 
} 

並覆蓋Labelable以顯示警告。

Ext.define('MyApp.overrides.form.Labelable', { 
    override: 'Ext.form.Labelable', 

    setActiveWarnings: function(warnings) { 
     // similar to setActiveErrors 
    }, 

    unsetActiveWarning: function() { 
     // similar to unsetActiveError 
    } 
}); 

還有其他的一些usecases的需要像啓用和字段的禁用要處理,你可能需要重寫onEnable和禁止接通根據您的需要。

更新

這裏是顯示警告小提琴。 驗證:姓氏爲必填項。 警告:姓氏必須包含至少3個字符。

https://fiddle.sencha.com/#fiddle/17da

0

我將延長Ext.form.Basic這樣的:

Ext.define('MyApp.form.Basic',{ 
    extend:'Ext.form.Basic', 
    isValid: function() { 
     var me = this, 
      invalid; 
     Ext.suspendLayouts(); 
     invalid = me.getFields().filterBy(function(field) { 
      return !field.validate() && !field.mayBeInvalid; 
     }); 
     Ext.resumeLayouts(true); 
     return invalid.length < 1; 
    } 
}); 
Ext.define('MyApp.form.Panel',{ 
    extend:'Ext.form.Panel', 
    xtype:'myformpanel', 
    createForm: function() { 
     var cfg = {}, 
      props = this.basicFormConfigs, 
      len = props.length, 
      i = 0, 
      prop; 

     for (; i < len; ++i) { 
      prop = props[i]; 
      cfg[prop] = this[prop]; 
     } 
     return new MyApp.form.Basic(this, cfg); 
    } 
}); 

這樣你就可以註釋這樣的字段:

xtype:'myformpanel', 
items:[{ 
    xtype:'textfield', 
    // this field should be validated. 
},{ 
    xtype:'textfield', 
    mayBeInvalid:true // our own extension property 
    // this field should not block the form submission 
}] 

,然後提交如常。

完全未經測試,但你會爲我做的,我猜:)

的選擇,如果你真的只需要它在一個單一的submit()喊單的形式,是手工做同樣的事情提交之前:

var invalidFields = formpanel.getForm().getFields().filterBy(function(field) { 
    return !field.validate() && !field.mayBeInvalid; 
}); 
if(invalidFields.length < 1) form.submit({ 
    clientValidation: false, // do not validate anymore 
    ... 
}) 
+0

對不起,我認爲這不是我所追求的。你只是想跳過「mayBeInvalid」字段失效?我並不試圖跳過驗證,我試圖添加另一個「軟」驗證,它只顯示帶有消息的警告圖標而不會使域失效。因此,如果必填字段爲空,它仍應使其無效,但如果字段值允許在10以下說,它應該仍然有效並可提交,但在字段旁邊有一個警告圖標(而不是紅色感嘆號)。 – serg

1

亞歷山大給出了一個很好的例子來實現這一點。根據你的答案我犯了一個撥弄着一些基本的東西,你怎麼能直接實現某種柔軟的警告到文本框:https://fiddle.sencha.com/#fiddle/16rk

Ext.define('Ext.form.field.MyText', { 
    extend:'Ext.form.field.Text', 
    listeners: { 
     blur: function() { 
      if (this.softWarning && this.softWarning == true) { 
       this.softValidate(); 
      } 
     } 
    }, 
    softValidate: function() { 
     var el = this.inputEl; 
     if (el) { 
      if (this.getValue().length < 5) { 
       el.dom.style.backgroundColor = 'red'; 
       el.dom.style.color = 'white'; 
      } else { 
       el.dom.style.backgroundColor = ''; 
       el.dom.style.color = ''; 
      } 
     } 

    } 
}); 

要知道,這是一種可能的方式。我會建議你的需求結合兩個答案。

+0

謝謝,但這幾乎是我試圖避免的全手動解決方案 - 手動檢查每個字段的一些條件,並手動操縱dom並在其中注入某些東西。我試圖在現有的validatior功能的基礎上進行構建,並且對字段上的「validator」屬性具有類似的行爲 - 提供一個函數,在觸發錯誤工具提示旁邊會觸發警告工具提示。 – serg

+0

沒有最好的方法來模擬構建工具中的「驗證器」行爲。你總是必須重寫/擴展表單/字段來實現這一點。最好的方法是定義某種行爲並使用偵聽器來觸發自定義驗證。 – Tyr

+0

我明白了,所以我想知道我需要重寫什麼驗證器/表單/字段方法才能保持儘可能多的現有驗證器功能。重寫字段模糊只是手動執行所有操作,而不用重複使用任何內容。我想保留99%的現有驗證器功能,而不是從頭開始手動重新創建它。 – serg