2014-04-11 130 views
0

我有一個JSF應用程序,其中有一個像這樣的組合框。JSF onchange事件

<script type="text/javascript" defer="defer"> 
    <!--//--><![CDATA[//><!-- 
    helpKey = 'APPLICATION_EDIT_DATASOURCE'; 

    function reapplyStyles() {} 

    function selectT(data){ 
     if(data.status == "begin"){ 
      $('editForm:selectTypeButton').click();  
     } 
    } 

    //--><!]]> 
</script> 

    <h:form id="editForm"> 
    <h:inputHidden id="id" value="#{applicationObject.objectId}"/> 
    <h:inputHidden id="type" value="#{applicationObject.object.type}"/> 
    <h:inputHidden id="selectedDSForApp" value="#{applicationObject.selectedDataSourceId}"/> 
    <ui:param name="activityDataSource" value="#{applicationObject.selectedDataSourceBean}"/> 

    <a4j:outputPanel id="activityDataSourceRulesPanel"> 
    <h:panelGrid columns="2" columnClasses="padded" rowClasses="padded"> 

     <h:outputText value="#{msgs.transformation_rule}"/> 
     <h:panelGroup> 
      <h:selectOneMenu id="dsTransformationRule" value="#{activityDataSource.selectedTransformationRule}" 
          disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}" 
          readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}"> 
      <f:selectItems value="#{activityDataSource.transformationRules}"/> 
      </h:selectOneMenu> 
      <ui:fragment rendered="#{sp:hasRight(facesContext, 'ManageRules')}" > 
       <input type="button" value="#{msgs.button_ellipsis}" class="ruleEditorBtn" 
        onclick="SailPoint.Rule.Editor.edit($('editForm:dsTransformationRule').value, 
          'ActivityTransformer', 
          $('editForm:refreshActivityDataSourceRulesButton'))" /> 
      </ui:fragment> 
     </h:panelGroup> 

     <h:outputText value="#{msgs.correlation_rule}"/> 
     <h:panelGroup> 
      <h:selectOneMenu id="dsCorrelationRule" value="#{activityDataSource.selectedCorrelationRule}" 
          disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}" 
          readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}"> 
      <f:selectItems value="#{activityDataSource.correlationRules}"/> 
      </h:selectOneMenu> 
      <ui:fragment rendered="#{sp:hasRight(facesContext, 'ManageRules')}" > 
       <input type="button" value="#{msgs.button_ellipsis}" class="ruleEditorBtn" 
        onclick="SailPoint.Rule.Editor.edit($('editForm:dsCorrelationRule').value, 
          'ActivityCorrelation', 
          $('editForm:refreshActivityDataSourceRulesButton'))" /> 
      </ui:fragment> 
     </h:panelGroup> 

     <h:outputText value="#{msgs.activity_data_src_type}"/> 
     <h:panelGroup> 
     <a4j:outputPanel id="collectorSettings"> 
      <h:selectOneMenu id="collectorType" 
          value="#{activityDataSource.object.type}" 
          rendered="#{empty activityDataSource.object.id}" 
          disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}" 
          readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}"> 
          <!-- onchange="$('editForm:selectTypeButton').click();"> --> 
      <f:ajax event="change" 
        onevent="selectT" 
        execute="@this dsTransformationRule dsCorrelationRule" 
        render="dsTransformationRule dsCorrelationRule" 
        listener="#{activityDataSource.handleCollectorTypeChange}" /> 
      <f:selectItem itemValue="" itemLabel="#{msgs.select_collector_type}"/> 
      <f:selectItems value="#{activityDataSource.collectorTypes}"/> 
      </h:selectOneMenu> 
      <h:selectOneMenu id="fixedCollectorType" value="#{empty activityDataSource.object.type ? 'None' : activityDataSource.object.type}" 
          rendered="#{not empty activityDataSource.object.id}" 
          disabled="true" 
          readonly="true"> 
      <f:selectItem itemValue="#{empty activityDataSource.object.type ? 'None' : activityDataSource.object.type}" 
          itemLabel="#{empty activityDataSource.object.type ? msgs.none : activityDataSource.object.type}"/> 
      </h:selectOneMenu> 
     </a4j:outputPanel> 
     </h:panelGroup> 
    </h:panelGrid> 
    </a4j:outputPanel> 

    <a4j:outputPanel id="configSettings"> 
     <h:messages infoClass="formInfo" warnClass="formWarn" errorClass="formError" fatalClass="formError"/> 

     <h:panelGroup rendered="#{not empty activityDataSource.object.collector}"> 
     <ui:include src="#{activityDataSource.configPage}"/> 
     </h:panelGroup> 
    </a4j:outputPanel> 
    <h:panelGroup> 
     <div class="buttonRow"> 
     <ui:fragment rendered="#{sp:hasRight(facesContext, 'ManageApplication')}"> 
      <h:commandButton id="activityDataSourceSave" action="#{activityDataSource.saveAction}" value="#{msgs.button_save}" styleClass="primaryBtn"/> 
     </ui:fragment> 
     <h:commandButton id="activityDataSourceCancel" action="#{activityDataSource.cancelAction}" value="#{msgs.button_cancel}" styleClass="secondaryBtn"/> 
     </div> 
    </h:panelGroup> 

    <a4j:commandButton id="refreshActivityDataSourceRulesButton" 
         style="display:none" 
         immediate="true" 
         render="activityDataSourceRulesPanel"/> 

    <a4j:commandButton id="selectTypeButton" action="#{activityDataSource.selectType}" style="display:none" 
         render="configSettings, collectorSettings" 
         oncomplete="initializeSelectedConfigPage();"/> 

    </h:form> 

