Monday, January 31, 2011

Xpages - How to dynamically add client side script library? (xp:headTag)

The following is a way using which u can include client side javascript libraries into xpages in a dynamic fashion. Yes it lets you compute javascript library's URL in the XPage.


Note the usage of the scoped variables along with custom text in constructing the url of the script library


<xp:headTag tagName="script" rendered="true" loaded="true">
<xp:this.attributes>
<xp:parameter name="clientSide" value="true"></xp:parameter>
<xp:parameter name="src">
<xp:this.value>
<![CDATA[#{javascript:return applicationScope.get("senchaSourceBase")+"sencha-touch-debug.js"}]]>
</xp:this.value>
</xp:parameter>
</xp:this.attributes>
</xp:headTag>

To know about including style sheets in similar fashion click here

Hope this helps :)

How To Add Style Sheet URL Dynamically To XPages? (xp:headTag)

The following is a way using which u can include style sheets into xpages in a dynamic fashion. Yes it lets you compute style sheet URL in the XPage.

Note the usage of the scoped variables along with custom text in constructing the url of the style sheet

<xp:headTag tagName="link" rendered="true" loaded="true">
   <xp:this.attributes>
         <xp:parameter name="rel" value="stylesheet"></xp:parameter>
         <xp:parameter name="type" value="text/css"></xp:parameter>
         <xp:parameter name="href" >
         <xp:this.value>
<![CDATA[#{javascript:return applicationScope.get("scopeVariableNameContainingURL")+"leftouturl/filename.css"}]]>
</xp:this.value>
         </xp:parameter>
     </xp:this.attributes>
</xp:headTag>



To know about including client side script libraries in a similar fashion click here
Hope this helps :)

Thursday, January 27, 2011

View All Design Elements in a Lotus Notes Database in a Single View ($FormulaClass)

The design properties of View Consist of a item named "$FormulaClass".
It is the value on this item that decides the boundaries on what a view can display. By Default the value on this is "1". And this means a lotus notes view with "$FormulaClass" item set to 1 can display only documents present in a database, which is again governed by the view's selection formula.


But when we change this particular value to a set of predefined values, it works wonders.
The following table would give you a glimpse of what it is capable of.


Value of $FormulaClass         Viewing Elements
1                                                     Documents 
4                                                     Forms and Subforms
8                                                     Views, Folders and Navigators
16                                                   Database Title
32                                                   Design Collection 
64                                                   ACL Note (in compiled format)
512                                                 Agents (Shared)
1024                                               Shared Fields   
1548                                               Forms, Sub-forms, Views, Folders,
                                                       Navigators, Agents(Shared),                  
                                                       Shared Fields 


Yes changing the view's $FormulaClass item value to one of the above mentioned values will help you display design docs too...(And that can be controlled/manipulated) in a lotus script agent

I have checked with 8.5.2 and the value "1548" in "$FormulaClass" of the view also displays XPages and CustomControls.

Seems like a visual equivalent of NotesNoteCollection.

Caution : 
I copied paste all the documents in a view with "$FormulaClass" set to "1548". And it did duplicate my design elements. So be careful when you perform any tests with this concept

A working illustration is found in the following page:

Hope this helps:)

Filter HTML/XML tags from a text

function filterHtmlTags(source) {
var result=source.replace(/(<([^>]+)>)/ig,"");
result=trim(result, "\n");
return result;
}

//function to trim of leading and trailing spaces
function trim(str, chars) {
return ltrim(rtrim(str, chars), chars);
}

//function to trim of white spaces on the left
function ltrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

//function to trim of white spaces on the right
function rtrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

Thursday, January 20, 2011

Sencha Touch

The Sencha Touch API is pretty amazing and is awesome. As far as I have seen it helps you with application developement for mobile/IPad and works well in Safari and webkit. Google Chrome too...:)

But it did not work with IE/Firefox....

Go through the video and I am sure you will thirst for more....



Sencha Touch - Intro to Layouts from Sencha on Vimeo.

The following site contains more such videos and they are all awe some
http://vimeo.com/18134446

hope this helps :)

Wednesday, January 19, 2011

Decode Html Using Javascipt - decodeHTML()

The following function helps you replace most of the html equivalents of the special strings like &,"..etc to their original form. I hope it covers all of them, but i am not sure...

And yes there is a more elegant way to do this. But I thought it might be useful for to give an idea to people who are looking out for this.

