How to pass and display a custom control in another custom control - xpages

I am creating an application where I want to add data to a form in a wizard format. I will have a series of modal dialogs that step through the data entry process. I am using the Bootstrap modal dialogs. I intend on saving each step to a managed bean. The application needs to work on all devices, which is why I am doing it this way.
I am trying to create a single custom control to hold the modal window, and then pass the window title, mainContent, button title to the control using custom properties. The window title, and button title work fine. The "mainContent" property contains the XML code for the custom control to display in the window. My question is how to I make the control display the actual custom control content vs the XML string of the custom control name. My goal is to make a reusable snippet.
I have tried using 'Include Page' which makes the whole xpage disappear. I have tried using the 'dynamicContent' control but have been unable to get it to work. There is a very distinct possibility I am not using that control correctly. I left that code in there. Sidenote: xc:layout on the xpage is my Bootstrap layout that I don't think factors in.
XPage code - all that is there is calling the modalWindow custom 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">
<xc:layout>
<xc:modalWindow button_title="Save and Continue to Step 2"
window_title="Create New PO - Step 1 of 7">
<xc:this.mainContent><![CDATA[<"xc:NewPO_Step1 />"]]></xc:this.body>
</xc:modalWindow>
</xc:layout>
Here is the code for the custom control "modalWindow"
<?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">
<a href="#myModal" role="button" class="btn" data-toggle="modal">
Begin Creating New PO
</a>
<div id="myModal" class="modal hide fade" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">
×
</button>
<h3 id="myModalLabel">
<xp:text escape="true" id="computedField3"
value="#{javascript:compositeData.window_title}">
</xp:text>
</h3>
</div>
<div class="modal-body">
<xe:dynamicContent id="dynamicContent1"><xp:text escape="true" id="computedField2" value="#{javascript:compositeData.mainContent}">
</xp:text><xp:this.facets>
</xp:this.facets>
</xe:dynamicContent>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">
Cancel
</button>
<button class="btn btn-primary">
<xp:text escape="true" id="computedField4"
value="#{javascript:compositeData.button_title}">
</xp:text>
</button>
</div>
</div>

You can use "Include Page" adding ".xsp" to the name of custom control:
<div class="modal-body">
<xp:include id="include1">
<xp:this.pageName><![CDATA[${javascript:compositeData.mainContent + ".xsp"}]]></xp:this.pageName>
</xp:include>
</div>
Add mainContent="nameOfYourCustomControl" to modalWindow call and you have the flexibility you are looking for:
<?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">
<xc:modalWindow button_title="Save and Continue to Step 2"
window_title="Create New PO - Step 1 of 7" mainContent="step1">
</xc:modalWindow>
</xp:view>
In this example you have to create a custom control "step1" which contains all the content.

Related

simple hide/show behavior....best practice?

It is embarrassing that I am having these 'newby' questions a lot, as I am late to the XPages rodeo for real work. Please be gentle.
This is BASIC functionality, needing to have a field that is initially hidden on new pages, until another combobox gets set to a certain value (think of any generic 'other' field, that is only displayed if "Other" is selected in the main field.).
Behold..my panel:
<xp:panel
id="mod"
rendered="#{javascript:document1.getItemValueString('approval') === 'modify'}">
<div class="container">
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="modification">
Describe modification
</label>
<xe:djTextarea
id="modification"
styleClass="form-control"
cols="185"
rows="25">
</xe:djTextarea>
</div>
</div>
</div>
</div>
</xp:panel>
then, my combobox (see onchange):
<xp:comboBox
id="approval"
styleClass="form-control"
style="width:400px;">
<xp:this.onchange>
<![CDATA[XSP.partialRefreshPost("#{id:mod}");]]>
</xp:this.onchange>
<xp:selectItem
itemLabel="Select one"
itemValue="">
</xp:selectItem>
<xp:selectItem
itemLabel="Approve"
itemValue="approve">
</xp:selectItem>
<xp:selectItem
itemLabel="Modify"
itemValue="modify">
</xp:selectItem>
When I change the value of the combobox in the browser, I get this error in a dialog:
I have a feeling that once I get a better grasp on how to deal with SSJS and element IDs, I will be much more productive. If anyone has a link to an article that explains this well, I would love to know it.
After all that rambling, question is how do I get this partial refresh to work?
As always, your feedback is truly appreciated.
The problem is the "mod" panel is not initially rendered so its not available/visible to the onchange event.
Put the "mod" panel in a "modParent" panel and make that the target of your partialRefresh.

How to make sections in Xpages look like this

