簡體   English   中英

JSF 2.0驗證和字段突出顯示

[英]JSF 2.0 validation and field highlighting

我正在尋找有關在JSF 2.0中添加字段錯誤突出顯示的最佳方法的一些指導/意見。 到目前為止,我已經成功地使用了Cagatay的示例並對邏輯進行了一些小的調整。

String styleClass = ( String ) uiInput.getAttributes().get("styleClass");
        //Check the valid flag
        if ( !uiInput.isValid() )
        {
            //Component already has a styleclass
            if ( styleClass != null )
            {
                //check if it's already highlighted
                if ( !styleClass.contains("ui-input-invalid") )
                {
                    //if not add the error class to it
                    styleClass = styleClass + " ui-input-invalid";
                    //and put the new styleclass back on the component
                    uiInput.getAttributes().put("styleClass", styleClass);
                }
            } else
            {
                //no current style class so just add the error class
                uiInput.getAttributes().put("styleClass", "ui-input-invalid");
            }       
        } else  //component is valid so we might need to remove a highlight
        {
            //component has a styleclass
            if ( styleClass != null )
            {
                //check if it is already highlighted
                if ( styleClass.contains("ui-input-invalid") )
                {
                    //remove error class from the string
                    styleClass = styleClass.replace("ui-input-invalid", "");
                    //and put the new styleclass back on the component
                    uiInput.getAttributes().put("styleClass", styleClass);
                }
            }    
        }

我還建議將el添加到每個組件的樣式類中-styleClass styleClass="#{component.valid ? '' : 'ui-input-invalid'}"
與Bean驗證JSR303結合使用時,這兩種方法都像一個超級工具。 但是,我還有兩個附加的驗證階段。 1驗證整個表單,即字段的正確組合; 1驗證字段和表單成功后驗證我們的一般業務規則。 為了使這些階段也添加突出顯示,我需要做一些手工工作。 對於這兩種突出顯示方法,我都必須手動將組件的有效標志設置為false。 要訪問該組件,我已將其綁定到其自己的對象,形式為vo。 現在以Cagatay的示例為例,我需要將所有組件添加到列表中,然后將此列表傳遞給突出顯示方法。 如果我使用樣式類方法,則不必擔心組件列表和傳遞給突出顯示方法的問題。 這對我來說似乎是更好的方法,但是我有點擔心它在JSF頁面中添加了邏輯,這是我想遠離的。

您認為最好的方法是什么,或者還有我不知道的另一種方法? 我還假設沒有綁定到組件的其他方法來設置有效標志嗎? 目前,我必須綁定每個組件,以便可以設置其有效標志。

自從我問這個問題已經有一段時間了,與此同時,我們實際上已經將JSF部分實現到了我們的企業應用程序中。 突出顯示的字段的解決方案非常復雜,並且要使其正常工作,可重用和可自定義,它實際上必須緊密地適應包含JSF /輸入值對象,關聯的輸入字段對象和Bean驗證的框架。 因此,在這里絆腳的某人可能無法獲得他們所尋找的答案。 但是,我將包括一部分內部設計文檔,其中描述了該機制。 希望這對其他人有幫助:

突出顯示字段和錯誤消息在JSF中,突出顯示字段是一項非常復雜的任務。 這是因為html id / name是由jsf在運行時生成的,並且可以包含許多前綴。 當JSF位於form / tab / datatable / composite組件內時,它將在id前面添加前綴。 ucn的ID可能最終變為tab1:contentForm:jsfDataTable:1:ucn。 因此,幾乎不可能嘗試預先確定ID是什么,然后再嘗試突出顯示。 要解決此問題,請使用preRenderComponentEventListener類。 這與輸入類型一起注冊在facesConfig.xml中。 這告訴JSF生命周期只要將要呈現該類型的輸入就運行此類。 然后,我們可以訪問輸入的短ID和長ID,然后可以保存它們並在以后查找。 完整過程如下:

  1. facesConfig.xml中的條目會注冊一個preRenderComponentEventListener和關聯的輸入類型。 每次在呈現輸入之前,都會調用processEvent方法。
  2. facesConfig.xml中的條目注冊了一個名為componentMap的HashMap,該哈希表用於存儲輸入的ID。
  3. 調用processEvent方法時,將檢索Input元素。 檢索componentMap並將輸入的ID / clientID添加到地圖。 輸入的ID是Key(這是短ID,即ucn),而ClientID是值(這是JSF生成的長ID,即csn01Form:jsf454:ucn:1)。 為了處理多個相同名稱的輸入(如在DataTables中),該鍵將添加一個遞增索引。 例如,如果地圖中已經存在ucn3,那么我們將添加。
  4. 完成此過程后,componentMap將包含每個輸入字段的條目。 因此,通過使用短ID,可以檢索完整的clientID。
  5. 在BackingBean中,捕獲並處理了FormatValidationExceptions和RuleException。
  6. FormatValidationExceptions。 這些來自BeanValidation。 創建InputVO的子類,其中包含Destin8Input的子類(請參見CSN01InputVO)。 如果需要在Input上進行格式驗證,則應使用自定義bean驗證進行注釋。 例如@StringCheck(請參閱Bean驗證)。
  7. FormatValidation類具有一個稱為validateFormats的方法,該方法采用一種InputVO類型,並通過Bean驗證程序運行它(使用事務控制器時,該方法將自動運行)。 Bean驗證器將自動獲取每個帶注釋的字段,並運行與注釋關聯的isValid()方法。 例如,@ StringCheck檢查輸入的值是否與正則表達式匹配以及輸入的字符數是否正確。 任何失敗都將導致ConstraintViolation。 此時,將使用Destin8Input的錯誤顯示名稱生成錯誤消息。 所有驗證檢查均已執行,將導致一組ConstraintViolations。
  8. 在validateFormats方法中,一組ConstraintViolations循環,並將每條消息添加到ValidationFormatException中的錯誤消息列表。 每個錯誤的htmlID也會添加到“字段錯誤列表”中。
  9. ValidationFormatException被捕獲在BackingBean中。 所有錯誤消息都將作為FacesMessage添加,以顯示在頁面頂部。
  10. RuleException類似,除了拋出異常時手動添加要突出顯示的消息和字段。 消息代碼將從數據庫中查找。
  11. 現在,錯誤列表的ID循環了,並用於從componentMap中檢索關聯的完整ClientID。 每個ClientID被添加到一個列表中。
  12. 此列表傳遞到JSFUtils.highlightFields方法,其中每個ClientID都添加到〜分隔字符串中。
  13. 然后使用“錯誤”鍵將此定界的字符串添加到RequestMap(這是根據每個請求自動可用的映射)。
  14. 然后,將該字符串作為Destin8Template.xhtml的一部分進行檢索-
  15. 然后立即調用了一個名為HighlightFields的javascript方法。 這有效地循環了定界的String,獲取了完整的ID,然后使用jQuery添加了Error css類。
  16. 重要的是要注意,Java輸入和JSF輸入之間的鏈接是id。 為了連接2,至關重要的是它們具有相同的ID。 這是通過使用IDConstants類來實現的。 這是一個ENUM,其中包含不同字段的條目。 條目也被添加到IDConstants托管bean中,該條目允許通過facelet進行訪問。 然后將其添加為適用輸入元素的id屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM