Browser Back Button - Breaking onClick event - xpages

I have a repeat control setup which contains a table. The table row(s) contain information from an entry in a view. When the user clicks on the entry, it will redirect them to another xPage which contains the information pertaining to the item they clicked.
I noticed that if you click the browser back button (in this case mobile iPhone Safari), it will redirect you to the previous page, but the onClick events do not fire if you click a row in the repeat control.
I'm not exactly sure what is causing this to break, but has anyone run into this in the past or have any idea no what may fix this issue?
var entry:NotesViewEntry = data;
var docId = entry.getDocument().getUniversalID();
var url = context.getUrl().getAddress().replace(view.getPageName(), '');
context.redirectToPage(url + "/xCall.xsp?documentId=" + docId + "&action=openDocument");
Edit:
The issue appears to only occur when using mobile Safari (for iPhone). It works fine in Chrome/Internet Explorer.
Another interesting detail, if you click on an item and it redirects you to a page, then you click the browser back button, you can click on the repeat control and nothing happens. However if you way 15-20 seconds and then click, it works like expected. If you click anytime before 15-20 seconds, nothing happens
Second Edit:
I ended up coming across this link: https://github.com/christophery/pushy/issues/51 which described a problem where the browser back button was creating weird behavior. I ended up using the following code which seems to have fixed the issue.
// for jQuery
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {window.location.reload();}
});
// for regular JS
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload()
}
};

This might be caused by the browser caching the previous page. Add this to the beforePageLoad event of your XPage in order to tell the browser not to cache the page:
<xp:this.beforePageLoad><![CDATA[#{javascript:
// Do not cache the HTML pages in the browser
var exCon = facesContext.getExternalContext();
var response=exCon.getResponse();
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Cache-Control", "no-store");
}]]></xp:this.beforePageLoad>

Related

Chrome extension keeps resetting

I'm new to chrome extension development but I'm running into issues debugging and with the extension itself. I currently have a form with a submit button and after the user hits submit I change the html to show the data that was just submitted.
document.addEventListener('DOMContentLoaded', function() {
console.log("1");
document.getElementById("submitButton").addEventListener('click', myFunction);
console.log("2");
//getCurrentTabUrl(function(url) {
// renderStatus(url);
//});
});
function myFunction() {
document.getElementById("formOutput").innerHTML = document.getElementById("formInput").value;
alert("hi");
console.log("test");
);
}
In this, 1 and 2 are displayed to the extension debugging console and the alert runs as well when the button is clicked. The test shows up very briefly and then it disappears.The formoutput value changes very briefly as well and then changes back to the default value I have. Does anyone know why my code/the chrome extension would be doing this?
Thanks!
When button with type submit (This is the default if the attribute is not specified) is clicked, the form data will be sent to server and page will be redirected to new page. Then your content script will be injected again, that's why the it changes back to default value.
To avoid this, you could change button with other types, or calling e.preventDefault to prevent default behavior. Then you would want to use Ajax to send data to server, which ensure the whole page won't be redirected and only parts of UI can be updated.

Auto-collapse any item in PrimeFaces PanelMenu on page loading

I'm writing a Primefaces 5.1 portlet.
It consists in a unique page containing a panelMenu, and I need that it starts with any panel collapsed everytime a user change page (on page loading).
But, if I open a panel, then change page, it will start showing that panel still opened.
I wasn't able to find any option to achieve this goal (e.g. collapsed=true, ignoreCookie=true or something similar).
The only solution I found was the following Javascript code:
PrimeFaces.widgets.myPanelMenu.collapseRootSubmenu(PrimeFaces.widgets.myPanelMenu.headers);
The problem is that this code will collapse any opened panel (so on page loading user is able to see panel menu collapsing animation) but it seems it doesn't store this state in its cookie/localstorage... the result is that on any page loading user can see this animation.
I'm sure it doesn't save its state, because the only way to "solve" the problem is to manually re-open and re-collapse the panels... then, on following page change, these menus start closed (and there is no animation).
I also tried to use PrimeFaces.widgets.sideMenuPanel.saveState() after collapsing, but with no success.
Do you have any idea about?
Thank you...
I found a solution to the problem.
If you read my discussion with Kukeltje (comments on my question), you will find that latest Primefaces' versions will solve the problem.
Otherwise, if you want to avoid upgrade or modify sources, and you need a quick fix based on Javascript only please read the following part of the answer.
It directly works on the component's state using JavaScript.
First of all you need to have a variable reference to your component:
<p:panelMenu model="#{menuBackingBean.menuModel}" widgetVar="sidePanelMenu" />
Then you should add the following JS code on document ready:
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
// 1. On page loading collapses possible opened panels
panelMenu.collapseRootSubmenu(panelMenu.headers);
// following line is commented because it never should be necessary is not necessary (unless unexpected situation I never verified)
//clearSidePanelMenuPreferences();
// 2. Call the "clear preferences" actions on click on two tpe of links: first level are the panel link (used to open/close the menu) and second level are the destination links
// We need to fork also on the first level links to be sure it works after user clicks there then exit from the page in another way
panelMenu.headers.children("a").click(function(){setTimeout(clearSidePanelMenuPreferences, 500)}); // setTimeout is necessary because this event should be fired after preferences are written
panelMenu.headers.siblings().find("a").click(function(){clearSidePanelMenuPreferences();});
The function called to clear preferences are the following:
function clearSidePanelMenuPreferences() {
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
panelMenu.expandedNodes = []; // clear the opened panels lists
panelMenu.saveState(); // store this information
}
Hope it helps
Please check this block of code
PF('myPanelMenu').headers.each(
function(){
var header = jQuery(this);
PF('myPanelMenu').collapseRootSubmenu(header);
header.removeClass('ui-state-hover');
}
);
I prefer to do this in order to execute this method only once and keep the menu option selected.
$(document).ready(function() {
if(location.pathname == "/cotizador/" || location.pathname == "/cotizador/faces/login.xhtml"){
var panelMenu = PrimeFaces.widgets.sidePanelMenu;
// 1. On page loading collapses possible opened panels
panelMenu.collapseRootSubmenu(panelMenu.headers);
panelMenu.expandedNodes = []; // clear the opened panels lists
panelMenu.saveState();
}
});

