2014-04-11 105 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中。 –