These forums are now Read Only. If you have an Acrobat question, ask questions and get help from one of our experts.

Saving a PDF with the Current Date Time as filename

viruletdew
Registered: Oct 27 2008
Posts: 43

Hi,

I have spent most of the day reading through posts regarding Saving and Save As form functions, for Acrobat Reader users.

I understand that unless we purchase special reader extensions, our users must create a digital id and sign the form before they may save the form.

I have also successfully tested the app.execMenuItem("SaveAs") function.

This would be sufficient, however we need the following two functions, in order to eliminate user error:

1. Automatically fill in the filename with a formatted datetime string (ie: YYDDMM_HHMM)

2. Save it to a folder in a shared network drive.

Thanks for your help. We are running on a deadline, and I'm stumped.

Jessica

My Product Information:
LiveCycle Designer, Windows
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
Quote:
I understand that unless we purchase special reader extensions, our users must create a digital id and sign the form before they may save the form.
I suspect you misunderstood what you read since that is not the case.

In order for Reader to save a modified document, the document must have certain rights applied. Acrobat Pro 8 and 9, as well as Adobe's LiveCycle Reader Extensions product, are capable of applying such rights to documents. LiveCycle Reader Extensions is capable of applying certain rights that Acrobat Pro cannot.

When rights are applied with Acrobat Pro, there are licensing restrictions that apply. In short, if you will be deploying the form to more than 500 recipients, you are limited to extracting information from no more than 500 instances (including hardcopies) of the form that have been returned to you.

In order to do what you want with renaming/relocating the file when it is saved, you would have to use JavaScript (perhaps with a Save As button you create, a custom menu item, or a custom toolbar button), and install a folder-level JavaScript file on each user's machine. This would allow you to execute code that you normally would not be able to due to security restrictions. In particular, you'd use the doc.saveAs method, which is documented in the Acrobat JavaScript reference, and this would have to be called from a trusted function. Thom Parker has a recent article on using trusted functions in one of his JavaScript Corner articles here.

If this doesn't sound like it would work for your situation, post again as there may be different approaches you can take, including those that are server-based.

George
viruletdew
Registered: Oct 27 2008
Posts: 43
Ok. So if I am to understand correctly, Adobe Reader users absolutely may not Save a copy of a modified form, even if they Digitally Sign the form via a Digital Signature field. This post on Adobe forums led me to believe otherwise: http://www.adobeforums.com/webx/.3bc3b72f

I would like to utilize something server-based, however due to circumstances beyond my control, I will not have access to a server, prior to the form delivery date. Apparently that would be a "progressive enhancement" Which is too bad.

So, I guess my only option is to create a trusted function. I have no idea how to do this, so I will read the Thom Parker article.

Thanks.
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
Reader users cannot apply a digital signature unless the document has had the appropriate rights applied. So the idea that activating Reader's ability to save a modified document is achieved by the end user applying a digital signature is incorrect.

What that person in the other forum was talking about was the alternate method of using restricted JavaScript code within a document, which is to use a certified document, as opposed to placing code in a folder-level JavaScript file that you then need to install on your user's machine. Digital signature technology is involved, but the approach of using certified documents is often overlooked because it is relatively easy to make changes that cause the document to become de-certified. In other words, this approach is often not useful in a workflow that needs to be reliable.

So, not only do you have to create the appropriate JavaScript code and place it in a JavaScript file that you install in the correct location on all of your user's machines, you need to apply the usage rights, either with Acrobat Pro or LiveCycle Reader Extensions. If you use Acrobat Pro to apply the rights, keep in mind the licensing restrictions.

George
viruletdew
Registered: Oct 27 2008
Posts: 43
So if I were to create a .js file, with my trusted JavaScript function in it - doc.saveAs and datetime, I could then just call it from the click event of the my "regular" button? How would I call the file?

What I have so far is pretty thin. Please let me know if I am heading in the right direction. How would I set a network drive and folder destination?

Config.js:

var SaveRequest = app.trustedFunction(
function (myDateString)
{
app.beginPriv();
var myDocName = myDateString + ".pdf";
doc.saveAs(myDocName);
app.endPriv();
}
);

Thanks again!
viruletdew
Registered: Oct 27 2008
Posts: 43
Okay. So I've tried to work this out a bit more:

