2013-04-23 41 views
2

我有一個字符串是從selectonemenu設置的。菜單中的值取決於另一個菜單中的選擇,並使用JavaScript填充。前端的一切行爲都很好(菜單正確更新等),但是當我們提交更改時,字符串沒有被設置。該菜單有一個轉換器,並且正在調用getAsObject。有人知道爲什麼字符串沒有被設置?使用由JS填充的selectOneMenu在JSF和Seam中設置字符串

Edit.jspx

<h:selectOneMenu value="#{detectorInstance.type}" converter="detectorConverter" onchange="updateSubTypes(this, '#{applicationName}')"> 
    <s:selectItems value="#{detectors.detectors}" var="detectorSelection" label="#{detectorSelection.name}" noSelectionLabel="Unknown"/> 
</h:selectOneMenu>  
<a4j:outputPanel id="detectorSubType"> 
    <h:selectOneMenu value="#{detectorInstance.detectorSubType}" converter="detectorSubTypeConverter"/> 
</a4j:outputPanel>  

DetectorSubTypeConverter.java

@Name("detectorSubTypeConverter") 
@BypassInterceptors 
@org.jboss.seam.annotations.faces.Converter 
public class DetectorSubTypeConverter implements Converter { 
    public Object getAsObject(final FacesContext facesContext, final UIComponent uiComponent, final String identifier) { 
     return identifier; 
    } 

    public String getAsString(final FacesContext facesContext, final UIComponent uiComponent, final Object o) { 
     return o.toString(); 
    } 
} 

detectors.js

function updateSubTypes(typeSelect, appName) { 
    var jsonRoot = appName + "/services/rest/detectors/detectors"; 

    jQuery.getJSON(jsonRoot, function(data) { 
     var subTypes = getSubTypes(typeSelect, data); 
     var subTypeSelect = typeSelect.next().firstChild; 
     subTypeSelect.options.length = 0; 
     for (var i = 0; i < subTypes.length; i++) { 
      subTypeSelect.options[i] = new Option(subTypes[i], subTypes[i], false, false); 
     } 
    }); 
} 

function getSubTypes(typeSelect, detectors) { 
    var selection = typeSelect.options[typeSelect.selectedIndex].text; 
    var subtypes = new Array(); 
    for (var i = 0; i < detectors.length; i++) { 
     var uuid = detectors[i]['detector']['name']; 
     if (selection == uuid) { 
      for (var j = 0; j < detectors[i]['detector']['subtypes'].length; j++) { 
       subtypes[j] = detectors[i]['detector']['subtypes'][j]['name']; 
      } 
     } 
    } 

    return subtypes; 
} 
+0

在你的第二selectOneMenu我看到一個值,但沒有列表 - 是故意的?你如何提交更改? – gebuh 2013-04-24 02:21:48

+0

是 - 空列表是故意的。 js調用根據類型列表中的選擇填充它。我對jsf/seam非常陌生,所以我不太確定提交更改需要什麼,我認爲這是用「Value」屬性處理的。 – 2013-04-24 14:53:36

+0

selectOneMenu是否需要selectItems?如果是,是否它必須包含要提交的值? – 2013-04-24 15:11:42

回答

0

我不認爲通過JS填充物品selectOneMenu用於是正道與Seam/JSF合作。原因是,當你顯示一個包含項目列表的下拉菜單時,Seam/JSF會檢查提交的值是否出於安全原因列在列表中。

正確的做法應該是:

  • 處理第一個下拉的onchange事件,並重新計算第二個下拉的項目上服務器
  • 然後重新呈現第二個下拉

的想法是如下所示:

<h:selectOneMenu value="#{detectorInstance.type}" converter="detectorConverter" onchange="updateSubTypes(this, '#{applicationName}')"> 
    <s:selectItems value="#{detectors.detectors}" var="detectorSelection" label="#{detectorSelection.name}" noSelectionLabel="Unknown"/> 
    <a4j:ajax event="click" execute="@this" render="detectorSubType" 
     listener="#{detectorInstance.onTypeChange}"/> 
</h:selectOneMenu> 
<a4j:outputPanel id="detectorSubType"> 
    <h:selectOneMenu value="#{detectorInstance.detectorSubType}" converter="detectorSubTypeConverter"> 
     <f:selectItem value="#{detectorInstance.types}" /> 
    </h:selectOneMenu> 
</a4j:outputPanel> 

第二個下拉列表的項目是f rom detectorInstance.types。在detectorInstance.onTypeChange,你重新計算detectorInstance.types,然後重新提交render="detectorSubType"

+0

我認爲這是正確的,但我們實際上試圖擺脫這種方法來避免ajax調用。 – 2014-04-17 13:55:47