function decodeHTML(str) {

/*
 *   @Param : str - your native html string to be decoded     *
 *   @Return : str - decoded html                                        *
 *   @Created : 19th Jan 2011                                            *
 */

str=str.replace(/&nbsp;/gi, " ");
str=str.replace(/&ndash;/gi, "–");
str=str.replace(/&mdash;/gi, "—");
str=str.replace(/&iexcl;/gi, "¡");
str=str.replace(/&iquest;/gi, "¿");
str=str.replace(/&quot;/gi, "\"");
str=str.replace(/&ldquo;/gi, "“");
str=str.replace(/&rdquo;/gi, "”");
str=str.replace(/&lsquo;/gi, "‘");
str=str.replace(/&rsquo;/gi, "’");
str=str.replace(/&laquo;/gi, "«");
str=str.replace(/&raquo;/gi, "»");
str=str.replace(/&amp;/gi, "&");
str=str.replace(/&cent;/gi, "¢");
str=str.replace(/&copy;/gi, "©");
str=str.replace(/&divide;/gi, "÷");
str=str.replace(/&gt;/gi, ">");
str=str.replace(/&lt;/gi, "<");
str=str.replace(/&micro;/gi, "µ");
str=str.replace(/&middot;/gi, "·");
str=str.replace(/&para;/gi, "¶");
str=str.replace(/&plusmn;/gi, "±");
str=str.replace(/&euro;/gi, "€");
str=str.replace(/&pound;/gi, "£");
str=str.replace(/&reg;/gi, "®");
str=str.replace(/&sect;/gi, "§");
str=str.replace(/&trade;/gi, "™");
str=str.replace(/&yen;/gi, "¥");
str=str.replace(/&aacute;/gi, "á");
str=str.replace(/&Aacute;/gi, "Á");
str=str.replace(/&agrave;/gi, "à");
str=str.replace(/&Agrave;/gi, "À");
str=str.replace(/&acirc;/gi, "â");
str=str.replace(/&Acirc;/gi, "Â");
str=str.replace(/&aring;/gi, "å");
str=str.replace(/&Aring;/gi, "Å");
str=str.replace(/&atilde;/gi, "ã");
str=str.replace(/&Atilde;/gi, "Ã");
str=str.replace(/&auml;/gi, "ä");
str=str.replace(/&Auml;/gi, "Ä");
str=str.replace(/&aelig;/gi, "æ");
str=str.replace(/&AElig;/gi, "Æ");
str=str.replace(/&ccedil;/gi, "ç");
str=str.replace(/&Ccedil;/gi, "Ç");
str=str.replace(/&eacute;/gi, "é");
str=str.replace(/&Eacute;/gi, "É");
str=str.replace(/&egrave;/gi, "è");
str=str.replace(/&Egrave;/gi, "È");
str=str.replace(/&ecirc;/gi, "ê");
str=str.replace(/&Ecirc;/gi, "Ê");
str=str.replace(/&euml;/gi, "ë");
str=str.replace(/&Euml;/gi, "Ë");
str=str.replace(/&iacute;/gi, "í");
str=str.replace(/&Iacute;/gi, "Í");
str=str.replace(/&igrave;/gi, "ì");
str=str.replace(/&Igrave;/gi, "Ì");
str=str.replace(/&icirc;/gi, "î");
str=str.replace(/&Icirc;/gi, "Î");
str=str.replace(/&iuml;/gi, "ï");
str=str.replace(/&Iuml;/gi, "Ï");
str=str.replace(/&ntilde;/gi, "ñ");
str=str.replace(/&Ntilde;/gi, "Ñ");
str=str.replace(/&oacute;/gi, "ó");
str=str.replace(/&Oacute;/gi, "Ó");
str=str.replace(/&ograve;/gi, "ò");
str=str.replace(/&Ograve;/gi, "Ò");
str=str.replace(/&ocirc;/gi, "ô");
str=str.replace(/&Ocirc;/gi, "Ô");
str=str.replace(/&oslash;/gi, "ø");
str=str.replace(/&Oslash;/gi, "Ø");
str=str.replace(/&otilde;/gi, "õ");
str=str.replace(/&Otilde;/gi, "Õ");
str=str.replace(/&ouml;/gi, "ö");
str=str.replace(/&Ouml;/gi, "Ö");
str=str.replace(/&szlig;/gi, "ß");
str=str.replace(/&uacute;/gi, "ú");
str=str.replace(/&Uacute;/gi, "Ú");
str=str.replace(/&ugrave;/gi, "ù");
str=str.replace(/&Ugrave;/gi, "Ù");
str=str.replace(/&ucirc;/gi, "û");
str=str.replace(/&Ucirc;/gi, "Û");
str=str.replace(/&uuml;/gi, "ü");
str=str.replace(/&Uuml;/gi, "Ü");
str=str.replace(/&yuml;/gi, "ÿ");


return str;
}

Hope this helps :)

Tuesday, January 11, 2011

