bookmark_borderYOUFEB: YOUr FEedBack required

I wanna thank to all loyal readers of my blog. I know you’re out there somewhere…

Please get in contact with me.. write comments about my blogs, what you liked, in terms of content, in terms of writing style, what you didn’t like, what you missed.

Let me know who you are and what problems your dealing with…

I know most of you (besides maybe some 20 guys around the world) are struggling with the same issues than I have…

Have you ever wondered if it is possible to keep all code within a LN application in one place? Say ONLY in the java classes?

I believe the interface with drag&drop of fields, clicking on properties, entering attribute values etc. is great, but it’s also a GREAT pain!!!

Who of you has read my post about “do not copy and paste” stuff? Where an xPage wouldn’t behave, just because I copied and pasted and forgot to remove one of those “properties”…

I do envy those guys working with GWT.. they GUIs are so slick, so fast, so adaptable… and as far as I know they application runtime lifecycles are more easy to understand.

Or can you really tell me about the order of execution of all those “events”? Or when the first moment would be where you have a handle to the DominoDocument?

I do understand that most LN applications are just “little” adaptations of document mgmt templates, discussion templates etc.. but hey.. there are people out there really trying develop high-end applications, including workflows etc…

stay tuned for more questions answered from my side.. and tell me about your questions…

Michael

bookmark_borderFRULE: frustrated about stupid error messages

Scenario:
created xPage, added some fields, changed some properties, added custom control with buttons to save etc…, tried to create and save a “document” …
wouldn’t save…  wtf makes fun with me???

damn…

tried to find out what the problem was, got the idea to add an “display errors” control, guess what, there WAS an error!!

Search??? what search??? and WHERE?????

almost went nuts!!!

finally, you guess: after HOURS!!!, I had a brilliant or stupid idea: remove the form validations on “save” as the xPage wasn’t really “connected” to an existing form, and guess what!!

THE SEARCH ERROR MESSAGE DISAPPEARED!!!

Lesson learned:
1. xPages error messages are stupid as stupid can be
2. never use form validations if the xPage isn’t associated with an actual form

FRUstradedLearningExperience

I know.. usually all this wouldn’t happen when you start from scratch.. but as all lazy developers.. I sometimes “copy&paste” and this ain’t really helping sometimes!

bookmark_borderindip: use bean within another bean

I wanted to use a bean within another bean. And I wanted the most elegant way to achieve this.

Here’s what I got:

define the beans in the faces-config.xml as follows (notice the color codings, to show references!)

  <managed-bean>
    <managed-bean-name>childBean</managed-bean-name>
    <managed-bean-class>com.abb.xpages.beans.ChildBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
  </managed-bean>
   <managed-bean>
    <managed-bean-name>ParentBean</managed-bean-name>
    <managed-bean-class>com.abb.xpages.beans.ParentBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
         <managed-property>
     <property-name>childBeanX</property-name>
     <value>#{childBean}</value>
   </managed-property>
  </managed-bean>

then in your “parentBean” you “inject” the childBean as follows:

ChildBean childBean = null;
public void setChildBeanX(ChildBean bean){
childBean = bean;
}
then you can access the childBean in other places in your parentBean, 

Example method from the parentBean:
public String getColor(){
return childBean.getColor();
}

As always I hope someone might find this useful when struggling around with beans! Also check out my other recent post regarding scope setting if you require notes objects being serialized.

bookmark_borderquindip: problems with beans containing references to Notes objects?

I tried desperately to maintain references to Notes objects within a bean.

I always got a stupid error, either 500 or serialization error…

then I stumbled across this excellent article.

Solution Summary:
don’t use “view” for bean scope if you need to serialize notes objects! use session or request scope.

Stupid!!! really stupid!!!

but now I got my stuff working

Michael

bookmark_borderquindip: handle onKeyPress event server side (sort of ;-) )

Did you ever need to “catch” a key event? I did! Using the type-ahead feature i wanted to fill some fields depending on the selected value from the type-ahead field.

Now I used the “onBlur” event first. But that would require the user to move the focus away from the field with type-ahead.

I was looking for a solution where immediately after hitting <enter> the fields below would be filled.

Turns out this is pretty easy:

use two onKeyPress event handlers: one client-side, one server-side:

client-side:

if (thisEvent.keyCode==13) {
      return true;
}else{
      return false;
}

server-side:
call whatever functionality you need! in our case it’s a bean populating dependant fields


the client-side piece of code checks for <enter> and calls the server-side functionality only on <enter>

bookmark_borderindip: really cool type-ahead

this time just a link to share with you guys out there.

A REALLY, did I make this clear? REALLY REALLY cool fancy way to make type aheads the way I need them:

http://www.timtripcony.com/blog.nsf/d6plinks/TTRY-7XD5P9

kudos to Tim Tripcony


