Is there a way to use a javascript object as a custom control property? - xpages

I'm currently building a custom control to be used as an application's view navigator (classic OneUI style). First of all: this is a 8.5.3 based project, and unfortunately there's no way to use Extlib stuff or other extensions / plug-ins. So we have to build all the tricky stuff ourselves using only what came "out-of-the-box" with 8.5.3.
I'd llike to build my navigator using a repeat control containing <xp:link> controls. Datasource could be an array of javascript objects where each single object would look like this:
var navEntry = {"entryLabel" : "label-of-link",
"entryTarget" : "target-url-of-link",
"entryStyle" : "style-to-emphasize-selected-link"}
Each array element then would describe a single navigator entry.
Since the navigator will be used in all possible "DominoView" Xpages it yould make sense to build the array of JS objects at the Xpage level and then pass that info into the custom control.
I'm aware that there are multiple ways to do this, and one could be "Custom Control Properties". If there was a way to pass my JS object array.
(Hope I could make clear what I'm trying to do here...)

That object looks like a HashMap to me really. You should be able to pass that in to a custom control via custom property if you use the type java.util.HashMap I'd think. You'll need to type it in I'm sure. I've passed custom objects in by using java.lang.Object.

The custom control will get loaded during the Page Load event, and usually properties have to be available at that point. If they're loaded during the Render Response phase, that's too late. So your SSJS object will need to be Compute on Page Load.
To use contents of a repeat control, you would need to set repeatControls=true, otherwise the repeat is only built during render response. Until then it's just a single set of controls with no data in them. However, Im pretty sure repeatControls="true" means you only get the number of rows you define. You can't change it via a pager.

You can manually define the type of the custom property. For a standard SSJS Object you use "com.ibm.jscript.std.ObjectObject", for a SSJS Array you use "com.ibm.jscript.std.ArrayObject" etc. As editor for the custom property, I set the string editor ("String value").

Related

Passing properties to a custom control using xp:include

When using an Include Page to dynamically load a custom control onto an XPage, is there a way to pass custom property values to the custom control as part of the include?
Peter, the include page doesn't load a custom control but another XPage. Pages don't have properties. However... the page becomes part of the component tree, so you have access to its contained controls using getComponent("thecomponent").getParameterMap (Off my head, might be called slightly different)
Does that help?

Conditional Client Side Validation?

I have a radio button group that gets it's values using an #Dblookup. In addition to the name to appear in the radio button group, the document also has a field to determine if another field on the xPage should be displayed or not.
If the field is displayed then it should be required.
I can do the conditional validation just fine in SSJS using an #DbLookup to lookup the document selected in the radio button group.
But I would like to be able to do it CS so it is faster and so it looks like my other validations. Is there anyway to do this?
If a field is not rendered then the node will not exist in the DOM. Your CS javascript would need to examine the DOM and look for the node, normally by looking for a specific ID. As Xpages changes the ID's sent to the browser your validation function would either need to be computed so it would know what ID to look for or you would need to look for it in some other unique way ( like add a css class name to just that field and then do a DOM search for nodes with that class name )
Once you can determine if the field has been rendered then you can run your usual CS validation routine against the other field.
If you're using client-side validation throughout your app, setting the required property on the field should achieve what you need.
If not, it may be worth looking at the Extension Library Dojo Validation Text Box. All the Extension Library Dojo control run client-side validation, even if validation is set as server-side at application level. Bear in mind that for the Dojo Validation Text Box, just setting the required property is not enough. You need to add more specific validation.
After that, the key is to ensure the partial refresh event on your radio group is set to skip validation. I haven't tried, but I believe that should achieve what you need.

developing library controls for xpages

I' working on a library control for Xpages and need some help in creating.
I would create a control which reads a configuration file and creates controls in a table, controls like Editboxes, checkboxgroups and so on.
so and now to my questions:
could I initiate controls from the Exlib or must I implement them all by my self?
if I could use them from the Exlib could anyone explain me how?
I hope its clear what i mean if not please ask me for further informations.
When creating your own components, if you're closely replicating some behavior that is already in an extension library component, I highly recommend you extend that component and just add what's needed to accommodate your different functionality. This makes things much easier and you don't have to code around every little scenario that the component might be placed in.
But, if you are developing a component that is nothing like any of the extension library or core components then just ensure your component extends UIComponent or UIComponentBase. If going this route, you'll also need to create your own renderer which extends Renderer. This is what will build the on-screen representation of your component. Again, if there's already something in the core components or extension library components that closely mimics what you need then make your renderer extend that renderer. Also, don't forget to include the renderer definition in the faces-config file and the component definition in the xsp-config file or your component won't work.
As for initiating controls from the extlib.... I assume you mean can you inject them onto the page at runtime. If so the answer is absolutely yes. To add an input text field to the page where there is a container (i.e. panel, div, span, whatever) with an ID of "someContainer"
XspInputText input = new XspInputText();
input.setValue("someValue");
input.setId("someID");
UIComponent container = FacesContext.getCurrentInstance().getViewRoot().findComponent("someContainer");
container.getChildren().add(input);
To see the api for all of the core and extension library components take a look at the XPages Controls Documentation. For a more complete tutorial on creating your own components take a look at my blog for creating a custom component inside an nsf, the steps are pretty much the same for putting them into a library:
Part 1,
Part 2 and there is an example database in the Part 2 post.

libary control for Xpages and using ssjs for defaultvalues/validators

I' working on a libary control for Xpages and need some help in creating.
I would create an control wich reads a configuration file and creates controls in a table, controls like Editboxes, checkboxgroups and so on.
Ive Build my control like Keith Strickland
in his Bolg entry
http://xprentice.gbs.com/A55BAC/keithstric.nsf/default.xsp?documentId=82770C11FA7B9B21852579C100581766
so and now to my queststion:
I would store in my configuration ssjs code for computing a defaultvalue or an validation
but how could I compute the ssjs?
the automatic generated code from the Designer uses a PageExpressionEvaluator Object but I couldent create one by my self.
someone an Idea?
You can use the ExpressionEvaluatorImpl class instead:
com.ibm.xsp.page.compiled.ExpressionEvaluatorImpl( facesContext )

XPages Rich Text Component

Is there any chance to get the html content (mime) from a rich text component without any datasource. I would like to grab the content from the field like this. getComponent("FieldName").value but this dosen't work.
thanks.
You can bind the control to a scoped variable; for example, #{viewScope.comments}. You can then retrieve the submitted value from the scope instead of from the component itself; for example, viewScope.get("comments").
Alternatively, you can set a dataContext variable to a JS expression, e.g. <dataContext var="richText" value="#{javascript:return {value:""};}" />. Then you can bind the control to #{richText.value} and retrieve it via the same expression.
And, of course, you could define a managed bean and bind the control to one of its properties. This option provides the most flexibility, but isn't quite as simple as the other two options above.
The solution for my problem is
getComponent("FieldName").getValue()
thanks for your help.

Resources