Triggering lotus script agents and obtaining their response on the XPage using Server side javascript - An XMLHTTPRequest equivalent

Triggering agents from server side javascript in XPages is easy. How ever obtaining the response from the agents once the lotus script agent completes execution and displaying the same on the xpage was always a challenge to me. The following is a way helped me achieve it,

/***************************************************/
importPackage(java.net);
importPackage(java.io);

//create a url object by passing the lotusscript agent's url and ensure that you have some print statements in your agent
var agent:URL = new URL("Agent URL");
//create a connection with the agent's url provided
var agentConnection:URLConnection = agent.openConnection();
//open a buffered reader that gets the stream of response from the agent connection        
var inputReader:BufferedReader = new BufferedReader(new InputStreamReader(agentConnection.getInputStream()));
//read the output line by line and store them in a string
var res:String="";
while ((inputLine = inputReader.readLine()) != null) {
     res+=inputLine;

//update the result to a output field on the XPage to view the same visually
getComponent("output").setValue(res);

/***************************************************/


This attempt was successful and I was able to recieve responses on the XPage but is a Synchronous way. Hence you may have to wait until the agent gets executed and the response is obtained.

Am yet to find the same to do in a Asynchronous way.

Hope this helps :)

Triggering lotus script agents and obtaining their response on the XPage using Client side javascript - An XMLHTTPRequest equivalent in Dojo

The traditional way through which we perform AJAX calls to lotusscript agents to obtain responses kept failing for me in XPages. I kept wondering why I was not able to get back any response from the agents.

The following dojo method though different, helped me accomplish the same,

/***************************************************/
      dojo.xhrGet( { // 
        url: "The url of your lotusscript agent", 
        handleAs: "text",
sync: true,
        timeout: 5000, // Time in milliseconds

        // The LOAD function will be called on a successful response.
        load: function(response, ioArgs) { 
         returnValue=response;
         alert(returnValue) ;  // this will alert your print statements from the lotusscript agent
        },

        // The ERROR function will be called in an error case.
        error: function(response, ioArgs) {  
          console.error("HTTP status code: ", ioArgs.xhr.status);
          returnValue= response;
          return returnValue; 
          }
        });
/***************************************************/

How ever I was not able to get the browser wait as I would do when using,
xmlHttp.open(GET,url,false)

The sync flag seems to work differently than I expected in the dojo.xhrGet method

Hope this helps :)

Importing Java Packages in server-side-script in XPages

In an attempt to use methods in java directly in XPages, I used to try the traditional import methods which would say,

import java.io.*;

 to import the IO.* package in Java and that will always return an error. I was wondering how to do these stuffs untill I stumbled upon a http://www.stevecastledine.com/sc.nsf/dx/using-standard-java-packages-in-your-xpage-code"> post in Steve Castledine's Blog

The proper way to do that in XPages is as follows,

importPackage(java.io)


so in general I assume that to be importPackage(java package name without .*)


Hope this helps :)

Monday, January 10, 2011

getWebDBName in XPages (@WebDBName in XPages)

The following is a function that helps u obtain the web db name of a database in xpages (@WebDBName)


function getWebDBName() {
var arg=@Trim(arguments[0]);
var webDBName="";
if (typeof arg!="undefined"){
webDBName=@ReplaceSubstring(arg,"\\","/");
return webDBName;
}
var dbPath=@DbName()[1];
webDBName=@ReplaceSubstring(dbPath,"\\","/");
return webDBName;
}


The following are the ways in which u can use the above function

getWebDBName("a\\b/c\\d.nsf");      //will return a/b/c/d.nsf
getWebDBName(database);             //will return @WebDBName;
getWebDBName();                          //will return @WebDBName;
getWebDBName(db:NotesDatabase);  // will return @WebDBName of the db object being passed

Hope this helps :)

Friday, January 7, 2011

Getting Key Strokes on XPages (eg. Enter Key Press)

Most javascript resources on the web said some thing similar to the following to capture key strokes.

var key;
if(window.event)
key=window.event.keyCode;
else
key=e.which //for firefox explicitly on XPages

But the same failed in case of XPages in Firefox and I was puzzled

After a long try I found the following fix which worked for client, web-IE/Firefox/Chrome. The trick is bolded in the following code

var key;
if(window.event)
key=window.event.keyCode;
else
key=thisEvent.which //for firefox explicitly on XPages

//if enter key is pressed proceed or else skip
if (key == '13') {
alert("Enter Key Pressed");
}

Hope this helps :)

Wednesday, January 5, 2011

Get Current URL in XPage

In traditional Web Application it is kind of simple to get the current url using location.href.

In case of XPages the following is the method to get the current url in XPages

context.getUrl().toString();

Hope this helps :)

