Thursday, April 19, 2007

Websphere Portlet Factory

Just installed Websphere Portlet Factory (WPF) and test it out a bit. My previous experience of developing portlet is using Websphere Studio Application Developer (WSAD), now called Rational Application Developer (RAD). Definitely WPF is much simpler to get started with, for developing portlets than WSAD.

I manage to built a simple portlet to display a Domino application view and document in a few minutes. Basically a few builders in a portlet factory model would do the job. But this just create the WPF provided standard view and display all the fields in the document. It would take more work to customized to the way we may want it to be. But still so far, no Java coding yet. Good new ya.

Will spend more time learning up WPF. Definitely it is much easier to learn than building portlet in WSAD. This hold true especially for those who are still going to learn Java :) Let just see how far we can built portlet application using WPF without JAVA codings. Will update my findings soon.

Tuesday, April 10, 2007

Websphere Portal iFrame portlet on IE 7

I was testing an Websphere Portal v6.0 iFrame portlet. It was working on IE 6.0 and Firefox. But on IE 7, I get the error message below.

The portlet cannot be displayed because your browser does not support iframes.

My first impression was that IE7 support for iframe was disable. So I check the IE settings and it seems alright. After some searching around, I found the problem is not with IE7. It's a known issue but can be easily solved. Go to the Portal Administration -> Portal Settings -> Supported Clients. The list of supported client is listed there. IE 7 is missing. Just "Add new client" and filled up the information as per MSIE 6.0. Only the information below needs to be changed

User Agent:
.*MSIE 7.0.*

Version:
7.0

It would be much easier if we could make a copy of the IE 6.0 client setting and make the necessary changes only. Any portlet guru who can modify the Supported Client setting portlets to have additional copy function?

Looking forward to play around more with Portal Server.

Tuesday, April 03, 2007

Document Navigation From View - HTTP_Referer

On Lotus client, when opening a document from a view, normally will be open on a new tab. Thus closing it may bring you back to the view.

On web, people try to avoid opening a new window. When opening a document from a view, users will expect to go back to the view that they come from. Users can access the same document from different views. Thus application have to be built to handle this.

One way to do this is passing the view name through the anchor link when opening the doc from the view. A simple way is to look through the view table DOM anchor and append the required query strings. I usually put the a div tag ("viewtable") around the embedded view in the $$ViewTemplate. This code below will look through the anchor link and append in the view name.

var anchor =
document.getElementById("viewtable").getElementsByTagName("a");
for(var i=0; i<=anchor.length; i++){
if(anchor[i] !== undefined){
anchor[i].href = anchor[i].href + "&view=" +
document.getElementById("viewname").value;}
}

This is a simple solution but when you have a large view, you have to take into consideration of the script performance. There should be a simpler way to do this. I just thought of using CGI values.

So I tried using HTTP_Referer. It returns the url of where you come from, thus it can be used to retrieve the view name. I store the view name in a hidden field for easy reference. The formula below can be used in the field to retrieve the view name from the HTTP_Referer. If it cannot find the view name in the HTTP_Referer, it will put in a default view name.

a:=@Left(@Right(HTTP_Referer; ".nsf/"); "?OpenView");
@If(a=""; "vMyAction"; a)

The "Close" button in the document can use the field to navigate back to the view.
When going from read to edit mode, the referer will be the read mode thus losing the view name info. A simple way around this is to pass the view name along in the URL when opening the document in edit mode or going back to read mode. It can easily be retrieve using @UrlQueryString.

There are many ways to do the document navigation from the view. You can use the methods above, cookies, etc. If you know a better or simpler way to do it, feel free to drop in your comments.

Add to del.icio.us

Tuesday, March 20, 2007

Javascript String Performance

Followup previous article on innerHTML performance, I now take a look at what is the better way to built the HTML string for the innerHTML.

I use 2 for loop to built a table with 1000 rows and 5 columns. 4 different ways of building the string is tested. The test is done on Firefox 2.

1) str += ...
2) str = str + ...
3) str = str.concat(... , ...)
4) str.push(... , ...)

Below is the javascript sample for the 4th test cases

function init(){
console.time("String")
var newStr = new Array("<table>");
for(var i=0; i<1000; i++){
newStr.push("<tr>");
for (var j=0; j<5; j++){
newStr.push("<td>row ", i, " col ", j, "</td>");
}
newStr.push("</tr>");
}
newStr.push("</table>");
document.getElementById("content").innerHTML = newStr.join("");
console.timeEnd("String");
}

I did sample of 20 time and get the average result.







Test TypeAverage Time (ms)
1str += ...317.5
2str = str + ...285.4
3str = str.concat(... , ...)287.2
4str.push(... , ...)298.4


The results is quite close. The 1st Case is the slowest among all. The other 3 time is almost silimar considering their performance variation is about the same. Thus for most case (small functions), either way should be fine. But to squeeze every ms out, try using case 2-4.

