Using Expression Language in SSJS - xpages

When referring to a bean property (id) in EL, I use #{bean.id}.
I now have a requirement to prepend that data with some static text. I do this by using SSJS: "sometext" + bean.getId();
Is there a way that I can use the EL notation in SSJS? e.g "sometext" + #{bean.id};
I realise that in this example it is not hugely different, but when requesting more complex or nested properties, I think it would come in useful.

Though you could theoretically execute arbitrary EL inside SSJS blocks, it's too ugly to be worth doing (probably something like facesContext.getApplication().createValueBinding("#{bean.id}").getValue(facesContext)).
You can, though, mix binding types in the same property when what you want to do fits the needs. For example: <xp:text value="#{javascript:doFoo()} some other text #{bean.id}"/>. That would fit the specific case of your question, but may not fit the larger need in practice.
A related technique that fits other situations is to use load-time SSJS (or other) bindings in order to generate run-time EL bindings. For example: <xp:fileDownload value="${javascript:'#{' + compositeData.dataSource + '.' + compositeData.fieldName + '}'}"/>. Again, that is situational, but can be useful.

Related

how to compute the variable name of a session scope variable for a repeat control

I would like to compute the variable name of a sessionScope variable that I use as the data binding source for a xp:repeat control.
I notice the diamond to compute the variable name is not there. Perhaps it is possible via another way?
In theory it should be. Scoped variables are Maps. A dominoDocument datasource works as an object in the similar way - document1.myField runs as document1.getValue("myField") and document1.setValue("myField"). I know there are ways to bind to a computed field name, I think in a Custom Control, for example, getting a field name passed in would be document1[#{compositeData.passedField)]. So a similar process for binding to a scoped variable - sessionScope[#{myComputedVariable}] should, in theory, work.
There are 2 approaches, one favored over the other, but the other forced onto you in case the name you have to concatenate strings in order to have the final variable name (as it seems to me since you are speaking of a repeat control):
EL approach
<xp:repeat value="#{something}" var="whatever">
<xp:text value="#{sessionScope[whatever]}" />
SSJS approach
<xp:repeat value="#{something}" var="whatever">
<xp:text value="#{javascript:sessionScope.get('somePrefix' + whatever)}" />
Problem of the second approach is that you can't do proper data binding with it if it's an input field, only for display.
If you need proper data binding then I suggest, although inelegant - but I don't have your full picture, a backing bean that concatenates your string so that it can be served through EL ready for use.

Define the multiplicity of an association by an attribute

In the example I made every object of the type "Folder" have an array of type "File" with the name "content" a size of "n" as a private attribute (just saying my understanding of it to make sure that I am not already wrong there). That's how I see it in most examples but I never understand what "n" now is. Is it another attribute of the "Folder" object or is it something that we specify in another part of an UML diagram or something else completely?
What I am trying to achieve is that every object of the type "Folder" has an additional attribute that specifies the size of the "content" array.
Of course, you can not only write 0..*, but use any concrete number, too. If that number has some external definition, you can use there n, as you have it.
The external definition means "not defined by class diagram elements, except notes". Everything that you need to be said on a class diagram page, but can't because of the UML limitations, should be put in a note.
So, n can be defined in appropriate note on the page or in some different document or both.
As #Kilian had mentioned, in the case of some more complicated dependencies of such variables you can use constraints. This way seems to me the most powerful.
But if n has no objective definition or dependency, but is a simple variable that can have any meaning, then it will be correct to use a rule, such as 0..*, or 1..*, or maybe 3..5, according to the reality you are working with.

Can i get all components of an xsp document in xpages?

I have a simple document with 3 fields and 1 rich text field. I also have an xpage with 3 simple edit box controls and 1 rich text. The name of my NotesXSPDocument is document1.
Question 1:
Can i get a vector with all the controls of the xsp document? for example, instead of using getComponent("fld1"), getComponent("fld2") ... etc, can i use something like getAllComponents() or document1.getControls()? These methods do not exist of course so i am asking if there is a way to do it. I know i can get all items of a document (not XSP) by calling document1.getDocument().getItems(). IS there anything similar for xsp?
Question2:
Lets say we can get a vector as i described above. Then if i iterate through this vector to get each control's value, is there a method to check if it is rich text or simple text field?
Technically, yes, but not readily and this is one of those situations where there's likely a better way to approach whatever underlying problem it is you want to solve.
Nonetheless, if you're looking to get a list of inputs on the page, XspQuery is your friend: http://avatar.red-pill.mobi/tim/blog.nsf/d6plinks/TTRY-96R5ZT . With that, you could use "locateInputs" to get a List of all the inputs on the page, and then check their value method bindings to see if the string version is referencing your variable name. Error-prone and not pretty, but it'd work. Since they're property bindings, I don't think the startsWith filter in there would do what you want.
Alternatively, you could bind the components to something in a Java class from the start. I've been doing just such a thing recently (for a different end) and initially described it here: https://frostillic.us/f.nsf/posts/my-black-magic-for-the-day . The upshot is that, with the right cleverness for how you do your binding="" property, you could get a list of all the components that reference a property of a given object.
As for the second part of the question, if you DO get a handle on the components one way or another, you can check to see if it's a rich text control by doing "component instanceof com.ibm.xsp.UIInputRichText".
A bit complex but yes. facesContext.getViewRoot() is an UIViewRoot object so it has List<UIComponent> getChildren() method which returns its children.
However, since it's a tree-structure, some of its children will have additional children components. You have to traverse the entire tree to build a list of components you want to see.
For types, you can decide what type a component is by its class. For instance, UIInput is a text box, etc.

In RDFa, difference between property="" & rel="", and resource="" & about=""?

I am currently teaching myself RDFa Core 1.1 after successfully learning RDFa Lite rather easily. Straight to the point, I can't understand two things: the difference between property and rel, and the difference between resource and about.
Please explain to me in simpler terms than the spec :)
property vs. rel:
Both attributes indicate a predicate of a triple, e.g. rel="http://purl.org/dc/terms/creator, which is the predicate ... has as a creator: ....
The difference is, from where they take their object. Slightly simplified, the rules for property are: The object is taken ...
from a valid content attribute or, if this is not present in the tag,
(if no datatype attr is present in the tag:) from a valid resource attribute or, if this is not present in the tag,
(if no datatype attr is present in the tag:) from a valid href attribute or, if this is not present in the tag,
(if no datatype attr is present in the tag:) from a valid src attribute or, if this is not present in the tag,
from the inner content of the element started by the tag.
Slightly simplified, rel differs in two aspects:
It takes its object only from a resource or a href or a src attribute.
It takes its object not only from an attribute of the same tag, but may also take it from descendant tags. The whole mechanism is called "chaining": "This is the main difference between #property and #rel: the latter induces chaining, whereas the former, usually, does not." 1 Usually, but property can induce chaining if used with typeof (cf. 2).
about vs resource:
about is the attribute to indicate the subject of a triple. The rules for resource are more complicated: It may indicate a subject or an object, and chaining plays a role here, too.
IMHO, chaining is the most complicated and confusing part of RDFa (and does not give you more than syntactic sugar). I would avoid chaining. This is possible by avoiding the attributes rel, rev, resource and typeof, which brings some further simplification at the same time. Thus, I use only the following attributes:
about for the subject
property for the predicate
content or href or src (or the inner content of the element) for the object, following the rules outlined above
lang for a language tag for object literals, e.g. lang="en"
datatype for a datatype tag for object literals
prefix (but only once in a document), so that I can abbreviate URLs by prefixing, e.g. property="dc:creator"
vocab (rarely and at the most once in a document), so that I can abbreviate URLs implicitly, e.g. property="creator".
(And I use the tag <base href="..."> to indicate the URL base value of the document.)
This is a strict, safe, easy-to-use and easy-to-parse subset of RDFa and allows to express any triple you want.
I would personally recommend to ignore / avoid using rel and about, they are not really necessary to write RDFa if you follow the rule of thumb that you should not try to be too smart by stuffing as many attributes as possible in a given HTML element. There are around for backward compatibility reasons. The other attributes from 1.1 are worth learning though: content and datatype.
Stephan's advice is in general conformance with RDF Lite 1.1, which does not include #rel or #about for precisely these reasons.
Another good rule of thumb is to not try to include markup of more than one entity on a given element, which was often an example of specifying an images license.
#property and #rel are very similar to each others, but served different purposes in RDFa 1.0, but this was confusing, even for experts. (Formerly, #rel was used for specifying objects which are other nodes, and #property was used for specifying literal values. While there are some remaining differences, but sticking to non-clever markup, you can do everything with #property that you could do with #rel.
Similarly, #about can be avoided to just use #resource. The difference is that #about sets the current subject and #resource the current object, but for child nodes the parent object (taken from the parent's current object becomes the current subject. There were another minor differences concerning the presence of #typeof, but if you only use #resource, it pretty much does what you want.
To summarize the best practices from RDFa Lite 1.1 you can also check out the RDFa 1.1 Primer:
stick to #vocab, #prefix, #property, #resource, and #typeof
avoid making more than one statement in a given element

