How do I change the default XML generated for a blank XPage? - xpages

The default XML generated when a new XPage is created looks like thi
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
</xp:view>
but when you add new components from the extension library and other palette items the view xsmlns namespace changes. It also reformats code and screws up any JavaScript and or CSS on the page.
How can I change the default XML created to look more like this and therefore cover my bases when I add new components?
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex"
xmlns:xc="http://www.ibm.com/xsp/custom">
</xp:view>

One possible solution I could come up with would be to create a template in your Eclipse Designer (Preferences > XML > XML Files > Editor > Templates).
Just to test this I created this template:
xmlns:xe="http://www.ibm.com/xsp/coreex"
xmlns:xc="http://www.ibm.com/xsp/custom"
Saved it under the name "myAddNamespace" with context "XML Attribute" and "Automatically insert" = ENABLED.
If then I create a new xpage, I can go into source view, place my cursor at the end of the default namespace before the closing '>', then type "my", hit - and then select my template to be inserted at the cursor position:
I'm aware that this is NOT what you really asked for, but it's at least something

Tested this on 9.0.1 and it automatically formats the way you mention. For example without touching anything I get this.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xe:dialog id="dialog1"></xe:dialog>
<xc:test></xc:test>
</xp:view>
You can force a reformat pressing CTRL-SHIFT-F (or right click, source->format). You can modify how the formatting works by selecting "File-Preferences" menu option, then select "XML->XML Files->Editor".
I think what you want is "Split Multiple Attributes each on a new line".

Related

how to generate the name of a custom control in it's design definition property

I would like to generate the name of the custom control in it's design definition property. how should i do that?
i tried:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:panel>
<%=this.pageName %>
</xp:panel>
</xp:view>
because this.getPageName() gives you the name of custom control name on custom control's main level.
but that does not work there.
After few tests it seems you can read only custom properties.
Because you write design definition to some specific custom control, you can use:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:panel>
My control name
</xp:panel>
</xp:view>
I am aware of harder maintainability with copypasta coding style.

XPage Page Load and Render Response events running twice