Tuesday, January 4, 2011

Export view contents to excel using LotusScript on web

The following stuff was obtained from "http://www.botstation.com/code/view2excelweb.php". This proved to be very useful to me... Saved a lot of time ofcourse. A Nice Tool

This LotusScript agent exports all documents from a Domino view to Excel. It can be triggered from web browser so the user can immediately see the results in his Excel application.
User can specify what view he wants to export by appending a view name as an URL parameter to the agent.
Set agent to be run as "Web User" in order to prevent accessing reader-protected documents unavailable to regular users.

/***************************************************/
Sub Initialize
'This agent export any view to excel using web browser interface.


'To select a default view to export, change the view name in the code below.
'You can also provide view name as parameter to the agent. As the agent runs
'with authority of it's signer make sure the agent can not access the views which
'are not supposed to be exported. Use this function at own risk or remove it, so 
'the agent always uses the default view. 
'Example of appending a view name parameter to the agent:
'http://intranet.company.com/applications/mydb.nsf/ExportViewAgent?open&expview=ExportAllPeople


'Warning: to avoid errors on columns containing multivalue fields, use following
'column formula to combine multivalues: @Implode(MVField;",")
'Columns containing icons are not exported.
'Columns used for counting totals are not exported. 


'Copyright Botstation (www.botstation.com)
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView 
Dim doc As NotesDocument
Dim colcounter As Integer, currentcol As Integer
Dim expview As String, filename As String 
Dim colnames
Dim colnumbers 


Redim colnumbers (0 To 100) As Integer
Set db=session.currentdatabase
Set doc=session.DocumentContext


filename="Excel "+db.Title+" "+Format(Now, "yyyy-mmm-d hh-mm")+".xls" 'file name which will be suggested to user to save the resulting Excel file 
tmp=""


If Instr(doc.query_string_decoded(0),"expview=")=0 Then ' find out if view is supplied as URL parameter to this agent
Set view = db.GetView("ExportToExcel") ' no view supplied as parameter, use your default export view
Else
expview=Strright(doc.query_string_decoded(0),"expview=")
If Instr(expview,"&")>0 Then expview=Strleft(expview,"&")
Set view = db.GetView(expview) ' get the view passed as parameter to the agent
End If
If view Is Nothing Then
Print "Export Error - Export view does not exist" 
Exit Sub
End If
colcounter=0
currentcol=0 'starting column number. 0=first column
Forall c In view.Columns 
If c.isIcon<>True Then ' do not include icon columns
If c.Formula<>"""1""" And c.Formula<>"1" Then 'do not include columns which are counting docs (Total)
colnumbers(colcounter)=currentcol 'put into array what columns are valid for exporting
tmp=tmp+"<th>"+c.Title+"</th>" 
colcounter=colcounter+1 'total nr of valid columns
End If
End If
currentcol=currentcol+1 'increment counter of columns with 1
End Forall


If colcounter=0 Then 
Print "Export Error - No valid columns to export"
Exit Sub
End If
Redim Preserve colnumbers (0 To colcounter-1) As Integer 'remove unused array values
' ---- output browser header ------
Print |Content-Type:application/vnd.ms-excel| 'You can also try with "application/octet-stream"
Print |Content-Disposition: Attachment; filename="|+filename+|"| 'Triggers the save/open browser prompt instead of embedding the spreadsheet in the browser
Print ""
' --------------------------------
Print "<table border=1>" 'set border to 1 pixel, otherwise Excel shows no cell separators.
Print tmp 'output view column headers
Set doc = view.GetFirstDocument
While Not ( doc Is Nothing ) 'process all documents in view
tmp=""
tmp=tmp+"<tr>" 'begin a new table row
Forall colnr In colnumbers 'process all previously validated columns
colvalue= doc.ColumnValues(colnr)
tmp=tmp+"<td>"+CStr(colvalue)+" </td>" 'make a new table cell
End Forall
tmp=tmp+"</tr>" 'close row
Print tmp 'output values to browser after each row/document
Set doc = view.GetNextDocument (doc)
Wend 
Print "</table>"


End Sub 
/***************************************************/

Hope this helps :)

Handling "timeout exceeded" error in an XPage with an Ajax partial page refresh

XSP.submitLatency is a property associated with the XPage which governs the amount of time a pratial refresh can take in XPages. Exceeding which you get the "timeout exceeded" error asking you to refresh the entire page or cancel.


One of the most irritating errors that I have encountered in xpages. I even felt helpless against these errors in many cases :(


Thank god i found this in the 8.5 developerworks forum.


The following is a method to over ride it.
XSP.submitLatency = 60000; //timeout limit increased to 60 seconds


Hope this saves developers from going through the ones I crossed.


:)