Tuesday, May 28, 2013

Big Tables with fixed headers (eg. 1000 Rows and 200 Columns)

There have been a lot of solutions on the innernet when I searched for tables with fixed headers. Most of them worked pretty much the way the demonstration was made in those websites.

But all of them had a lot issues when the size of the table got bigger. Especially with a table containing 1000 + rows and 200+ columns, literally all available examples choked and I had a lot of issues reusing them.

Some of the issues that I encountered during the course of this R&D are as follows

1. Position:fixed would have been used and hence I will not be able to scroll towards right to find new column titles
2. Position-y or Position-x: fixed was not available
3. Ready made solutions which had a fix to the above mentioned points were mostly from jquery and they choked out the browser making them squell with an error page saying some script is running which stops the page from loading on time - DO YOU WANNA KILL IT???
4. Minimizing the table size was not an option
5. Had to think through the tableCellElement.offsetWidth
6. Gave a thought about creating headers with multiple separate div tags and displaying them simultaneously
7. Even solutions that helped admist all these issues required me to scroll through the entire 200+ columns to see the vertical scroll
8. Un even table cell widths

on and on and so on....

Eventually the following seemed promising to me and it did work well with both ie and chrome.

Step 1: I used the following inline styles

table {width:auto;}
thead {  position: absolute;}
thead th { height:50px; }
tbody { height:150px; overflow: scroll; }
tbody td { height:60px;}

Step 2: following is a supportive script that will help your table header stay in tact. This includes a timer

var interval = "";
  var itr = 0;
  var repeatDuration = 100;
  interval = window.setInterval("myfunc()", repeatDuration);

function myfunc() {

if (document.all) {
document.getElementsByTagName("thead")[0].style.left="-"+document.documentElement.scrollLeft+"px"
document.getElementsByTagName("thead")[0].style.top=document.documentElement.scrollTop+"px"
} else {
document.getElementsByTagName("thead")[0].style.left="-"+document.body.scrollLeft+"px"
document.getElementsByTagName("thead")[0].style.top=document.body.scrollTop+"px"
}

}
Step 3: Construct your table and view it on the browser.

Hurray I was able to do it atlast. Try it out and let me know if it works in firefox and safari too :)

Monday, May 27, 2013

Trigger Select All Checkbox Click in XPage view panels in XPages


This post shows the method through which the select all button that you would enable on a Xpage view panel can be programatically clicked.

I found need for a scenario in which I would require the document ids of all documents that are being displayed on a Xpage view in a browser. Eventually the simplest userfrinedly/user interactive mechanism that I was able to think about was the native select all feature available with the XPage view controls in Lotus Notes.

It took me quite a while to understand the usage though, It was quite tricky and tough but not any more :)
Following is the code fragment that allowed me to do this silly stuff

var viewPanelContainer=document.getElementById("ViewPanelContainer");

//-- Following line of code has been commented and the forth comming lines, second and third respectively
//have been introduced to bypass a IE bug related to the HTMLNode.getElementsByClassName command in javascript
//var selectAllCheckBox=viewPanelContainer.getElementsByClassName("xspCheckBoxViewColumnHeader")[0];
var selectAllCheckBoxes=getElementsByClassName(viewPanelContainer, "xspCheckBoxViewColumnHeader");
var selectAllCheckBox=selectAllCheckBoxes[0];
//-- End of block highlighting the work around for an IE bug


selectAllCheckBox.click(); //dispatchEvent("click");

Here I am using a function named as getElementsByClassName. The function is available in the blog, you can simply search for the same using the name itself or use any other method that you have. This is essential for the code to work in the tremendously awesome Internet explorer crap.

For all other poor browsers out there, they are in capable of making my life difficult and hence a simple object.getElementsByClassName will work on them

Hope this helps :)

Dojo Toolbar related tips and tricks in XPages

A while ago I was working on creating a tool bar for one of my Xpages. I was able to find a lot of reliable resources on the internet. It did take me a lot of time to understand and build my own toolbar though.

