You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PrimeFaces中用jQuery获取AccordionPanel折叠面板激活标签ID及自动保存

Hey there! Let's tackle your problem step by step. First, we'll fix the issue of getting the correct AccordionPanel tab and hidden field when an input changes, then we'll go over solid auto-save solutions for PrimeFaces.

Fixing the Field Change Detection & Hidden Field Update

Your current jQuery code targets #reviewHidden directly, which won't work well if you have multiple tabs (it'll update all matching hidden fields). Instead, we need to traverse the DOM from the changed input to find its parent tab and corresponding hidden field.

Modified XHTML (keeping your core structure)

<p:accordionPanel id="FacilityAccordId" activeIndex="null" dynamic="true">
    <p:ajax event="tabChange" listener="#{facilities.saveClicked}" />
    <p:tab id="priortabId" title="Prior Sanction/Review Info">
        <p:panel id="priorPanelId" header="Prior Sanction/Review Info">
            <h:inputHidden id="reviewHidden" value="#{facilities.hiddenReview}" />
            <p:inputText value="#{facilities.sanctAuth}" styleClass="textbox" id="psrSanctAID" />
            <label><h:outputText value="Sanction Authority" /></label>
        </p:panel>
    </p:tab>
    <!-- Add more tabs with their own hidden fields here if needed -->
</p:accordionPanel>

Updated jQuery Code

$(document).ready(function() {
    // Listen only for input changes inside your target AccordionPanel
    jQuery(document.body).on('change', '#FacilityAccordId input', function(event) {
        const $changedInput = $(this);
        
        // Find the parent tab panel (PrimeFaces renders p:tab as a div with class ui-tabs-panel)
        const $tabPanel = $changedInput.closest('div.ui-tabs-panel');
        
        // Get the ID of the parent AccordionPanel
        const accordionId = $tabPanel.closest('div.ui-accordion').attr('id');
        console.log('Changed input belongs to AccordionPanel:', accordionId);
        
        // Find the matching hidden field inside this specific tab (works even with PrimeFaces' prefixed IDs)
        const $hiddenField = $tabPanel.find('[id$="reviewHidden"]');
        // Update the hidden field to mark changes
        $hiddenField.val('true');
        
        // Optional: Trigger an immediate save via remote command if needed
        // saveTabChanges([{name: 'tabId', value: $tabPanel.attr('id')}]);
    });
});

Key Details:

  • We limit the listener to inputs only inside your AccordionPanel to avoid unrelated input triggers.
  • closest('div.ui-tabs-panel') targets the exact tab containing the changed input (PrimeFaces uses this class for rendered tabs).
  • [id$="reviewHidden"] uses a jQuery ends-with selector to handle PrimeFaces' auto-generated prefixed IDs (like formId:FacilityAccordId:priortabId:priorPanelId:reviewHidden).
  • We grab the parent AccordionPanel ID by traversing up to the ui-accordion container (the rendered version of your p:accordionPanel).

PrimeFaces Auto-Save Feasible Solutions

Instead of manually updating hidden fields, here are cleaner, more PrimeFaces-native ways to implement auto-save:

1. Use p:ajax Directly on Inputs

Attach p:ajax to each input to trigger a backend save immediately when the value changes:

<p:inputText value="#{facilities.sanctAuth}" styleClass="textbox" id="psrSanctAID">
    <p:ajax event="change" listener="#{facilities.saveField}" update=":messages" />
</p:inputText>

In your managed bean:

public void saveField(AjaxBehaviorEvent event) {
    // Get the component that triggered the change
    UIComponent component = event.getComponent();
    // Traverse the component hierarchy to get the parent tab/accordion ID if needed
    String tabId = component.getParent().getParent().getId();
    // Save the updated field value to your database/session
    // ...
}

2. Periodic Auto-Save with p:remoteCommand

Set up a timed interval to auto-save all changes periodically (e.g., every 30 seconds):

<p:remoteCommand name="autoSave" action="#{facilities.saveAllChanges}" update=":messages" />

<script>
    // Auto-save every 30 seconds
    setInterval(function() {
        autoSave();
    }, 30000);
</script>

In your bean:

public void saveAllChanges() {
    // Save all modified fields from the AccordionPanel
    // ...
}

Combine this with a isDirty flag in your bean to only trigger saves when actual changes exist.

3. Tab Change Triggered Save

Leverage your existing tabChange listener to save changes when the user switches tabs:

  1. Add a isDirty flag for each tab in your managed bean.
  2. On input change, use the jQuery code above to call a remote command that marks the current tab as isDirty.
  3. In the tabChange listener, check if the previous tab was dirty, save its changes, then reset the flag.

内容的提问来源于stack exchange,提问作者Nishant Varshney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:17:57