Bean類

public String getSelectedTransformationRule() { 
    if (_selectedTransformationRule == null) { 
     ActivityDataSourceDTO dto = getObject(); 
     if (dto != null) 
      _selectedTransformationRule = dto.getTransformationRule(); 
    } 

    return _selectedTransformationRule; 
} 
public String getSelectedCorrelationRule() { 
    if (_selectedCorrelationRule == null) { 
     ActivityDataSourceDTO dto = getObject(); 
     if (dto != null) 
      _selectedCorrelationRule = dto.getCorrelationRule(); 
    } 

    return _selectedCorrelationRule; 
} 

在上面的代碼中,我有一個正常的onchange事件&一個Ajax平變化上組合框元素的id = collectorType事件。

對JSF中的相同元素使用兩個更改是否有任何限制。

另外我怎樣才能合併第一次onchange到ajax onchange。

回答

2

使用onevent<f:ajax>屬性如下:

<h:selectOneMenu id="collectorType" 
        value="#{activityDataSource.object.type}" 
        rendered="#{empty activityDataSource.object.id}" 
        disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}" 
        readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}"> 
    <f:ajax event="change" 
      execute="@this" 
      render="dsTransformationRule dsCorrelationRule" 
      listener="#{activityDataSource.handleCollectorTypeChange}" 
      onevent="$('#editForm\\:selectTypeButton').click();"/> 
    <f:selectItem itemValue="" itemLabel="#{msgs.select_collector_type}"/> 
    <f:selectItems value="#{activityDataSource.collectorTypes}"/> 
</h:selectOneMenu> 

還會注意到我已經修改了選擇'#editForm\\:selectTypeButton'逃脫你的按鈕的id的:

[更新]

這裏是你可以做,以實現我們在評論中討論的方案是什麼:

首先來填充這兩個dsTransformationRuledsCorrelationRule_selectedTransformationRule_selectedCorrelationRule分別創建一個初始化方法他們,並把它在@PostConstruct方法(check Why use @PostConstruct?),所以在你的bean類你會有這樣的事情:

@PostConstuct 
public void init() { 
    initRules(); 
    //include another things you want to be initializaed when this page finishes constructing. 
} 

private void initRules() { 
    ActivityDataSourceDTO dto = getObject(); 
    if (dto == null) 
     return; 

    if (_selectedTransformationRule == null) 
     _selectedTransformationRule = dto.getTransformationRule(); 

    if (_selectedCorrelationRule == null) 
     _selectedCorrelationRule = dto.getCorrelationRule(); 
} 

//Let the getters do no dto access, so it won't matter if they're called twice on change 
public String getSelectedTransformationRule() { 
    return _selectedTransformationRule; 
} 

public String getSelectedCorrelationRule() { 
    return _selectedCorrelationRule; 
} 

現在你f:ajax可以正常executerender您的選擇菜單,無需擔心多次

<f:ajax event="change" onevent="selectT" 
     execute="@this dsTransformationRule dsCorrelationRule" 
     render="dsTransformationRule dsCorrelationRule" 
     listener="#{activityDataSource.handleCollectorTypeChange}" /> 

這樣,當調用handleCollectorTypeChange訪問您的DTO層,將同時擁有_selectedTransformationRule_selectedCorrelationRule他們最後選擇的值填充。

在一個側面說明,如果你想經由在Update Model Values階段之前調用事件偵聽器的方法得到驗證或轉換階段,選擇菜單dsTransformationRuledsCorrelationRule的值,或直接,檢查this answer這將幫助你達到組件的價值。

希望這能解決您的問題,或者至少讓您朝正確的方向發展。

+0

其工作。但我注意到,在調試與我想要渲染的元素相關的bean中的該方法時會調用兩次。如何處理這個? –

+0

@CODEFISH到底什麼叫兩次?你的'render'屬性中的元素是什麼? –

+0

我解開了我的問題。 bean類的這兩個方法在change事件上被調用兩次.ajax change事件在元素id = collectorType中。 –