In summary my understanding is you may have to use all or few of the following dojo.require attributes in your page


dojo.require("dojo.parser");
dojo.require("dijit.form.Button");
dojo.require("dijit.Toolbar");
dojo.require("dijit.Tooltip");
dojo.require("dijit.ToolbarSeparator");

I also found that I was using the code line "var djConfig = { baseScriptUri : "js/dojo/",parseOnLoad : true };"
I am not sure if I had used the djConfig variable any where in my program to construct the tool. I guess it automatically loads with Xpages. If not - what stops you from a copy & paste :)

! guess I copy codes blindly at times lol.

Again I wanted this to be visible to the entire XPage and hence I used a "xp:scriptBlock" tag to define them

Later I copied code from the standard examples about dojo toolbar available on the web and modified it to suit my requirements
This sure is a lot of code. Just skip or delete the code fragments that might not be of interest to you.

Now I have acquired a decent tool bar when I preview the page on the browser. Which looks like the following.

<div id="toolbar" style='display:none;position:fixed;_position:absolute;
top:0;_top:expression(eval(document.body.scrollTop));
left:0;_left:expression(eval(document.body.scrollLeft));'>
<div id="toolbar1" dojoType="dijit.Toolbar">
<div dojoType="dijit.form.Button" id="toolbar1_Home"
iconClass="iconHome" showLabel="false">
Home
</div>
<span id="span6" dojoType="dijit.Tooltip" connectId="toolbar1_Home">
Home
</span>
<span data-dojo-type="dijit.ToolbarSeparator"></span>
<div dojoType="dijit.form.Button" id="toolbar1_ExportAll"
iconClass="iconExportAll" showLabel="true">
Export All
</div>
<span id="slides_tip" dojoType="dijit.Tooltip" connectId="toolbar1_ExportAll">
Export all data to Excel Sheet
</span>
<span data-dojo-type="dijit.ToolbarSeparator"></span>

<!-- div dojoType="dijit.form.Button" id="toolbar1_ExportSelected"
iconClass="iconExportSelected" showLabel="true">
Export Selected
</div>
<span id="fs_tip" dojoType="dijit.Tooltip" connectId="toolbar1_ExportSelected">
Export
selected documents to Excel Sheet
</span>

<span data-dojo-type="dijit.ToolbarSeparator"></span-->


<div dojoType="dijit.form.Button" id="toolbar1_PrintPage"
iconClass="iconPrintPage" showLabel="true">
Print
</div>

<span id="thumb_tip" dojoType="dijit.Tooltip" connectId="toolbar1_PrintPage">
Print the page as you see it
</span>
<span data-dojo-type="dijit.ToolbarSeparator"></span>

<div dojoType="dijit.form.Button" id="toolbar1_PrintAll"
iconClass="iconPrintAll" showLabel="true">
Preview All
</div>

<span id="span2" dojoType="dijit.Tooltip" connectId="toolbar1_PrintAll">
Preview all documents
</span>
<span data-dojo-type="dijit.ToolbarSeparator"></span>

<div dojoType="dijit.form.Button" id="toolbar1_PrintSelected"
iconClass="iconPrintSelected" showLabel="true">
Preview Selected
</div>

<span id="span1" dojoType="dijit.Tooltip" connectId="toolbar1_PrintSelected">
Preview selected documents
</span>

<span data-dojo-type="dijit.ToolbarSeparator"></span>

<div dojoType="dijit.form.Button" id="toolbar1_SearchField"
iconClass="" showLabel="true">
<xp:inputText style="width:222.0px" id="SearchContent">
</xp:inputText>
</div>
<div dojoType="dijit.form.Button" id="toolbar1_SearchButton"
iconClass="iconSearchButton" showLabel="false">
Search Image
</div>

<span id="span4" dojoType="dijit.Tooltip" connectId="toolbar1_SearchButton">
Search
</span>

<div dojoType="dijit.form.Button" id="toolbar1_HighlightButton"
iconClass="iconHighlightButton" showLabel="false">
Highlight Matches
</div>