How to import two cc both contain compositeData?

I do not know that the question is right? Please do not take it your mind if it is crazy. Actually I am working on xpages application. There I need to do two things, that I want to add the picklist functionality and binding the dynamic data like field_1,field_2,field_3, ... upto n depands on customer choice.I am using the composite data for both custom controls. I can remove the picklist control's composite data and also I can do it by passing the scope variables. But that takes more time than the composite data.
I did not get any error. But the binded documents is not saving.
Is it possible to import the CCs that are having composite Data?
Code for first CC:-
<xc:viewpicklist datasrc="view1" dialogID="dialog1" dialogWidth="700px" dialogTitle="Pick this field value!!!">
<xc:this.viewColumn>
<xp:value>0</xp:value>
<xp:value>1</xp:value>
<xp:value>2</xp:value>
</xc:this.viewColumn>
</xc:viewpicklist>
Code for Second CC:-
<xc:BOM_Partinfo BOM_Partinfo="#{document1}"
TNUM="field#{index+1}" Desc="Desc#{index+1}" quan="Ea#{index+1}"
exp="exp#{index+1}" cap="cap#{index+1}" total="price#{index+1}"
RD="RD#{index+1}" m="manufact#{index+1}"
m_n="manufactnum#{index+1}">
</xc:BOM_Partinfo>
You can read information that is set in the properties of a custom control if it was static in the calling page:
var x = getComponent("yourcomponentid");
x.getPropertyMap().get("parametername");
but you want to propagate a data source from the outer control to the inner control...
You need to plan carefully. If you hand over the data source, then your custom control is dependent on a fixed set of fields in the data source (that would be a parameter of type com.ibm.xsp.model.DocumentDataSource). This would violate the encapsulation principles. So I would recommend you actually hand over data bindings - the advantage: you are very flexible what to bind to (not only data sources, but also beans and scope variables would work then). The trick is you provide the binding name as you would statically type it in (e.g. "document1.subject" or "requestScope.bla" ). In your control you then do
${"#{compositeData.field1}"}
${"#{compositeData.field2}"}
You need one for each field.
You cannot send a document data source to a custom control using composite data parameters.
You can try and use this script instead
http://openntf.org/XSnippets.nsf/snippet.xsp?id=access-datasources-of-custom-controls
Define data source in XP/CC where you want those CCs. Define parameter "dataSourceName" for both CCs. Inside each of them use EL "requestScope[compositeData.dataSourceName].fieldName" everywhere you want to bind to datasource.

Resources