I am baffled. In the oneUI 3 documentation page there is a nice section. It looks like this:
I create a new db and set the theme to 3.0.2 and put in the code below, and it looks nothing like what I am trying to produce.
How can I use the OneUI documentation to reproduce what I see there?
<?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">
<xp:section id="section1" header="Header"
headerStyle="lotusSectionHeader2">
</xp:section>
</xp:view>
Good point. It looks like this:
Note, the "Widget Container" control (xe:widgetContainer) in the XPages Extension Library is roughly equivalent to the OneUI Section control. You can see that in Extension Library Demo App at: XPagesExt.nsf/OneUI_WidgetContainer.xsp
It might be a better fit to design the page using that control rather than the xp:section control.
Also, in the OneUI 3 doc that you link to, on the right of the page, 25% down the page, there's a Theme dropdown where you choose "default" or "gen2".
The behavior you're asking for looks like the "gen2" behavior (seems like OneUI 2),
while your screenshot of what it looks like is closer to the "default" (OneUI 3) behavior.
You may want to investigate how to enable the gen2 appearance.
If you paste this code from the documentation does it work? If it does then you need to move the standard html elements to xpage elements.
<!-- section is an HTML5 element. Use div if you are using HTML4. -->
<section class="lotusSection2">
<!-- header is an HTML5 element. Use div if you are using HTML4. -->
<header class="lotusSectionHeader"><div class="lotusInner"><a class="lotusArrow" role="button" aria-expanded="true" aria-controls="sectionBodyID" href="javascript:;" title="Collapse section"><img class="lotusTwistyOpen" src="../../css/images/blank.gif" alt="" aria-label="Collapse section" /><span class="lotusAltText">▼</span></a><h2 class="lotusHeading">Section Header</h2><a class="lotusIcon lotusActionIcon" href="javascript:;" role="button" aria-haspopup="true" aria-owns="[menuID]"><img src="../../css/images/blank.gif" alt="" /><span class="lotusAltText">Actions</span></a></div></header>
<div id="sectionBodyID" class="lotusSectionBody">
<div class="lotusChunk">Data goes here....</div>
<header class="lotusSubheader"><a class="lotusArrow" role="button" aria-expanded="true" aria-controls="subsectionID" href="javascript:;" title="Collapse section"><img class="lotusTwistyOpen" src="../../css/images/blank.gif" alt="" aria-label="Collapse section" /><span class="lotusAltText">▼</span></a><h3 class="lotusHeading2">Subsection</h3></header>
<div id="subsectionID" class="lotusSubsection">
More data goes here....
</div>
</div></section><!--end section-->
As Maire points out, the Widget Container control does what you want using the following code:
<xe:widgetContainer id="widgetContainer1"
titleBarText="Section Header" collapsible="true"
style="width: 300px;">
<xe:this.dropDownNodes>
<xe:basicLeafNode label="test1"></xe:basicLeafNode>
<xe:basicLeafNode label="test2"></xe:basicLeafNode>
<xe:basicLeafNode label="test3"></xe:basicLeafNode>
</xe:this.dropDownNodes>
More data here...
</xe:widgetContainer>
But as she points out, the look & feel you posted is for the Gen2 theme, which isn't implemented in XPages. So what you get is this:

Set "autocomplete" property of Xpages form

I need to set the 'autocomplete' property of the form in my Xpage. I know how to set it on fields, but I need to completely prevent the browser from autofilling my forms.
Add <xp:form> to your XPage and set property autocomplete="off":
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core">
<xp:form autocomplete="off">
<xp:inputText>
...
</xp:inputText>
...
</xp:form>
</xp:view>
This will render the <form...> with autocomplete property:
<body class="xspView tundra">
<form id="view:_id2" method="post" action="/XPages/Stacky2.nsf/a.xsp" class="xspForm"
enctype="multipart/form-data" autocomplete="off">
This prevents the browser from autofilling of all fields on your form.

SharePoint 2010 - RichImageField not displaying in display mode