Summary:
1. in the outline of the editbox with type ahead you will find below the “ajax” component. Select it to see it’s properties in the appropriate pane.
2. select valueMarkup = true
3. add a function name (eg. getNames(searchValue) which returns an unordered list of elements and surround every part which should NOT be part of the value returned into the field with: <span class=”informal”>text you don’t want in the field after selecting the target value</span>
4. add searchValue in the var property

we use Managed Beans to return type aheads (which makes it WAY faster as the JavaScript does not need to be evaluated!)

bookmark_borderindip: making type-ahead easy as pie in 3 steps!!!

Did you ever use the Extension library names picker? Do you like it? I don’t!

Why? It requires the user to use his mouse and make too many clicks to get to what he wants.

I have a better way to achieve it and it can be adopted to any type-ahead you would like: in only 3 steps!!!

And the coolest thing is: you can actually “fine tune” it.

Just to give a clue:
We have a database regarding travels which requires the user to enter his flights, we have a huge list of airports worldwide. So the user has 3 options for type-ahead: 2 characters will search for all airports in the country with that ISO code, 3 characters will search for a specific airport by that identifier and if the user enters more characters a full text search is being conducted! Ain’t that cool?

Steps: (check out the color coding where each piece goes to)
1. Define the field, make sure the var attribute is the one used as parameter to the method call of your bean, make sure the Class name is the name you defined as bean name (see step 3)

<?xml version=”1.0″ encoding=”UTF-8″?>
<xp:view xmlns:xp=”http://www.ibm.com/xsp/core”>
<xp:inputText id=”airport”>
<xp:typeAhead mode=”partial” minChars=”2″ var=”searchValue
preventFiltering=”true”
valueList=”#{javascript:TypeAHeadBean.searchAirport(searchValue)}”
ignoreCase=”true”>
</xp:typeAhead>
</xp:inputText>
</xp:view>
2. Define the bean:
public class YourBean implements Serializable{

private static final long serialVersionUID = -4498155370434392583L; // this can be auto generated and is required for beans as they have to be serializable

public ArrayList<String> searchAirport(String searchValue){
try {
ArrayList<String> al = new ArrayList<String>();

Database db = (Database) DominoUtils.getCurrentDatabase();

                         // this is the part you may want to customize, ie with a creative view you might not need FTSearch (take a look at ($Users) in the names.nsf
View view = db.getView(“lupAirports”);
if( 2 == searchValue.length()){
view.FTSearch(“[AirportCountryCode]=”+searchValue, 0);
}else if(3 == searchValue.length()){
view.FTSearch(“[AirportCode]=”+searchValue, 0);
}else{
view.FTSearch(“*” + searchValue.toLowerCase() + “*”, 0);
}


Document doc = view.getFirstDocument();

while(null != doc ){
                                // the values you add here will be displayed in the type ahead
al.add(doc.getItemValueString(“AirportName”));

doc = view.getNextDocument(doc);
}
                        // maybe you wanna sort the result properly
Collections.sort(al);
return al;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}

}

// maybe you wanna add some “recycling of Notes objects”…

3. Setup the bean:
Add the bean to the faces-config.xml
  <managed-bean>
    <managed-bean-name>TypeAHeadBean</managed-bean-name>
    <managed-bean-class>com.acme.YourBean</managed-bean-class>
    <managed-bean-scope>view</managed-bean-scope>
  </managed-bean>
If you open the Package Explorer view you will find the faces-config.xml here:

Results:
more than 3 characters type-ahead conducting a fulltext search

3 characters type-ahead which looks up the specific airport

2 characters type-ahead which looks for all airports in the country denoted by the 2 character ISO code

I hope one again you enjoyed my blog.. any comments are welcome, don’t hesitate starting a discussion about an interesting topic

bookmark_borderquindip: use ctrl F8 to switch perspectives

so you read my article about how easy it is to debug xPages and now get stuck in the debug perspective all the time but you would like to checkout your code etc?

simple: use <ctrl><F8> to switch perspectives.

If you open first all those perspectives you don’t need and close them via WindowClose Perspective then it’s a simple matter of <ctrl><F8> to switch between Debug and xPages perspective

ah.. as a side note:

did you know that you can actually “debug” the building of the xPage component tree itself?
Open the Package Explorer view and inside your LN application open the Localxsp folder. There you will find the Java classes which have been created out of the XML in the xPages designer!

You can then set a breakpoint in the Java class for your xPage here:

    protected AbstractCompiledPage createPage(int pageIndex) {
        return new nameOfYourXPage();
    }

bookmark_borderquindip: accessing grouped values (checkbox/radio groups)

I was trying to get the selected values from a check box group, but I failed miserably…

Almost when I gave up I got an error and then I found this site:
the XPages Extensibility API Documentation

via the class XspSelectManyCheckbox I then figured I had to search for the JSF API.

There I found this:
java.lang.Object[] getSelectedValues() 
Return the currently selected values, or null if there are no currently selected values.

which basically means:

getComponent(“myCheckBoxGroupID”).getSelectedValues() will return an ARRAY!!! checkout the [] at the end the object.

so finally it was easy to parse the selected values:
var valueArray = getComponent(“myCheckBoxGroupID”).getSelectedValues();
// valueArray[0] contains the first value
// valueArray[1] contains the second value etc.

can you believe it how stupid I am? and how relieved to finally have found a way to read the selected values with SSJS?