In September I posted a link to some auto Save JavaScript for ePerformance. This worked, but it prevented the page from timing out and it would also save while I would be typing on the document and then all of a sudden I would be at the top of the document. This was quite annoying. At the same time I was working on warning the user about leaving the page via the back button, I had asked Jim Marion a couple questions and he recommended I monkey patch the timeout function to auto save the document. So below is my JavaScript that monkey patches the displayTimeoutMsg function and warns the user if they navigate away from the page with the back button.
<input type="hidden" name="AUTOSAVE" value=""/>
<script type="text/javascript">
threadLock = false;
function user_function()
{
//alert('starting process');
var changes = checkFormChanged(document.%formname);
if (changes && !threadLock)
{
threadLock = true;
if ("%page" == "EP_APPR_MAIN1" || "%page" == "EP_APPR_BASE1")
{
//submitAction_%Formname(document.%Formname,"EP_BTN_LINK_WRK_EP_STORE_PB");
hAction_%Formname(document.%Formname,'EP_BTN_LINK_WRK_EP_STORE_PB', 0, 0, 'Save', false, true);
}
}
}
</script>
<script type="text/javascript" language="javascript">
(function() {
var originalendModalCntrl = ptCommonObj.endModalCntrl;
ptCommonObj.endModalCntrl = function() {
window.onbeforeunload = function(){};
return new originalendModalCntrl();
}
})();
window.onbeforeunload = function(e) {
var changes = checkFormChanged(document.%formname);
if (changes && !threadLock)
{
threadLock = true;
if ("%page" == "EP_APPR_MAIN1" || "%page" == "EP_APPR_BASE1")
{
return "You have unsaved changes, please save them."
};
}
}
</script>
<script type="text/javascript">
function adaptLinks() {
var links = document.getElementsByTagName('a');
for (i = 0; i != links.length; i++) {
links[i].onclick = (function () {
var origOnClick = links[i].onclick;
return function (e) {
window.onbeforeunload = function(){};
if (origOnClick != null && !origOnClick()) {
return false;
}
}
})();
}
}
(function() {
var originaldisplayTimeoutMsg = displayTimeoutMsg;
displayTimeoutMsg = function() {
window.onbeforeunload = function(){};
user_function();
return new originaldisplayTimeoutMsg();
}
})();
adaptLinks();
</script>
This comment has been removed by a blog administrator.
ReplyDeleteWe tried this piece of code on Tools 8.51, but when the Save is triggered, it reset's the Timeout counter. How can we prevent the Time-out counter from being reset in Tools 8.51 and App 9.1 ?
ReplyDeleteDivya,
ReplyDeleteThis code does reset the timeout counter, however the second time the user will be timed out. This was acceptable in my organization as we time users out every 30 minutes. But we had considered moving that to 1 hour. If this is not acceptable to your organization then you need a mechanism to tell you when the save happens organically vs the timeout JavaScript that we are injecting into the page.
You can add a hidden field to your page and mark that field as “Modifiable Via JavaScript” , then give it Page Field Name that is meaningful, something like AUTOSAVEFLAG. Then in your HTML that your adding to the page add this new Flag as a Hidden Input.
< input type="hidden" id="AUTOSAVEFLAG" name="AUTOSAVEFLAG" value="F"/>
< script type="text/javascript">
threadLock = false;
function user_function()
{
var changes = checkFormChanged(document.%formname);
if (changes && !threadLock)
{
threadLock = true;
if ("%page" == "EP_APPR_MAIN1" || "%page" == "EP_APPR_BASE1")
{
//submitAction_%Formname(document.%Formname,"EP_BTN_LINK_WRK_EP_STORE_PB");
var flag = document.getElementById('AUTOSAVEFLAG');
flag.value = 'T';
Preceding code is not changed….
Then add some PeopleCode to the SavePreChange event of your hidden field to inject javascript to redirect the user to the logout url.
Kevin,
ReplyDeleteWe are currently trying to implement exactly what you documented here. I have one question and it may sound very stupid, but where do we need to put this code. We already have a working 'autosave' like your original , but we would like to do exactly what you have posted here and I just need some help as to where the code needs to go. I am very new to javascript and monkey patching and just need some guidance.
Thanks,
Anthony
Anthony,
ReplyDeleteI added an HTML area to both the Page.EP_APPR_MAIN1 and Page.EP_APPR_BASE1 at the bottom, then I pasted the JavaScript above into the HTML area as a constant value.
To test this code, I used FireFox and the Firefox plugin, Firebug. You can set breakpoints within the JavaScript and interact with the browser via the console. These techniques are shown in Jim Marion's PeopleTools Tips and Techniques book. If you don't have a copy then I recommend that you get one, as it has a great chapter on JavaScript.
Thanks for stopping by!
Kevin, Should this also work for IE 8? I added the HTML area (and code) to both pages and neither the autosave or navigation message is working. Is there something else that needs done in AppDesigner? My email is scott.tallent@windstream.com Thanks
DeleteScott, I believe this will work with IE 8. However, I would start by debugging using firebug or chrome.
DeleteHi Kevin,
ReplyDeleteCould you please tell me whether you are passing any time interval for auto-save to happen or will the code be fired continuously until the user gets logged off?
Since EP_APPR_EDIT5 is the page where we type a lot , and if we using the above piece of code to save EP_APPR_EDIT5 which will call the save button thus redirecting it to EP_APPR_BASE1 page might lead to resetting of timer.
Supriya,
ReplyDeleteWe are also discovering that users are being timed out on this page as well, we are also discovering managers are opening multiple windows and are losing their data when the secondary window timesout. I have no solution for this last issue, other then training. But the first issue, the same one you are having is not accounted for within this post. I will be looking into a solution for this in the near future.
My initial thought is to add a hidding field that is accessible via javascript to this page that will execute some save peoplecode, since there is currently no save functionality on this page.
I hope this blog topic is still active in spite of its age.
ReplyDeleteWe have tried this code at PT 8.50, PS 9.1. The warning about leaving the page without saving data is a welcomed touch, and is working. But the timeout does not work for us.
Even after enabling the alert("starting process") code, we never see that alert. Instead, we see the standard timeout message, and then the timeout does occur without save.
I wonder if the function displayTimeoutMsg() has a different name or doesn't exist at our version level?
I am also confused by the test for page names (if ("%page" == "EP_APPR_MAIN1" || "%page" == "EP_APPR_BASE1")) since we are directly modifying those two pages. Makes me think my approach may be incorrect. To me, that is the equivalent of code like "if (2+2 == 4)" So I'm convinced that I didn't understand something, and my approach is flawed. Can you help?
You are correct regarding the %page code. The useful part of this code is if your going to use tools 8.54+ and component branding. You would only want to save the component from these two pages, or you will get a data buffer error on the document.
DeleteTry using chrome and bring up console (F12) and then navigate to the doucment and look for some JavaScript errors. We have decommissioned this code and now use the delivered auto save that is available in 9.2 tools 8.54.
kevin, looks like your above code for "warning the user about leaving the page via the back button" works only in 9.1/<8.52 versions.
ReplyDeleteI heard you saying there is a delivered auto save that is available in 9.2 tools 8.54.
we just recently upgraded tools to 8.54 but still on 9.1.
1.can you let me know the delivered auto save code and i will try to implement in 8.54/9.1 to see if it works.
I included the js that we were using during testing, while we worked out a bug with the delivered Autosave. I am happy to share it with you, but it is not fully vetted and you will still need to follow the approach I laid out in AutoSave III.
Deletechange the input_tag to input and the script_tag to script below:
// special variable to store "our" single jQuery instance
if(!window.psjq$) {
window.psjq$ = window.$ = window.jQuery;
} else {
// ignore recent import and use the global single instance
window.jQuery = window.$ = psjq$;
}
threadLock = false;
var xStore = document.getElementById("ZZ_EP_STORE");
function user_function()
{
//alert('starting process');
// debugger;
console.log('user_functin called');
if (!threadLock)
{
threadLock = true;
if ("%page" == "EP_APPR_BASE1" )
{
xStore.value = 'T';
//alert(xStore.value);
//document.%formname.submit();
window.onbeforeunload = function(){};
console.log('appr_base1 save called');
submitAction_%Formname(document.win0,'#ICSetFieldEP_APPR_BASE1.EOTL_UI_BTN_ID.EXIT_SAVE#SAVE');
} else {
xStore.value = 'T';
//alert(xStore.value);
//document.%formname.submit();
window.onbeforeunload = function(){};
console.log('EP_APPR_MAIN1 save called');
submitAction_%Formname(document.win0,'#ICSetFieldEP_APPR_MAIN1.EOTL_UI_BTN_ID.EXIT_SAVE#SAVE');
}
}
}
function adaptLinks() {
var links = document.getElementsByTagName('a');
for (i = 0; i != links.length; i++) {
links[i].onclick = (function () {
var origOnClick = links[i].onclick;
return function (e) {
window.onbeforeunload = function(){};
if (origOnClick != null && !origOnClick()) {
return false;
}
}
})();
}
}
$(document).ready(function() {
// debugger;
console.log('setting ZZtimeoutID');
zztimeoutID = window.setTimeout('user_function()', (warningTimeoutMilliseconds + 5000));
});