Dynamic Content Control in Extlib flips out after rebuild - xpages

I have an issue with the dynamic content control in ExtLib. Every time I compile my xpage the dynamic content control flips out if I do not reload the page. I need a way to control this, like an onerror event on the control.
this is wahat's happening
I open my webpage, the dynamic content control works fine
I do some changes to my xpages and build (webpage still open)
I click a link on my webpage to reload the content in the dynamic content control.
the webpage flips out and starts to reload constantly using a partial refresh url.
I use various ways to update this control. sometimes it is through a csjs link and somtimes it is per interval using XSP.partialRefreshGet() so I guess I need a way to know if the dynamic content control is available before calling it, or let the control notify me somehow that is is not available
any idea?
Thanks
Thomas

When you change an XPage you must do a manual full reload of that page in any browser. Executing any call from the stale page will not work.

Related

Xpages document changing document mode?

I have a strange thing occurring; as usual, I can't post code, unfortunately, so I'm describing the problem in case anyone can suggest a possible cause.
I have an xpage with a custom control included on it; the custom control handles document locking and changing to edit/read-only modes via links. The document locking is done by setting an applicationScope variable based on the UNID. To make it more friendly for other users on the system, I run a function periodically on the page to check whether the document is locked or not and update a link/label/tooltips appropriately (e.g. if locked by another user, then the "Edit" button is disabled; when the lock is released, it's re-enabled). This is done by calling an "xagent" through a standard, simple dojo-based ajax call.
For some reason, the behavior of the system gets erratic after 45 seconds to a minute. I'm checking the lock status every ten seconds or so, so it's not happening with the first call. I'm displaying a list of records associated with the document; each record is a row in a repeat. When I first go into edit mode, the controls are all displayed as they should be, i.e. editable. If the user changes a particular value with a combobox, it updates the whole row with a partial refresh. When things get erratic, I noticed that the row starts refreshing in read-only mode, which suggests to me that the document is changing edit mode. The only time I knowingly change edit mode is if a "Cancel" or "Save" button is pressed. (The locking mechanism itself doesn't have anything to do with the edit mode.)
It certainly seems like the ajax call I'm making is at the root of this. But I've stripped the xagent and the client-side code down to practically nothing, and it's still happening. I can't see what would be causing this behavior. Can anyone hazard a guess? Thanks....
Maybe check if the server log file has warnings like:
WARNING CLFAD####W: State data not available for /page because no control tree was found in the cache.
If you're seeing those warnings, it could be that the server can no longer find the current XPage page instance in the cache. In that case the page will revert to the initial state, like when the page was first opened. That might be why the document goes to read-only mode.
The session cache of server-side page instances only holds 4 pages when xsp.persistence.mode=basic, or it holds 16 instances when xsp.persistence.mode=file or fileex.
If you load 4 xagent page instances, then that will fill the cache, and it will no longer be able to find the page instance for the current XPage you are viewing. So the XPage will stop performing server-side actions, and partial refresh will always show the initial state of that area of the page.
To avoid that problem, in the xagent page you can set viewState="nostate" on the xp:view tag, so that page instances are not saved for the xagent page, as described here:
https://tobysamples.wordpress.com/2014/12/11/no-state-no-problem/
Or else you can create and reuse one page instance for the xagent, so only one is created. That is, on the first call to the XAgent, have the xagent return the $$viewid value for the xagent page instance (#{javascript:view.getUniqueViewId()}), and then in subsequent requests to the xagent use that $$viewid in the request, to restore the existing xagent page instance instead of creating new instances that will fill the cache. So the subsequent xagent requests will be like so:
/myApp.nsf/xagent1.xsp?$$viewid=!aaaaaaaa!
It's hard to troubleshoot without code, but here are a few thoughts:
How are you checking document locking? Via a client-side JavaScript AJAX call or an XPages partial refresh? If the latter, what is the refresh area? If the former, what is the refresh area you're passing and the return HTML? Does it always occur when you're in edit mode on a row and the check happens, or independently of that? The key thing to check here is what the check for locking is doing - is it checking the server and returning a message outside the repeat, or checking the server and returning HTML that overwrites what's currently on the browser with defaults, e.g. the document mode as read mode.
What network activity is happening between the browser and the server and when? Is something else overwriting the HTML for the row, so resetting the row to read mode.
It's unlikely to be random, the key is going to be identifying the reproduceable steps to identify a common scenario/scenarios and cause.
EDIT
Following on from your additional info, is there a rendered property on the Edit link? If that calculates to false in earlier JSF lifecycle phases, the eventHandler is not available to be triggered during the Invoke Application phase. Because the eventHandler also includes the refreshId, there is no refreshId and refreshMode, so it defaults to a full refresh with no SSJS running. See this blog post for clarification http://www.intec.co.uk/view-isrenderingphase-and-buttons/.

XPage not syncing properly with backend data on partial refresh

I have an XPage that displays fields in a document. I also have the ability to pop out a new window that displays those same fields. I'm implementing a document locking scheme so that the two instances can't cause conflicts (and this is how I'm testing it).
A problem I've run into is that when the user edits the document in the pop out and saves it, a partial refresh of the panel containing those same fields in the original page doesn't show the updated data.
The save in the pop out was successful, and I can see in the Notes client that the document does indeed have the new value, but the original page simply won't show the new value. A complete page refresh using the reload button in the browser works, but I'd like to trigger this programmatically and as quickly as possible, hence the partial refresh.
Does anyone know what is going wrong? Is the NotesXspDocument in the original page getting out of sync with the backend document? I read about document1.getDocument(true), but that doesn't seem to do anything.
(As usual, I can't supply source code unfortunately....)
Once the NotesXspDocument is loaded with the XPage, a partial refresh does not update the xspDoc from the back-end DB, but from the in-memory DataSource.
You will need to refresh the XPage:
Reload the url from browser or in ssjs with a context.reloadPage()

Command Not Handled Exception

I'm new to Domino Designer. I'm trying to modify an existing application which is running on a remote server. I create a blank xPage and view in browser and it works. I add a label and view in browser and it works. I add a combo box and setup a data source for my xPage. The data source is in the current application and I'm using a view. I setup my combo to point to that data source and specify BindTo value. I view it in browser and I get Error 500 "HTTP Web Server: Command Not Handled Exception" I can open the view that I've used and see all the data in the view. I can even add, edit, and delete from the view.
Ideas... Thnxs in advance.
Additional Info. I've added a "View" from "Container Controls" and used the same data source and the same view and it also works in the browser.
The error being printed is:
javax.faces.el.PropertyNotFoundException: Error getting property 'CompanyName' from bean of type lotus.domino.local.View
com.sun.faces.el.PropertyResolverImpl.getValue(PropertyResolverImpl.java:119)
com.ibm.xsp.el.PropertyResolverImpl.getValue(PropertyResolverImpl.java:144)
com.sun.faces.el.impl.ArraySuffix.evaluate(ArraySuffix.java:182)
com.sun.faces.el.impl.ComplexValue.evaluate(ComplexValue.java:163)
com.sun.faces.el.impl.ExpressionEvaluatorImpl.evaluate(ExpressionEvaluatorImpl.j‌​ava:257)
com.sun.faces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:150) ....
This was already answered in the comments, but I want to write a better answer.
The problem in this case is that a view data source is being used for editing a document. Directly, this is not a possibility, though there are a few great ways to get around this. The first way, and my favorite, is to use an inline form. I think the Extension Library Demo database offers a few great examples of how to go about doing this. One way is to use a tooltip dialog. Another way is an inline form. A repeater is used and for every row in the view, a hidden panel can be made which contains the document data source and all field which are required to be changeable. By clicking on a button or link, the panel is made visible. This is my favorite variant because it is simple, quick, and generally looks great.
Another way to go about this is to have a view data source only, but use scripts to retrieve the document and set the values in the background and then save and release. It all depends on what you are trying to achieve.
My main recommendation is to look at the ExtLib demo and take a look at what they are doing there.

XPages templating dialog boxes

I am currently on a project redesigning an existing traditional domino web application to XPages. This application contains a web form with quite a lot of helper dialog boxes. Also notifications and validation and confirmation is done through dialogboxes.
I know I can create a custom control for each dialog box and add it to the Xpage and call the show. I even managed to load it dynamically using a dynamic content control with a facet for each dialog. Since the dialog cc contains a show() in the onClientLoad. It is easy to open a dialog by switching the content of the dynamic content control.
Still, adding all these custom controls to my XPages feels inefficient and really clutters the design tab. What's your take?
I would prefer setting the content of the dialog dynamically (Like in traditional domino you would define a form for each dialog). Is that possible?
If not is it possible to load a custom control dynamically (Like using a computed subform)?
Also for confirmation boxes I need the OK button to execute different code for each confirm. What would be the best way to implement that? Add custom parameter "functionOnOk" to the "dlgConfirm" custom control and evaluate that in the submit button?
PS: I am still using panels with dojoType=dijit.DialogBox, but will change those to extlib dialog boxes. For the confirm and messageboxes I am now using client side dijit.Dialogs with mark-up in code, but I would like the markup in XPages as well.
I know there are issues with panels with dijit.Dialog, because Dojo moves the dialog in the DOM, which prevents any SSJS in the dialog running. I don't know if that's also an issue with dijit.DialogBox, but I suspect it could be. Jeremy Hodge did some code to workaround that.
However, I would strongly recommend using the Extension Library control. Client-side dijit.Dialogs are likely to be much more difficult to code and will not allow any SSJS interaction. I'm not aware of any Dojo properties not available in the Extension Library control, and the Extension Library control also allows you to open or close the dialog both in CSJS or SSJS. It also allows you to specify an area to refresh on close.
In terms of the properties, preload is there purely to speed up showing. Are you using the refreshOnShow property? This ensures the URL or content is refreshed each time the dialog is shown. The Extension Library chapter on dialogs has a table covering all the properties. You can set the URL to point to another XPage or another web page. This may allow you to use the Dynamic Content control to pass parameters to switch the content that should appear.
In terms of the code behind the OK button, if you use the Extension Library dialog, you have all the functionality you would have outside the dialog.

jQuery Mobile - Dialogs without changing hash

I have a search dialog that I am popping up and filling with jquery templates. After they make a selection I set a value on the current page. As such I don't need hashTags or anything like that, I just need a pop-up dialog that I can open and close programatically. I am currently opening the dialog with
$.mobile.changePage(dialog, { transition: "slide", changeHash: false });
and closing it with
dialog.dialog('close');
However, in certain cases (when the page is navigated to), closing the dialog refreshes the current page.
Is there a better way to interact with this?
Update:
I think I figured out what is going on. So for some reason, jquery mobile usually keeps 2 pages loaded on the DOM - one of which is invisible, you can verify this by running $('[data-role=page]') in the console. One page is the page you're on, the other is the page that you initially navigated to. Not quite sure why they choose to do that, but there you have it.
So they treat dialogs as a page navigation with a different transition even if the dialog is already in the DOM. Therefore, if you go directly to the page and then trigger a dialog, modifying the current page and closing it works fine - because the original page is always loaded in the DOM. However if you go to another page, than navigate to the page that triggers the dialog, and THEN trigger the dialog it destroys the current page so that the pages in the DOM are the initial one and the dialog. In that case it reloads that dialog-launching page entirely and you never get a chance to make any modifications.
Jeez. How do I interact with the jqm dialog widget directly?
You can try two other things. Both should work:
1 set DomChache
How about overriding JQM to keep the page your are firing the dialog from in the DOM? The docs say you can set data-dom-chache and override cleaning the page from the DOM.
If it only happens when you load this page in via AJAX (vs. loading it directly) you could make DOM-keeping dependend on your trigger page having data-page-external, assign DOM-chache="true" only when the dialog is openend and remove it again once the dialog is closed.
2 override JQM
I had the same problem you described and got it to work like this (requires hacking into JQM though...):
// inside transitionPages function
if ( !$(toPage).jqmData('internal-page')
{fromPage.data( "page" )._trigger( "hide", null, { nextPage: toPage } );}
}
My problem was that pagechanging to certain pages (same as dialog) caused the preceding page (where the dialog fired from) to be removed from the DOM, so I had a blank screen (when trying to go back). I added data-internal-page="true" to the pages, which should keep the preceding page intact and added the if-clause in JQM.
So now pageHide (and DOMcleanup) only fires, if I'm not going to a page labelled with data-internal-page="true"
Cheers!
I think I was having a similar problem. What I wanted to do was based on certain parameters, pop a dialog window on load (with that content on the same page), which they can close and view the page that loaded.
I could get it to pop on load using load, or the pageshow events, but when I clicked close that sent you back to the previous page in history, instead of just closing the dialog.
//target your 1st page content, here its id=success
//the modal content is in a page id=dialog and data-role="dialog"
$('#success').live('pageshow',function(){
window.setTimeout(function(){
$.mobile.changePage('#dialog','pop',false,false);
},1);
}
Its a hack, and just allows the page load to beat the dialog so it gets stuck in history. Then the default dialog close behavior for the dialog works as expected. Talk about a PITA, if they took a little more for the JQuery UI dialog it would have made things a ton easier.
And regarding your question: Have you looked at Jquery Mobile Actionsheet plugin
If you don't really require a page to be loaded, that should be ok.
Also helpful could be Cagintranet iPad popover, although you have to tweak the design to be fullscreen on mobile devices. If you require CSS/Jquery to do that let me know (I'm using this in a JQM plugin I'm writing)
Hope that helps.

Resources