context.redirectToPage only works intermitently in Notes Client

I have a button in an Xpage with an OnClick event that does the following:
var viewPanel=getComponent("viewPanel1");
var docIDArray=viewPanel.getSelectedIds();
sessionScope.put("searchDocIDArray",docIDArray);
var url="exportData.xsp";
context.redirectToPage(url, false);
The exportData page is not rendered but just has some code to write out an Excel file. In the client sometimes it does this and sometimes it does nothing and sometimes it writes over the current Xpgage and is just blank. I think what I need to do is to just launch that page in a new window? I am not sure.
It works on the web every time.
What version is your client?
Another approach you can try is opening your xagent with a window.open () in the onComplete event of your button. I don't remember off the top of my head if that works in xpinc. The advantage of this is your export will open in a new tab.

XPages: Single Page Application Data View refresh

I have a Single Page Application that has two pages - the first page contains a Data View view control (I used the wizard to create the pages - I did not create any custom controls as the entire application only contains 4 pages!), the second page then displays the document selected in the Data View control. This works perfectly! My problem is that the documents that are displayed in the Data View Control are not being refreshed - I need to do a manual refresh for them to show up. Not a problem I though, just do an automatic refresh every 5 seconds (there are only going to be about 20 users using the application):
<meta http-equiv="refresh" content="5; URL="></meta>
this refreshes the page perfectly - if a user is on the second page s/he gets bumped back to the page with the Data View control (i.e. Page 1) and does not stay on the open document (ie page 2).
How can I get the Data View control to refresh periodically without being bumped back to the Data View control?
Thanking you in advance
ursus
I don't think you really want to refresh the view every n seconds as that has the possibility of becoming a huge performance issue, plus the cause for weirdness as you pointed out. There are 2 ways to approach this:
In the Application Page properties, set resetContent to true
Create a onAfterTransitionIn event to do an XSP.partialRefreshGet on the data view or it's container. This way when someone lands on the view it'll refresh it's contents. Below is an example:
var widget = dijit.byId("#appPageName");
dojo.connect(widget, "onAfterTransitionIn", function(moveTo, dir, transition, context, method){
console.log("onAfterTransitionIn args=",arguments);
var appPageChildren = dojo.query("[id='" + appPageName + "']").children()[0];
var contentId = appPageChildren.id;
console.log("contentId=",contentId);
setTimeout(function() {
XSP.partialRefreshGet(contentId, {});
},200);
});

disable back button in browser

I have a website having frames. Clicking on button in one frame updates the pages to be loaded in other frames. Now when user press the back button few of the frames load previous pages. i want user not to move back to previous page.
I used the code history.forward() on onload event of all my pages.
This works fine when back is pressed. User got navigated to most recent page always.
But the case is suppose user navigate to number of pages by clicking on button in first frame which updates the pages to be loaded in other frames. After navigation user select a page from the list of browsing history, then it is move forward to only one page, not the last page he was viewing.
This Happens in IE.
In firefox it works fine. User can select any page from the browsing history, he is relocated to most recent page
My opinion is, you should review your concept, because you want to "reconfigure" the browser's navigation buttons. Disabling browser features is in my eyes old fashioned.
I used the code history.forward() on onload event
Try following this way:
In the head section, insert the javascript:
var historySize = history.length;
Then replace in onload event: history.forward() by history.go(historySize - 1). A positive value means move forward to a particular position in browser's history object (array).
I cannot guarantee that it will work, but it is worth to try out.
write this code between script tags
history.pushState(null, null, location.href);
window.onpopstate = function () {
history.go(1);
};

Resources