In my Config.js file (Location: C:\Program Files\adobe\Reader 9.0\Reader\Javascripts)

//DateTime function
function myDateString()
{
app.beginPriv();
todayDate = new Date();
myYear = todayDate.getFullYear(); //return the four digit year
myMonth = todayDate.getMonth(); //return the month
myDate = todayDate.getDate(); //return the day of the month
myHour = todayDate.getHours(); //return the hours
myMin = todayDate.getMinutes(); //return the minutes
mySec = todayDate.getSeconds(); //return the seconds

myNewDate = myYear.toString() + myMonth.toString() + myDate.toString() + "_" + myHour + myMin + mySec;

return myNewDate;
app.endPriv();
}


// SaveAs Function
function saveDoc()
{
app.beginPriv();
var myDoc = app.newDoc();
var myPath = app.getPath("user", "documents") + "/WebRequestFiles/" + myDateString() + ".pdf"
myDoc.saveAs(myPath);
myDoc.closeDoc();
app.endPriv();
}


In MySaveAsForm.pdf (click event of "regular" button):

// SaveAs Function
var SaveRequest = app.trustedFunction(saveDoc());

Am I approaching this correctly, or am I way off base?

Thanks!
viruletdew
Registered: Oct 27 2008
Posts: 43
Hi George,

I have reworked my javascript, both in the folder level file (Config.js) and inline form level.

2 Problems:

1. In Acrobat Professional it is 90% functional, except the document saves as blank, but it does save. Could you help me figure out what is wrong with my doc.saveAs?

2. In Adobe Reader, I receive the following error:
NotAllowedError: Security settings prevent access to this property or method.
App.newDoc:38:XFA:Requests[0]:Buttons[0]:Button1[0]:click

Thank you soooo much for your help.

My code follows:

Config.js
//DateTime function
var myDateString = app.trustedFunction(function ()
{
app.beginPriv();
todayDate = new Date();
myYear = todayDate.getFullYear(); //return the four digit year
myMonth = todayDate.getMonth(); //return the month
myDate = todayDate.getDate(); //return the day of the month
myHour = todayDate.getHours(); //return the hours
myMin = todayDate.getMinutes(); //return the minutes
mySec = todayDate.getSeconds(); //return the seconds

myNewDate = myYear.toString() + myMonth.toString() + myDate.toString() + "_" + myHour + myMin + mySec;

return myNewDate;
app.endPriv();
}
);



// SaveAs Function
var saveDoc = app.trustedFunction(function ()
{
app.beginPriv();
var myDoc = app.newDoc();
var myPath = app.getPath("user", "documents") + "/WebRequestFiles/" + myDateString() + ".pdf";
myDoc.saveAs(myPath);
return myPath;
myDoc.closeDoc();
app.endPriv();
}
);



Inline code in pdf file, click event of button:
var saveSuccess = saveDoc();
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
Good job so far, but there are a few changes I'd recommend and a few you need to make:

//DateTime functionfunction myDateString() { return util.printd("yyyymmdd_HHMMss", new Date()); } // SaveAs Functionvar mySaveDoc = app.trustedFunction(function(doc) { var myPath = app.getPath("user", "documents") + "/WebRequestFiles/" + myDateString() + ".pdf" // saveAs is the only privileged code that needs to be enclosed// with beginPriv/endPrivapp.beginPriv();doc.saveAs(myPath);app.endPriv(); // Do you really want to do this?doc.closeDoc(); });

Now, the code you can use in a button in the PDF should be something like:

// SaveAs and close this documentmySaveDoc(this);

I haven't tested any of this, so let us know how it goes.

George
viruletdew
Registered: Oct 27 2008
Posts: 43
Hi George,

I updated my code. The datetime function is so much more concise.

However, now I am receiving the Security Error in both Acrobat Pro and Adobe Reader:
NotAllowedError: Security settings prevent access to this property or method.
App.newDoc:38:XFA:Requests[0]:Buttons[0]:Button1[0]:click

I'm really scratching my head over this...

Are there settings I need to apply somewhere?

Thanks again. You are such a big help.

Jessica
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
You'll have to post your updated code. Why are you doing an app.newDoc call?

George
viruletdew
Registered: Oct 27 2008
Posts: 43
Oh. I'm sorry. I updated my code with your suggested edits:

Config.js:
//DateTime function
function myDateString() {

return util.printd("yyyymmdd_HHMMss", new Date());

}

// SaveAs Function
var mySaveDoc = app.trustedFunction(function(doc) {

var myPath = app.getPath("user", "documents") + "/WebRequestFiles/" + myDateString() + ".pdf"

// saveAs is the only privileged code that needs to be enclosed
// with beginPriv/endPriv
app.beginPriv();
doc.saveAs(myPath);
app.endPriv();

// Do you really want to do this?
doc.closeDoc();

});

inline code:
// SaveAs and close this document
mySaveDoc(this);
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
That revised code does not have a call to the app.newDoc method, but the error message you posted indicates that this is what's causing the trouble. Might you have other code somewhere that's using app.newDoc?

BTW, since you're apparently working with a LiveCycle Designer created PDF, I'm not sure the code you use to call the function is correct. For a form created in Acrobat, the "this" object is the current document. I'm not sure how you'd reference the current document for an XFA form.

mySaveDoc(reference_to_this_document_goes_here);

George
viruletdew
Registered: Oct 27 2008
Posts: 43
To answer your app.newDoc question. I though I needed to created a new doc in order to save a copy of my current form...obviously not right.

It's just that after implementing your suggested code (pasted above), now I get a security error in both Acrobat Pro and Adobe Reader. I have not idea where do go from here.

function myDateString() and var mySaveDoc both live in the folder level document right?

myDateString() doesn't require any privileges?

Thanks again,
Jessica
viruletdew
Registered: Oct 27 2008
Posts: 43
Sorry, posted that last response before I saw that you responded...

That app.newDoc error message was copied incorrectly. This is the new error:

NotAllowedError: Security settings prevent access to this property or method.
App.getPath:25:XFA:Requests[0]:Buttons[0]:Button1[0]:click

I'll try to figure out how to alter the "this" in LifeCycle. I appreciate your help. I don't know what I would do otherwise.
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
Oops! Sorry about that. You can correct it by moving the

app.beginPriv();

statement before the

var myPath = ...

statement.

This is because app.getPath is indeed restricted, so it needs to be within the beginPriv/endPriv lines.

Regarding app.newDoc, what that does is create a new blank single-page document, which is not what you want. You already have a document, you just need to save it with a new name/location, which is what doc.saveAs does.

George
viruletdew
Registered: Oct 27 2008
Posts: 43
No worries. I'm glad for the help.

I moved the app.begin, so here is the new error:
doc.saveAs is not a function
30:XFA:Requests[0]:Buttons[0]:Button1[0]:click

Here is the current Config.js code:
//DateTime function
function myDateString() {

return util.printd("yyyymmdd_HHMMss", new Date());

}

// SaveAs Function
var mySaveDoc = app.trustedFunction(function(doc) {

app.beginPriv();
var myPath = app.getPath("user", "documents") + "/WebRequestFiles/" + myDateString() + ".pdf";

// saveAs is the only privileged code that needs to be enclosed
// with beginPriv/endPriv
doc.saveAs(myPath);
app.endPriv();

});

Inline code:
// SaveAs and close this document
mySaveDoc(this);


I have not found any documentation on what to use in place of "this". I have tried xfa.form.myForm and xfa.pdf. Each return with doc.saveAs is not a function.
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
That's what I was afraid of. Try this:

mySaveDoc(event.target);


George
viruletdew
Registered: Oct 27 2008
Posts: 43
Hi George,

You are great. After I enabled Adobe Reader Usage rights in Acrobat Pro, this worked. So to summarize all of this back and forth:

Folder level Config.js file: Applied at location - C:\Program Files\adobe\Reader 9.0\Reader\Javascripts

Code:
//DateTime function
function myDateString() {

return util.printd("yyyymmdd_HHMMss", new Date());

}

// SaveAs Function
var mySaveDoc = app.trustedFunction(function(doc) {

app.beginPriv();
var myPath = app.getPath("user", "documents") + "/WebRequestFiles/" + myDateString() + ".pdf";

// saveAs is the only privileged code that needs to be enclosed
// with beginPriv/endPriv
doc.saveAs(myPath);
app.endPriv();

});

Inline JavaScript: Applied to "regular" button click event