I have a traditional Notes application I am converting to XPages. In this application all of the XPages run the Page Load and Render Response events twice. I made a very simple XPage to illustrate this:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.beforePageLoad><![CDATA[#{javascript:print("db1 beforePageLoad");}]]></xp:this.beforePageLoad>
<xp:this.afterPageLoad><![CDATA[#{javascript:print("db1 afterPageLoad");}]]></xp:this.afterPageLoad>
<xp:this.afterRestoreView><![CDATA[#{javascript:print("db1 afterRestoreView");}]]></xp:this.afterRestoreView>
<xp:this.beforeRenderResponse><![CDATA[#{javascript:print("db1 beforeRenderResponse");}]]></xp:this.beforeRenderResponse>
<xp:this.afterRenderResponse><![CDATA[#{javascript:print("db1 afterRenderResponse");}]]></xp:this.afterRenderResponse>
</xp:view>
When this page is loaded in the browser the following is outputted to the server console:
My xsp settings are:
xsp.ajax.renderwholetree=false
xsp.client.script.radioCheckbox.ie.onchange.trigger=early-onclick
xsp.error.page.default=true
xsp.persistence.mode=file
xsp.resources.aggregate=true
xsp.user.timezone=true
xsp.html.doctype=html
xsp.theme.mobile.pagePrefix=m_
xsp.library.depends=com.ibm.xsp.extlib.library
xsp.theme=Bootstrap3
To ensure this isn't normal behavior I made a new, empty application and created the same XPage in it and set the same xsp settings. The XPage in the new application:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.beforePageLoad><![CDATA[#{javascript:print("beforePageLoad");}]]></xp:this.beforePageLoad>
<xp:this.afterPageLoad><![CDATA[#{javascript:print("afterPageLoad");}]]></xp:this.afterPageLoad>
<xp:this.afterRestoreView><![CDATA[#{javascript:print("afterRestoreView");}]]></xp:this.afterRestoreView>
<xp:this.beforeRenderResponse><![CDATA[#{javascript:print("beforeRenderResponse");}]]></xp:this.beforeRenderResponse>
<xp:this.afterRenderResponse><![CDATA[#{javascript:print("afterRenderResponse");}]]></xp:this.afterRenderResponse>
</xp:view>
When this page is loaded in the browser the output on the server console looks correct:
What would cause these events to execute twice?
After running compact -c (copy style compact) on the application the page load and render response events ran once:
It must have been some kind of corruption issue that was resovled by the compact.

Xpage: programmatically set custom control from session variable?

I am starting to get the dynamic nature of Xpages and am trying to make my coding more streamlined.
I am using the switchFacet cc in my xpages to control which custom control to load, depending on the value in a sessionScope variable.
To keep things simple I made the name of the cc match the sessionScope variable. So I ended up with the following code.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlnsstrong text:xc="http://www.ibm.com/xsp/custom"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xc:ccAppLayout>
<xp:this.facets>
<xc:ccAppNav xp:key="LeftColumn" />
<xe:switchFacet id="switchFacet1" xp:key="facet_1"
selectedFacet="#{javascript:return sessionScope.pageSelected}">
<xp:this.facets>
<xc:cpApp2Title1Page1 xp:key="cpApp2Title1Page1" />
<xc:cpApp2Title2Page1 xp:key="cpApp2Title2Page1" />
<xc:cpApp2Title2Page2 xp:key="cpApp2Title2Page2" />
<xc:cpApp2Title3Page1 xp:key="cpApp2Title3Page1" />
</xp:this.facets>
</xe:switchFacet>
</xp:this.facets>
</xc:ccAppLayout>
</xp:view>
Not to bad, but it seems to me things would be even cleaner if I could just directly set the cc to be the sessionScope variable. That way the code for this Xpage wouldn't have to change between different Xpages. I could get by with just one Xpage.
Is there a way to do this, and is it even a good idea?
Bryan
===============================================
What I am looking for is something like this:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlnsstrong text:xc="http://www.ibm.com/xsp/custom"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xc:ccAppLayout>
<xp:this.facets>
<xc:ccAppNav xp:key="LeftColumn" />
<xc:#{javascript:return sessionScope.pageSelected} xp:key="facet_1"></xc:#{javascript:return sessionScope.pageSelected}>
</xp:this.facets>
</xc:ccAppLayout>
</xp:view>
==============================================================
Knut,
That is a good suggestion, but as you indicated it only loads on page creation.
Is there a different way to do what I want, or is it just easier to leave the code as I originally had it?
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xc:ccAppLayout>
<xp:this.facets>
<xc:ccAppNav xp:key="LeftColumn" />
<xp:include id="include1" xp:key="facet_1">
<xp:this.pageName><![CDATA[${javascript:sessionScope.pageSelected + ".xsp"}]]></xp:this.pageName>
</xp:include></xp:this.facets>
</xc:ccAppLayout>
</xp:view>
You can use <xp:include... and "calculate" custom control's name:
<xp:include pageName="${sessionScope.yourCC}" />
The sessionScope variable has to contain the name of your custom control like "cpApp2Title1Page1.xsp". Don't forget ".xsp" at the end.
Be aware that pageName gets calculated only once at first page load.
I know from your previous question that you'd like to keep the possible pages flexible in a sessionScope variable. Assuming you have a sessionScope variable pages which contains all custom control names as an array then you'd use a repeat and put the xp:include in it:
<xp:repeat
id="repeat1"
rows="30"
var="key"
repeatControls="true"
value="${sessionScope.pages}">
<xp:panel
rendered="#{javascript:sessionScope.pageSelected == key}">
<xp:include
pageName="${javascript:key + '.xsp'}" />
</xp:panel>
</xp:repeat>
It will include all pages defined in sessionScope variable pages but render only the one page with the name contained in sessionScope variable pageSelected.
You'd include the code above instead your switchFacet.
Could you create one custom control to rule them all? A CC that takes the name of the desired CC as a custom property, then renders only the one you want. So shove the switchFacet into a new custom control, e.g. ccAll.xsp:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xc="http://www.ibm.com/xsp/custom"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xe:switchFacet id="switchFacet1" selectedFacet="#{javascript:return compositeData.ccName}">
<xp:this.facets>
<xc:cc1 xp:key="cc1" />
<xc:cc2 xp:key="cc2" />
<xc:cc3 xp:key="cc3" />
</xp:this.facets>
</xe:switchFacet>
</xp:view>
Add a custom property of ccName to the custom control using the "property definition" tab in the CC's properties.
Then add that to your XPage and pass in the sessionScope variable.
<xc:ccAll ccName="#{javascript:return sessionScope.pageSelected}"></xc:ccAll>
A while ago I have created a component to switch custom controls on-the-fly. The code is available at github:
https://github.com/hasselbach/domino-ccinjector
The component can inject custom components whenever you want: during a partial refresh or depending on a variable.

Using design definition for computed properties

I cant find a solution for this problem. I am using design definitions for almost all my controls.
They are working fine the only problem i have is that if i am computing one of the properties i cant use the property anymore in the design definition. It will create a text in red and the xpages will prompt some error messages.
Is there a way to ask if the property is computed and show a standard text instead.
This is the design definition.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:inputText type="text" value="<%=this.field_name %>"></xp:inputText>
</xp:view>
Whenever the value of the property field_name is computed in the custom control it brings up that error.
Anybody any ideas?
When I insert the Field custom control with a static text value for field_name, the design definition will display the field_name properly.
<xc:Field field_type="text" field_name="myfield_1"></xc:Field>
If I insert the Field custom control with a computed text value for field_name, it doesn't:
<xc:Field field_type="text"><xc:this.field_name><![CDATA[# {javascript:"myfield_"+#Text(1)}]]></xc:this.field_name>
</xc:Field>
Make sure field_name is the exact name of the property passed in as CompositeData. For example, I was able to reference the string property 'create' to create the image of field this way:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:inputText value="<%=this.create%>">
</xp:inputText>
</xp:view>
So, I suspect it's a typo, a missing property, or not a string.

Unable to set elements in an Application Layout control (XPages)

Ok, I have two custom controls:
MainLayout: Contains an Application Layout control (from the Domino extension library)
Section1: Contains a section with a header and a few items
Now I create a new XPage, and drag the MainLayout control on it.
Now I want to drag Section1 to the page, and connect it to LeftColumn area of the MainLayout... which seems like something trivial, but I can't get it to work for some reason.
When I drag the section1 control to the leftColumn area, the component is always getting inserted at the top of the page. The little pencil-icon next to "LeftColumn" seems decoration-only to me, because no matter if you left-click or right-click on it, nothing happens...
How is this supposed to work?
Update:
This how my xpage looks like after adding the MainLayout control:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
<xp:this.resources>
<xp:styleSheet href="/custom.css"></xp:styleSheet>
</xp:this.resources>
<xc:MainLayout></xc:MainLayout>
</xp:view>
XML of the MainLayout custom component:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex"
xmlns:xc="http://www.ibm.com/xsp/custom">
<xe:applicationLayout id="applicationLayout1">
<xe:this.configuration>
<xe:oneuiApplication titleBarName="Test"
placeBarName="Server1" legalText="YadaYada">
<xe:this.footerLinks>
<xe:userTreeNode label="User 1"></xe:userTreeNode>
</xe:this.footerLinks>
<xe:this.bannerUtilityLinks>
<xe:loginTreeNode label="Login 1"></xe:loginTreeNode>
</xe:this.bannerUtilityLinks>
<xe:this.placeBarActions>
<xe:basicContainerNode label="Select server">
<xe:this.children>
<xe:basicLeafNode label="Server1"></xe:basicLeafNode>
</xe:this.children>
</xe:basicContainerNode>
</xe:this.placeBarActions>
</xe:oneuiApplication>
</xe:this.configuration>
</xe:applicationLayout>
</xp:view>
I also have a custom where i use the application layout.
in my custom control I have above the configuration tag the following code
And in my XPage which use my custom layout I referer to my LeftColumn editable area by the following code

Resources