<span id="span3" dojoType="dijit.Tooltip" connectId="toolbar1_HighlightButton">
Highlight
matches without searching
</span>

<div dojoType="dijit.form.Button" id="toolbar1_AdvSearchButton"
iconClass="iconAdvancedSearch" showLabel="false">
Advanced Search
</div>

<span id="span5" dojoType="dijit.Tooltip" connectId="toolbar1_AdvSearchButton">
Advanced
Searching Options
</span>

<span data-dojo-type="dijit.ToolbarSeparator"></span>
<div dojoType="dijit.form.Button" id="div1" iconClass=""
showLabel="true">
<xp:label value="Show " id="label3"></xp:label>
<xp:comboBox style="width:80.0px" defaultValue="30"
id="docsToDisplay">
<xp:selectItem itemLabel="30 Docs" itemValue="30">
</xp:selectItem>
<xp:selectItem itemLabel="50 Docs" itemValue="50">
</xp:selectItem>
<xp:selectItem itemLabel="100 Docs" itemValue="100">
</xp:selectItem>
<xp:selectItem itemLabel="200 Docs" itemValue="200">
</xp:selectItem>
<xp:selectItem itemLabel="1000 Docs" itemValue="1000">
</xp:selectItem>
<xp:eventHandler event="onchange" submit="true"
refreshMode="complete">
<xp:this.action><![CDATA[#{javascript:var searchViewGrid:com.ibm.xsp.component.xp.XspViewPanel=getComponent("searchViewPanel");
var docsToDisplay=getComponent("docsToDisplay").getValue();
var docToDispInt=java.lang.Integer.parseInt(docsToDisplay)
searchViewGrid.setRows(docToDispInt)}]]></xp:this.action>
</xp:eventHandler>
</xp:comboBox>
</div>
</div>
</div>

Its a lot of code. Atleast I got a nice looking tool bar like the following on my screen now.



Now take a closer look at the parent tag that I have defined for the tool bar. The style that is being computed/defined here helps the tool bar stay on top of the page irrespective of the page scroll

I dont know whether this method is recommended or not but, it servers the purpose. So if you find/know of a better way to do this please do let me know of the same.

Here the various icon classes that I have used here are responsible for the nice icons that are being displayed on the tool bar. So mark sure that you define your styles properly. Following is one such example of the associated style sheet

Our net stop is to see how to define an onclick event for our nice tool bar buttons here. Hi hi what did you expect. On click event related activites needs to be explicity defined through code and its not a simple onclick event definition. Following is the way to do it.

It would seem a little complicated, but its easy to understand. Following screen shot shows how I defined onclick events for the toolbar buttons along with how I defined the functions that were associated with the onclick events

Hope this helps :)


Monday, May 13, 2013

GetElementsBYClassName bug in IE

A while ago I was working with a checkBoxElement.click() type of function in which I had my client side javascript code identify the checkBoxElement through a HTMLNode.getElementsByClassName('myClassName') method.

This worked like charm with Chrome ( Chrome is the best :), unfortunately as expected this one had issues with the great Internet Explorer.

Eventually I had to scan through the web and with little effort I found the following nice function

function getElementsByClassName(node, classname) {
/* function obtained, modified and reused from
http://stackoverflow.com/questions/7410949/javascript-document-getelementsbyclassname-compatibility-with-ie
*/
var objectCollection = [];
        var re = new RegExp('(^| )'+classname+'( |$)');
        var els = node.getElementsByTagName("*");
        for(var i=0,j=els.length; i<j; i++)
            if(re.test(els[i].className))objectCollection.push(els[i]);
            return objectCollection;
        }

This worked well across both Chrome and IE. I am relieved :)

Hope this helps :)

Thursday, May 2, 2013

Function to bring focus to a html field element


function focusField(field) {
var myField;
if (typeof field==='string')
myField=document.getElementById(field);
else if (typeof field=='undefined')
return;
else myField=field;

window.setTimeout(function ()
    {
myField.focus();
myField.select();
}, 0);
}