Code:
// SaveAs and close this document
mySaveDoc(event.target);

I have one more question :)
Is there any way possible to change the save to directory to a shared network drive? Or is it only possible to target the user's document directory.

Thank you so much. You saved my life on this one.

Jessica
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
Regarding the shared network drive, you can try it, but you will need to hardcode the path in your script. If you have trouble determining what string value to use, post again.

Also, you should consider changing the name of your trusted function, now that the world knows what it is. The doc.saveAs method has security restrictions for a reason, in part so any old PDF that a user opens up cannot saveAs itself on the user's system without them knowing. You've opened up a security hole, which is fine, but now you need to make it a bit smaller by using a hard-to-guess name for the trusted function. Change it back in case you need to post the code here again.

George
viruletdew
Registered: Oct 27 2008
Posts: 43
I changed the name of the function. Thanks for the reminder.

As for the path:

Do you mean this line of code needs to change?
var myPath = app.getPath("user", "documents") + "/WebRequestFiles/"

I would just need to change it to:
var myPath = "/myNetworkDrivePath/morePath/etcPath/" + ....

Thanks again!
viruletdew
Registered: Oct 27 2008
Posts: 43
Sorry. "\" not "/"
viruletdew
Registered: Oct 27 2008
Posts: 43
Okay. I see what you are talking about. I am getting an error when I simply try to add a string:

UnsupportedValueError: Value is unsupported. ===> Parameter cPath.
Doc.saveAs:19:XFA:Requests[0]:Buttons[0]:Button1[0]:click

my code:
var myPath = "\\myNetworkDrivePath\morePath\etcPath\" + myDateString() + ".pdf";

Is cPath a specific string conversion?
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
Actually, "/" is correct.

To see what the path should look like, open a document that's in the directory in question, open the JavaScript console (Ctrl + J), and type the following:

path

Then click Ctrl + Enter with the cursor on the line you just typed. It should display the path of the file.

George
viruletdew
Registered: Oct 27 2008
Posts: 43
That's what I thought at first, but my systems guy told me to use the "\". Which wasn't working....

The path request is a pretty handy.

Okay, so I think it works pretty well...far from where it was this morning. Now I just need to find some documentation on how to "lock" down fields after saving, or show some kind of edits log (user and date). Could you point me in a direction? You have been so great. I don't know how to thank you!

Jessica
George_Johnson
Online
Expert
Registered: Jul 6 2008
Posts: 1876
You need to define what you mean by "lock down", exactly? Once the forms are filled and saved, what will you do with them afterwards?

George
viruletdew
Registered: Oct 27 2008
Posts: 43
Hi George,

Well, at first I considered locking the fields after the form is filled out and a copy of it is saved. This is a web request form, if you haven't already gathered that from some of the code. However, now I think that would be a bit draconian.

Updated may need to occur, yet we still need some kind of tracking for measuring efficiency, time-lines and overall quality of the requests. So now I am interested in keeping track of amendments and additions to the request form each time a user edits and saves it.

This would mean the following, after the initial save:

1. Keeping the original file name upon editing and saving.

2. Gathering the User info and the Dates.

3. Gathering a summary of the changes or additions to the form.

I guess I would take the info from 2 and 3, then place it in a Read-only auto height text control at the bottom of the form.

Does this seem ineffective or too difficult? I'm sure it would be much easier with LifeCycle ES, but we don't have the budget or the overhead to maintain something of that scale.

Thanks for your input.

Jessica
John Grand
Registered: Aug 18 2009
Posts: 18
Save as with full date as part of the file name.

I would like to attach some code to a button the will save my form to th C:\Temp directory and use the current date and time as the file name. I am not sure how to write the code that controls the path. Any sample of how to do this would be helpful.

Thanks John
Hillyman
Registered: Apr 21 2009
Posts: 15
viruletdew,

I noticed that you expressed some interest in locking fields and such. There was a great Acrobat User Community Tech Talk entitled "Advanced Form Techniques" that covered how to go about locking all/some fields via scripting, buttons, etc. It also covers methods for submitting forms via email and creating unique IDs. At the end of the talk, the presenter provides a few sample files that have really helped me get a good start in my own projects. Here is the link:

https://admin.adobe.acrobat.com/_a200985228/p91165028/

Hope that helps!