I am currently doing some research into SharePoint Page Layouts and building pages based on those layouts.
I currently have a page layout containing several RichImageFields and RichHtmlFields, but it seems that the first RichImageField is not displaying (doesn't even render out anything).
As far as I can see, he's the same as the others:
<div id="headerImage">
<PublishingWebControls:RichImageField id="HeaderImage" FieldName="HeaderImage1" runat="server"/>
</div>
<div id="middleContent">
<div id="left">
<div id="about">
<fieldset>
<legend>About</legend>
<PublishingWebControls:RichHtmlField ID="About" FieldName="AboutMedicInfo1" runat="server"/>
</fieldset>
</div>
<div id="items">
<h1>
<SharePointWebControls:FieldValue FieldName="ItemsTitle1" runat="server"/></h1>
<PublishingWebControls:EditModePanel runat="server" CssClass="edit-mode-panel">
<SharePointWebControls:TextField runat="server" FieldName="ItemsTitle1" />
</PublishingWebControls:EditModePanel>
<div id="Item1">
<fieldset>
<legend>
<SharePointWebControls:FieldValue FieldName="Item11" runat="server"/></legend>
<PublishingWebControls:EditModePanel runat="server" CssClass="edit-mode-panel">
<SharePointWebControls:TextField runat="server" FieldName="Item11" />
</PublishingWebControls:EditModePanel>
<PublishingWebControls:RichHtmlField ID="Item1" FieldName="Item1Content1" runat="server"/>
</fieldset>
</div>
<div id="Item2">
<fieldset>
<legend>
<SharePointWebControls:FieldValue FieldName="Item21" runat="server"/></legend>
<PublishingWebControls:EditModePanel runat="server" CssClass="edit-mode-panel">
<SharePointWebControls:TextField runat="server" FieldName="Item21" />
</PublishingWebControls:EditModePanel>
<PublishingWebControls:RichHtmlField ID="Item2" FieldName="Item2Content1" runat="server"/>
</fieldset>
</div>
</div>
</div>
<div id="center">
<div>
<PublishingWebControls:RichImageField id="HighLight1" FieldName="HighLight11" runat="server"/></div>
<div>
<PublishingWebControls:RichImageField id="HighLight2" FieldName="HighLight22" runat="server"/></div>
<div>
<PublishingWebControls:RichImageField id="HighLight3" FieldName="HighLight32" runat="server"/></div>
</div>
<div id="right">
<div id="report">
<PublishingWebControls:RichHtmlField ID="Report" FieldName="Report" runat="server"/>
</div>
<div id="webparts">
<WebPartPages:WebPartZone runat="server" Title="Rechtsonder" ID="BottomRightControl"><ZoneTemplate></ZoneTemplate></WebPartPages:WebPartZone></div>
</div>
</div>
</div>
The funny thing is that I'm perfectly able to see the image when I'm in editing mode and when I'm viewing the Page Library items (after I added the specified field to the view).
Does anyone have any experience with this? Feel free to ask further questions if I might be unclear.
Okay, I should have checked before posting my initial question. It turned out that my problem was because I was using the Page content type, instead of the Article Page or Welcome Page content types. The Page CT doesn't have the field that the image was looking for.
What I find really interesting is that it still let me select the image AND it stored the value somewhere... even though there was no official field for it. I suspect that the field in the library is there, since you would need it for your other content types.
Anyway, hoping that someone else may find this useful.
Make sure that you don't miss the two properties RichText="TRUE" and RichTextMode="FullHtml" of the image field definition to be like:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field
ID="{4ea31e74-f59d-4ddf-863c-607a01735f65}"
Name="pls_H2_2_Image"
DisplayName="Titel 2 Bild"
Type="Image"
Required="FALSE"
RichText="TRUE"
RichTextMode="FullHtml"
Group="Custom">
</Field>
</Elements>
I faced this issue before and this solution did it properly.

How do I hide a menu item with an <li> tag in XPages

I have a traditional menu that us based on this convention
<ul>
<li><xp:link>menu link 1</xp:menulink></li>
<li><xp:menulink>menu link 2</xp:menulink></li>
</ul>
I want to selectively render the menu link 2 based on some logic.
I can render the <xp:link> fine but as the <li> is a HTML tag rather than an XPages Tag the rendering cannot be controlled.
I noticed that there is a tagName property for <xp:text> but not for <xp:link>.
see : http://xpagesblog.com/XPagesHome.nsf/Entry.xsp?documentId=4EB7314545EE0C19852578CB0066CE4C
What is the easiest way to manage this without using repeats etc ?
You can also wrap the entire <li>...</li> tag in an <xp:panel> tag that has a rendered script on it. Don't give the xp:panel an ID and no extra code is sent to the browser.
If you are using the Extlib or UP1 then you can also use the <xe:listcontainer> tag. It renders each direct child entry as a list item so you would end up with code similar to..
<xe:listcontainer>
<xp:link> ... </xp:link>
<xp:link rendered="renderscript"> ... </xp:link>
<xp:link> ... </xp:link>
</xe:listcontainer>
In this case there is no need for you to add the <ul> or <li> tags in the code, the ExtLib will look after that for you.
Instead of the LI tag, use a panel and set the tagName to "li" (new since 8.5.3):
<ul>
<li>
<xp:link>menu link 1</xp:link>
</li>
<xp:panel
rendered="#{test == true}"
tagName="li">
<xp:link>menu link 2</xp:link>
</xp:panel>
</ul>
I have used xp:span in the past and it has worked fine.
<xp:span>
<xp:this.rendered><![CDATA[#{javascript:document1.isEditable()}]]></xp:this.rendered>
<li>YOUR TEXT HERE</li>
</xp:span>
This works:
<ul>
<li>Static item 1</li>
<xp:text escape="false" id="computedField1" tagName="li" rendered="false">
<xp:this.value><![CDATA[#{javascript:'menu link 2'}]]></xp:this.value>
</xp:text>
<li>Static item 3</li>
</ul>
You can of course compute the rendered tag on xp:text.
If your not worried about whether or not the code shows you can always just change the class on the li systematically using ssjs
<ul>
<li class="#{javascript:return myclassname;}"><xp:link>menu link 1</xp:menulink></li>
<li><xp:menulink>menu link 2</xp:menulink></li>
</ul>

Resources