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

如何实现与JSF commandButton功能相同的纯前端JS按钮?

Absolutely! You can replicate the exact functionality of that JSF <p:commandButton> with a pure JavaScript button—no REST interface required. Here's how it works and how to build it:

How the Original JSF Button Works

First, let's break down what your original button does:

  • With ajax="false", it triggers a synchronous POST form submission to the current JSF page.
  • The JSF framework recognizes the action #{reporting.downloadPaymentsReport}, runs that backend method, and sends back a download response (with headers like Content-Disposition to prompt the browser to save the file).

Pure JS can mimic this exact flow by manually creating/submitting a form with all the parameters JSF expects.

Implementation Options

Option 1: Use an Existing JSF Form

If your page already has a JSF <h:form> (most JSF pages do), you can reuse it to trigger the download:

  1. Add a plain HTML button to your page:
<button onclick="downloadPaymentsReport()">Скачать</button>
  1. Add this JavaScript function:
function downloadPaymentsReport() {
  // Grab your existing JSF form (replace "reportForm" with your form's actual ID)
  const form = document.getElementById('reportForm');
  
  // Add hidden inputs to tell JSF to execute the download action
  const actionParams = [
    { name: 'javax.faces.source', value: 'downloadBtn' },
    { name: 'javax.faces.partial.execute', value: '@all' },
    { name: 'javax.faces.event', value: 'action' },
    // Explicitly specify the action method (adjust the name to match your bean's setup)
    { name: 'javax.faces.action', value: '#{reporting.downloadPaymentsReport}' }
  ];

  // Append each parameter to the form
  actionParams.forEach(param => {
    const input = document.createElement('input');
    input.type = 'hidden';
    input.name = param.name;
    input.value = param.value;
    form.appendChild(input);
  });

  // Submit the form (this triggers the backend action)
  form.submit();

  // Clean up the temporary inputs after submission
  setTimeout(() => {
    actionParams.forEach(param => {
      const input = form.querySelector(`input[name="${param.name}"]`);
      if (input) form.removeChild(input);
    });
  }, 100);
}

Option 2: Create a Temporary Form (No Existing Form Needed)

If you don't have an existing JSF form, you can dynamically create one with JS:

function downloadPaymentsReport() {
  // Create a hidden temporary form
  const form = document.createElement('form');
  form.method = 'POST';
  form.action = window.location.pathname; // Submit to the current JSF page
  form.style.display = 'none';

  // Get the JSF ViewState (critical for JSF to process the request)
  const viewState = document.querySelector('input[name="javax.faces.ViewState"]');
  if (!viewState) {
    alert('Could not find JSF ViewState. Ensure this page is a valid JSF page.');
    return;
  }

  // Build all required parameters
  const formInputs = [
    { name: 'javax.faces.ViewState', value: viewState.value },
    { name: 'javax.faces.source', value: 'downloadBtn' },
    { name: 'javax.faces.partial.execute', value: '@all' },
    { name: 'javax.faces.event', value: 'action' },
    { name: 'javax.faces.action', value: '#{reporting.downloadPaymentsReport}' }
  ];

  // Add all inputs to the form
  formInputs.forEach(inputData => {
    const input = document.createElement('input');
    input.type = 'hidden';
    input.name = inputData.name;
    input.value = inputData.value;
    form.appendChild(input);
  });

  // Add the form to the page and submit it
  document.body.appendChild(form);
  form.submit();

  // Remove the temporary form after submission
  setTimeout(() => document.body.removeChild(form), 100);
}

Then add the same HTML button as in Option 1.

Key Notes

  • ViewState is Mandatory: JSF requires the javax.faces.ViewState parameter to validate the request—don't skip this, or your backend will throw an error.
  • Match Existing Parameters: If your original JSF button relied on other form inputs (like date ranges or filters), make sure those inputs are included in the form you submit (either by reusing an existing form or adding hidden inputs for their values).
  • JSF Version Compatibility: The parameter names (javax.faces.source, etc.) work for most modern JSF versions (2.x+). If you're on an older version, you might need to adjust the parameter names slightly, but the core idea remains the same.

This approach will behave exactly like your original JSF button: it triggers the backend downloadPaymentsReport method, and the browser will handle the download response just as before.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:14:08