Xpages Null or empty string - components

I am working with xpages components and it is hard for me to quess when the getComponent("comp").getValue() returns null or when returns "" (empty string).
Is there a way to tell? Are there components which return null when other components return ""?

A component will have a null value if the value property has not been assigned. That can happen if the it's bound to a field on a document and that document does not yet have the field, e.g. it's a brand new document. It can also happen if it's bound to a scoped variable that hasn't been set yet.
It's best practice to bind, wherever possible, to the data source rather than go via the component. This way document1.getItemValueString("myField") will return a blank string if myField hasn't been set on document1, as well as if myField's value is "". Also, if in the future youo delete the component comp, the compiler won't (and can't) tell you you're calling that component in SSJS and you'll get a runtime error. If you're using document1.getItemValueString("myField"), it will still work.
Plus, as Tim Tripcony said, it's slower https://twitter.com/timtripcony/status/359532216382001152 and this blog post goes into much greater depth on why to talk to data not components http://www.timtripcony.com/blog.nsf/d6plinks/TTRY-942UPQ

Related

SPServices GetListItems returning field values as "undefined"

I ran across a problem for which I found no documented solution, but inadvertently found the solution myself. So I wanted to document this here for others who may encounter the same problem.
I was using a CAML query within SPServices to retrieve list items, then referencing "ows_{fieldname}" as usual to retrieve the field value for each list item. The field value was reported as "undefined" for all items. I quintuple-checked that I was specifying the proper name of the field and that my query was properly constructed.
I eventually discovered that the fields I was trying to reference were not displayed in the default view of the list. As soon as I changed the list properties to include the fields in the default view, the proper field values were returned within my javascript.
I don't know how much of Sharepoint's underpinnings work, but I was very surprised at my finding because it implies that the SPServices GetListItems method gets its data from the list's default view, not the actual underlying list. I realize I could be wrong in this interpretation, but I imagine others could run into this same problem.
The default, although unreliable, way GetListItems works is that it's suppose to returns all fields displayed on the default list view if you don't specify ViewFields on input. This is unreliable. Although you got it working - now - someone could come along later and change the default view thus breaking your sweet customization. Bummer. :)
I suggest always listing the ViewFields you are interested in on the GetListItems method. This ensures that your will get them if they are set. That's right. You could still get rows with an undefined field. This happens mostly on fields of type Lookup that are not set on a row.
Hope this helps you understand what is going on. Over the years I have created my own wrappers around SPServices to ensure I get back a reference to all fields requested, even if they are not in the response by Sharepoint.
When using SPServices' GetListItems method, be sure that any fields that you reference from the list are included in the list's default view, otherwise an undefined value will be returned.

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.

Siebel read only field problem

I'm trying to make a field read only when a given value is selected from a PickList.
I'm using a flag that is set to Y when the list has that value, and N otherwise.
I created a Business Component User Prop with the name Field Read Only Field: MyField set to the flag.
Thing is, this works with the vanilla component but it wont work on my custom component.
I can't figure out what is going on, the properties of the fields and flag are exactly the same. It should work...
Thanks for any help you can give me.
That user property is only supported on the business component class CSSBCBase and its subclasses. My guess is that you probably used CSSBusComp as the class of your business component. CSSBusComp is actually a superclass of CSSBCBase, and is very minimal and does not support Field Read Only Field. If that's the case, change it to CSSBCBase and you should be good to go.
Other option is that- if the record become read-only when the picklist value is being selected- that you'll need to make the picklist field Immediate Post Changes to be sure the user property is triggered.

Getting value from SPFieldBoolean

How do I get the value from a SPFieldBoolean object? Do I simply cast it to a boolean or do I need to do something further with it?
I am fetching it in an EventReceiver class during an ItemAdded event from properties.ListItem["fieldname"].
If there is a chance the field might not exist (and be null), how do I check for that?
The value is already a bool, you just need to type-cast it. All fields provide values in their native value-type — see also SPField.FieldValueType property that gives you the actual type in case you need to inspect it on runtime.
To make sure the field is contained in the list, just use the SPFieldCollection.ContainsField method on your list's Fields collection.

JSF: How do I include parameters in an action method's return string?

I'm writing an action method that will store a new object in a database. Once this is done, I want to navigate to view that newly created object. To do this, I was planning to include a querystring or some sort of parameter in the return String of the action method, but I can't figure out how. If I append a query string manually, it appears that it's being ignored. Also, manually adding parameters by concatenating strings doesn't seem like a good idea to me. Is it possible to do this in a type-safe manner?
The way I've always handled this is to get a reference to the bean which provides the content for the page you'll be displaying, and just set its properties directly. The navigation string returned from an action method isn't meant for passing parameters, but you don't need it to; all they'd be used for is setting bean properties anyway.

Resources