Does the allow print option work for webforms, if so how do you download the print from the webform?
Hi thanks, i found out how to enabled it, but does it support allow print as guest? because I had to set it to require login for it to work. I am trying to allow guest user to be able to print after submit.
with the guest user, we didn’t check so …
Hello,
I am also trying to print the form after submit.
Guest User should get option to download pdf of submitted form.
May I know any link or hint how to do it?
As of now I am getting this Submitted Message.
Hello
have you figured out a solution for a guest to print a web form?
BRs
Hi there!
I would also need a way to do this.
Did anyone manage to make a flow which allows public people (not registered users) to either download or print the filled form?
preferably to have the redirected to a custom webpage made in the website Builder and have 2 buttons for print and pdf download.
would this be possible?
Since no one bothers to come with an answer, I will provide you with my fix, just in case someone else will need it:
Project Summary: Print/Download PDF Functionality in Frappe
We created a custom page in Frappe Builder that allows users to print or download the PDF of the latest generated document from a specific Doctype (Cerere Generala Rutiera
), after a Webform submission. Below are the detailed steps, code, and full explanations.
The Goal was to have a simple web page with 2 buttons and allow logged in users to easily either print or download the PDF. Of course, you can choose the default print template from - Webform → Customize → Allow Print and choose the Template from there.
The API will retrieve the latest document the user generated, and replace the name dynamically in an API call (URL link).
1. Page Structure in Builder
The page created in Builder includes:
- Two buttons:
- Print: Opens a print view in a new window.
- Download PDF: Initiates the download of the document as a PDF.
2. JavaScript Script
Complete Script:
The script handles:
- Fetching the latest document name using the backend API.
- Configuring the buttons to generate dynamic links for printing and downloading.
Script:
document.addEventListener('DOMContentLoaded', function() {
console.log('Page loaded, fetching the latest document...');
// Retrieve CSRF token from Frappe
const csrfToken = frappe.csrf_token;
// Fetch API to get the name of the latest document
fetch('/api/method/ghidul_cetateanului.api.get_latest_document_for_user', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Frappe-CSRF-Token': csrfToken, // Add CSRF Token
},
body: JSON.stringify({}) // Empty body, necessary for some POST requests
})
.then(response => response.json())
.then(data => {
if (data.message && data.message.status === "success") {
const docName = data.message.document_name;
console.log("Latest document:", docName);
// Configure Print Button
const printButton = document.getElementById('printButton');
if (printButton) {
printButton.textContent = 'Print'; // Default text
printButton.addEventListener('click', function() {
printButton.textContent = 'Loading...'; // Loading text
printButton.disabled = true; // Disable button
const printUrl = '/printview?doctype=Cerere%20Generala%20Rutiera' +
'&name=' + encodeURIComponent(docName) +
'&format=Cerere%20Rutiera%20Standard' +
'&no_letterhead=1' +
'&trigger_print=1';
console.log('Opening print URL:', printUrl);
window.open(printUrl, '_blank');
printButton.textContent = 'Print'; // Restore text
printButton.disabled = false; // Re-enable button
});
}
// Configure Download Button
const downloadButton = document.getElementById('downloadButton');
if (downloadButton) {
downloadButton.textContent = 'Download PDF'; // Default text
downloadButton.addEventListener('click', function() {
downloadButton.textContent = 'Downloading...'; // Loading text
downloadButton.disabled = true; // Disable button
const downloadUrl = '/api/method/frappe.utils.print_format.download_pdf?' +
'doctype=Cerere%20Generala%20Rutiera' +
'&name=' + encodeURIComponent(docName) +
'&format=Cerere%20Rutiera%20Standard' +
'&no_letterhead=1';
console.log('Opening download URL:', downloadUrl);
window.location.href = downloadUrl;
downloadButton.textContent = 'Download PDF'; // Restore text
downloadButton.disabled = false; // Re-enable button
});
}
// Display success message
const messageDiv = document.getElementById('statusMessage');
if (messageDiv) {
messageDiv.textContent = 'Document ready for printing/downloading: ' + docName;
messageDiv.style.color = 'green';
}
} else {
// Handle error if the document is not found
const errorMessage = data.message ? data.message.message : "Could not find the document";
console.error("Error:", errorMessage);
alert('The recent document was not found. Please try again.');
const messageDiv = document.getElementById('statusMessage');
if (messageDiv) {
messageDiv.textContent = errorMessage;
messageDiv.style.color = 'red';
}
}
})
.catch(error => {
// Handle network errors
console.error('Error calling API:', error);
alert('An error occurred while loading the document. Please reload the page.');
const messageDiv = document.getElementById('statusMessage');
if (messageDiv) {
messageDiv.textContent = 'An error occurred. Please try again.';
messageDiv.style.color = 'red';
}
});
});
3. How the Script Works
- Retrieve the latest document:
- The script sends a POST request to the API to fetch the latest document for the logged-in user.
- Includes a CSRF token for security.
- Configure buttons:
- Print: Generates a link to open the print view in a new tab.
- Download PDF: Generates a link to initiate the document download.
- Error handling:
- Displays a status message if no document is found or if the API fails.
- Enhanced user experience:
- Displays loading states and restores button text after actions are completed.
API Script in Backend
To complete the functionality, you need to define an API method in the Frappe backend. This method retrieves the name of the latest document from the specified Doctype ( In this case) (Cerere Generala Rutiera
) for the logged-in user.
Complete API Script:
Add the following function to the api.py
(create it in the console if there isn’t one) file in your app (In this case): (ghidul_cetateanului
):
import frappe
@frappe.whitelist()
def get_latest_document_for_user():
"""
Returns the latest document from 'Cerere Generala Rutiera' for the logged-in user.
"""
try:
# Get the logged-in user
user = frappe.session.user
# Get the latest document for the logged-in user
doc = frappe.get_all(
"Cerere Generala Rutiera", # The Doctype to query
fields=["name", "creation"], # The fields to return
filters={"owner": user}, # Filter by the logged-in user
order_by="creation desc", # Sort by creation date (descending)
limit_page_length=1 # Return only one document
)
if doc:
return {
"status": "success",
"document_name": doc[0]["name"],
"creation": doc[0]["creation"]
}
else:
return {"status": "error", "message": "No documents found for the current user"}
except Exception as e:
frappe.log_error(frappe.get_traceback(), "Error in get_latest_document_for_user")
return {"status": "error", "message": str(e)}
Explanation of the API Script
- Necessary Imports:
frappe
: Used to access Frappe methods and data.
- Retrieve the Logged-in User:
frappe.session.user
gets the currently logged-in user.
- Fetch the Latest Document:
frappe.get_all
: Fetches documents from a Doctype with options such as fields, filters, sorting, and limits.
- Handle Success:
- If a document exists, it returns
status: success
along with the document’s name and creation date.
- Handle Errors:
- If no documents are found or an exception occurs, the method returns
status: error
with the error message. - Errors are logged on the server using
frappe.log_error
.
Register the API
Ensure that the ghidul_cetateanului app is installed and functional:
bench --site your_site_name install-app ghidul_cetateanului
Ensure the method is accessible via API by decorating it with @frappe.whitelist().
Testing the API
a. Test from the System Console
Access the System Console in Frappe and run:
from ghidul_cetateanului.api import get_latest_document_for_user
print(get_latest_document_for_user())
b. Test from the Browser
Use the browser console to make a call using frappe.call:
frappe.call({
method: “ghidul_cetateanului.api.get_latest_document_for_user”,
callback: function(response) {
console.log(response.message);
}
});
c. Test with cURL
You can use cURL to verify the API functionality:
curl -X POST https://weave.ro/api/method/ghidul_cetateanului.api.get_latest_document_for_user
-H “Authorization: token your_api_key:your_api_secret”
-H “Content-Type: application/json”
Expected Result
On Success:
{
“status”: “success”,
“document_name”: “Numere Rosii - 01140136”,
“creation”: “2025-01-14 12:34:56”
}
On Error:
{
“status”: “error”,
“message”: “No documents found for the current user”
}