The only thing to avoid is building the string like the example below.
newStr = newStr + "row ";
newStr = newStr + i;
newStr = newStr + " col ";
newStr = newStr + j;
newStr = newStr + "";

Use this instead:
newStr = newStr + "row " + i + " col " + j + "";

Any String that can be build in one line, should be done so.

Add to del.icio.us

Thursday, March 15, 2007

DOM innerHTML vs appendChild

There's a lot of debate on whether to use innerHTML or to add in HTML elements using DOM methods. Personally I prefer to use innerHTML because it is easier to use. innerHTML is said to be faster as well.

For comparison, I have develop 2 functions to create a table with 100 rows and 5 columns.

1) An array is use to built the Table HTML string. Then it is appended into innerHTML of a div "content".

function init(){
var ihtml = "<table id='mytable'>";
for(var i=1; i<=100; i++){
ihtml += "<tr id='row" + i + "'>";
for(var j=1; j<=5; j++){
ihtml += "<td id='col" + i + "_" + j + "'>" + i +

"_" + j + "</td>";
}
ihtml += "</tr>";
}
ihtml += "</html>";
document.getElementById("content").innerHTML = ihtml;
}


2) A DOM table is built and append into the div "content".

function init(){
var table=document.createElement("table");
table.setAttribute("id", "mytable");
for(var i=1; i<=100; i++){
var tr = document.createElement("tr");
tr.setAttribute("id", "row" + i);
for(var j=1; j<=5; j++){
var td = document.createElement("td");
td.setAttribute("id", "col" + i + "_" + j);
td.appendChild(document.createTextNode(i + "_" + j))
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById("content").appendChild(table)
}


I use Firebug profile to time the function. So what the performance result difference should I expect?




function 1(innerHTML)function 2
Average Time60 ms130 ms


Both function manage to execute in miliseconds. But, function 1 (innerHTML) is two time faster the DOM methods. I have increase it to 1000 rows and the result is the same, innerHTML is twice as fast. As a conclusion, innerHTML is much faster for more complex/larger DOM manipulation.

Add to del.icio.us

Tuesday, March 06, 2007

Quick Tip - Domino File Upload Control element

For file uploading on the web, File Upload Control element can be used in Domino Design. It will create the file upload file (eg tag below). The name of the File Upload field will start with %%File.

<input id="UserFile" size=50 type="file"
name="%%File.482571b10020b158.e1c9d0d2ceb6a5c5482571b50022e0ab.$Body.0.1F64">

@AttachmentNames will return all the attachment(s) filename of the document. To create anchor link to the file, a <ComputedValue> can be used to built the link.

temp := @AttachmentNames;
ahref := "<a title=\"" + temp +
"\" target=_blank href=" + DatabasePath +
"VUncat/" + @Text( @DocumentUniqueID ) +
"/$FILE/" + temp + ">" + temp + "</a>";
ahref

There is a problem when directly using the attachment name to be set as the anchor link. Files with space in the filename will produce broken link. Some file upload examples that I saw, include a message to inform user not to upload file with space in the filename. This is definitely not user friendly.

To overcome it use @URLEncode. It will handle the space or some other special characters in the filename.

ahref := "<a title=\"" + temp +
"\" target=_blank href=" + DatabasePath +
"VUncat/" + @Text( @DocumentUniqueID ) +
"/$FILE/" + @URLEncode("Domino"; temp) +
">" + temp + "</a>";

To add in additional function to removed the attachment, use an input checkbox with the name "%%Detach"

ahref := "<INPUT TYPE=checkbox NAME=\"%%Detach\" VALUE=\"" +
@URLEncode("Domino"; temp) + "\"> <a title=\"" +
temp + "\" target=_blank href=" + @WebDbName + "VUncat/" +
@Text( @DocumentUniqueID ) + "/$FILE/" + @URLEncode("Domino"; temp) +
">" + temp + "</a><br/>";

Checked on the filename that need to be removed. Then save document. The attachment will be removed.

Domino File Upload Control provides an easy way to upload file into the document. And the examples above is to access the attachments and manipulate it (open, delete).

Add to del.icio.us

Thursday, March 01, 2007

CNY Lou Sang

Lou Sang

Lou Sang is a Chinese New Year (CNY) dish. It consist of crackers, carrot, assorted colored ginger, pomelo, etc and not forgetting the raw fish. It is mix together with pepper, oil and plum sauce. Family and friends will stand and mix it up together using chopstick. While mixing, everyone will provide good luck wish like getting a promotion, better business, etc.

Lou Sang is only available about 1-2 weeks before CNY and 15th day after CNY (the last day of CNY - Chap Goh Meh). If you happen to be in Malaysia during then, don't forget to try it out at Chinese restaurant.