Thursday, December 01, 2011

Floating/Fixed Table Header in HTML Page or Inside DIV control

I’ve looked a lot for finding a solution were we can float a header of a table so that the header always appears on the top no matter how down do I scroll.
All the ‘floating table header’ solution ‘mostly’ worked were full HTML body is getting the scroll but none of them worked which can work inside scrolling div. None!
So I though I can create one. The concept was simple, get the ‘onScroll’ even of Div control and change CSS “top” property of table header to current scrolled position of Div. 
Unfortunately, there are many browser issues. Like mozilla doesn’t like when table cells change their position. Chrome rendering issues shows two headers rows when scrolled up.
At last, after storming through the problems, I arrived on this complex but simplified solution which is mentioned below. Copy the content in a blank HTML file and see the fun.

<html> 
    <head> 
        <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript" > </script> 
        <script  type="text/javascript"> 
            $(function() { 
                if($.browser.mozilla) 
                    //table row doean't float in firefox, div floats 
                    $(".floatingHeader" + " tr th div") 
                            .addClass("floatingStyle"); 
                else 
                    //table row can float in IE and Chrome 
                    $(".floatingHeader"+ " tr th") 
                            .addClass("floatingStyle"); 
            }); 
            function changeFloatingHeaderPosition(container, headerId) { 
                    if($.browser.webkit) //chrome rendering bug fix 
                        $("#"+headerId + " tr th") 
                            .css("visibility", "hidden"); 
                    if($.browser.mozilla) 
                        $("#"+headerId + " tr th div") 
                            .css("top", container.scrollTop); 
                    else 
                        $("#"+headerId + " tr th") 
                            .css("top", container.scrollTop); 
                    if($.browser.webkit) //chrome rendering bug fix 
                        $("#"+headerId + " tr th") 
                            .css("visibility", "visible"); 
            } 
     
      // Remove this method if you are using Jqeury earlier than 1.9
     (function() {
      var matched, browser;

      // Use of jQuery.browser is frowned upon.
      // More details: http://api.jquery.com/jQuery.browser
      // jQuery.uaMatch maintained for back-compat
      jQuery.uaMatch = function( ua ) {
   ua = ua.toLowerCase();

   var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
       /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
       /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
       /(msie) ([\w.]+)/.exec( ua ) ||
       ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
       [];

   return {
       browser: match[ 1 ] || "",
       version: match[ 2 ] || "0"
   };
      };

      matched = jQuery.uaMatch( navigator.userAgent );
      browser = {};

      if ( matched.browser ) {
   browser[ matched.browser ] = true;
   browser.version = matched.version;
      }

      // Chrome is Webkit, but Webkit is also Safari.
      if ( browser.chrome ) {
   browser.webkit = true;
      } else if ( browser.webkit ) {
   browser.safari = true;
      }

      jQuery.browser = browser;
  })();
        </script> 
        <style> 
            .floatingStyle 
            { 
                position:relative; 
                background-color:#829DC0; 
                top:0px; 
            } 
        </style> 
    </head> 
<body> 
    <div class="floatingContainer"     onscroll="changeFloatingHeaderPosition(this, 'idHeader' );"      style="height:150px; width: 100px;overflow:auto;"> 
        <table cellspacing=0 cellpadding=0> 
            <thead class="floatingHeader" id="idHeader"> 
                <tr> 
                    <th><div>Col1</div></th>                     <th ><div>Col2<div></th> 
                    <th ><div>Col3<div></th> 
                </tr> 
            </thead> 
            <tbody> 
                <tr><td>first_row</td><td>first_row</td><td>first_row</td></tr> 
                <tr><td>data</td><td>data</td><td>data</td></tr> 
                <tr><td>data</td><td>data</td><td>data</td></tr> 
                <tr><td>data</td><td>data</td><td>data</td></tr> 
                <tr><td>data</td><td>data</td><td>data</td></tr> 
                <tr><td>data</td><td>data</td><td>data</td></tr> 
                <tr><td>data</td><td>data</td><td>data</td></tr> 
                <tr><td>data</td><td>data</td><td>data</td></tr>             </tbody> 
        </table> 
</div></body><html>
Note: Dan/Kenji has written plugging for the same which might be useful to you. I've not verified if it works in all case but worth having a look. You can find it: here: http://www.redkitetechnologies.com/2013/03/floatingsticky-headers-for-visualforce-pageblocktable/

Tuesday, November 15, 2011

Find Missing Foreign Key References

If you database column naming convention says all foreign key columns must end with 'ID' then this is the query for you to find missing foreign key reference. E.g. PRIZE_ID means Foreign Key reference to PRIZE table.
SELECT 
    colT.TABLE_NAME , 
    colT.COLUMN_NAME 
FROM 
    INFORMATION_SCHEMA.COLUMNS AS colT 
WHERE 
    COLUMN_NAME LIKE '%id'
    AND 
    (colT.TABLE_NAME + colT.COLUMN_NAME) NOT IN
     ( SELECT 
          KOM.TABLE_NAME + KOM.COLUMN_NAME 
      FROM 
          INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS KOM)

Monday, June 20, 2011

Amazon SimpleDB in Nutshell for those who know RDBMS Systems

Note: Latest Available Amazon SimpleDB version as of today, i.e. when I am writing this, is in Beta status with API Version: “2009-04-15”

Overview of SimpleDB
Amazon SimpleDB is a highly available, flexible, and scalable non-relational data store that offloads the work of database administration. Developers simply store and query data items via web services requests.[1]

Representation of Data with SimpleDB:

Domains— Domains are similar to tables that contain similar data.

You can execute queries against a domain, but cannot execute queries across different domains.

Attributes— They are similar to columns in RDBMS, attributes represent categories of data that can be assigned to items.

Items— Represented by rows, items represent individual objects that contain one or more attribute name-value pairs.

Values—Similar to column value, values represent instances of attributes for items. An attribute can have multiple values. There is no data typing supported for attribute and all data is treated as text data during query execution.

However, Amazon SimpleDB is not a relational database, and does not offer some features needed in certain applications, e.g. complex transactions or joins (i.e. execute queries across different domains).[1] You need to rely on duplicating the data to avoid such scenarios.[2]

Benefits of using SimpleDB

Highly Available
Amazon SimpleDB creates and manages multiple geographically distributed replicas of your data automatically to enable high availability and data durability.
Flexible
You can change your data model on the fly, and data is automatically indexed for you.
Scalability
You can access additional machine resources by spreading your data set and requests across multiple domains.

Support for Reporting
Sql Server Reporting Service (SSRS) is a popular platform to build and access reports. SSRS reports are build based on dataset that has set for a report. It is possible to build dataset from SimpleDB.[3] 

Limitation with SimpleDB

Domain (similar to table): 250 active domains per account. More can be requested by filling a form. Note that each attribute (similar to column) can hold multiple value.[4]

Attribute (similar to column) name-value pairs per item: 256[4]

Maximum response size for Select: 1 MB (large data like images can be stored separately into cloud as files and an Attribute can store URL for the resource).[4]

Maximum items per select: 2500[4]

Attribute value length: 1024 bytes[4]

No datatyping: text only. Integers and reals must be represented using leading zeros to ensure proper query comparisons.[5]

References:

[1] Amazon SimpleDB (beta)
http://aws.amazon.com/simpledb/

[2] How And Why Glue Is Using Amazon SimpleDB Instead Of A Relational Database
http://blog.getglue.com/?p=1145

[3] Accessing SimpleDB from SSRS
http://www.chrisumbel.com/article/simpledb_ssrs.aspx

[4] Amazon SimpleDB Limits, Amazon SimpleDB Developer Guide (API Latest version)
http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/

[5] M/DB - A Free Open Source "plug-compatible" alternative to Amazon's SimpleDB database
http://gradvs1.mgateway.com/main/index.html?path=mdb

Thursday, April 21, 2011

How Apple's Location Services Work


Even though I like apples (specially the one which fell on Newton's head), I am not found of Apple as a corporation. Mainly because it is too secretive in its technologies and methods of doing something amazing. Location Services are one of those secretive things which need to be so secret but you can figure-out how it works.

Apple's Locations services uses (in order) A-GPS, Wi-Fi triangulation and Cell Triangulation (base on capability of your device).

Uses A-GPS
Pros
When you are outdoors, works amazingly.
Cons
Works poorly in urban environment with tall buildings. Even your vehicle roof is a problem for A-GPS. Doesn't work without GPS chip in device (case for iPod).

Uses cellular tower triangulation
Pros
Even with it's worst accuracy, sometimes it is more accurate than GPS in urban environment. This is because performance doesn't decrease in urban environments due to many towers triangulating in cities nowadays. 
Cons
Cellular tower triangulation as it is way too in accurate for the accuracy need of the day. This is option only when when no other medium of deciding location available.

Uses Wi-Fi triangulations
Pros
Works very accurate when one or more wi-fi is available in area. You need not to connect to a Wi-Fi, nether the Wi-Fi needs to know your requirement of locating your device. If the location of Wi-Fi is stored in Apple's giant database of all Wi-Fi and their co-ordinates, you are in luck. Your device contact Apple's service and based on Wi-Fi details, Apple will send you Wi-Fi coordinates. I am not sure if device triangulates the Wi-Fi once the coordinates are found or Apple's service will do it - but end result is accurate coordinates.
Cons
You need to be in range of one or more Wi-Fi. If you are using iPod, you should be connected with internet.

How Does Apple Get all Wi-Fi Locations?
Hmm... so the world need to have a database of all wi-fi and their locations. It is still guess for the people how apple has got this database? This is what I think based on recent controversies regarding Apple's privacy policy regarding sharing your iPhone location with Apple's Service:
When your device has correct location decided, it also looks for wi-fi around your device. It stores those information on iPhone and iTunes on your computer sends it to Apple. And so, this list has grown 2 fold in day and 4 fold in night (it is just saying).
Note that before to iOS 3.2, this was not the case so Apple used to use (and still using for older devices) Skyhook Wireless and Google's services for WiFi triangulations.

Now you are ready for next level: Go to Apple's Office Discloser of its Location Service and know more about it.

Friday, March 18, 2011

Good User Experience

Good user experience cannot be achieved by jazzy animations. It is these simple things that everyone wants to have.

google_attachment

Some common tips for better user experience (most of us knows but we don’t follow):

1. Use standard controls. In laymen language, text should look like text and button should look like a button.

2. Optimize for speed. Everyone want to get the things done faster. Don’t put animations which hinders speed of doing something. Your UI (specially forms) should be accessible by ‘keyboard only’ as well.

3. Think about the common mistake that user may be making while data entry. When you find something wrong, locate exact position and show understandable message to show the error.

4. Try to optimize available space. You controls should be able to adjust to larger width to avoid scrollbars if possible. Don’t put big logos of the application on each screen top.

5. Find the most used flows for your UI and optimize UI so user can complete the common tasks faster. If necessary, create different views of the same UI for different kind of user in organizational hierarchy.

Friday, February 04, 2011

Nested Transaction Handling with NHibernate

NHibernate doesn’t have inbuilt support for nested transaction (or I am not using latest version). But, with little compromises, you can create a class that enables almost everything what you really need. I am using NHibernateSessionManager which you can find here: http://www.codekeep.net/snippets/8b94e3e0-3ffd-4b59-b6ce-ed4d46158a7c.aspx
    public class SmartTransaction
    {
        bool _transactionOwner =false;
        bool _transactionActive = false;

        public bool IsActive
        {
            get
            {
                return _transactionActive;
            }
        }

        public void Begin()
        {
            if (_transactionActive) return; //return to bad programer's code

            try
            {
                _transactionOwner = !NHibernateSessionManager.Instance.HasOpenTransaction();
                if (_transactionOwner)
                    NHibernateSessionManager.Instance.BeginTransaction();
                _transactionActive = true;
            }
            catch
            {
                _transactionOwner = false;
                _transactionActive = false;
                throw;
            }
        }

        public void Commit()
        {
            if (!_transactionActive || !NHibernateSessionManager.Instance.HasOpenTransaction())
            {
                _transactionActive = false;
                return;
            }

            try
            {
                if (_transactionOwner)
                    NHibernateSessionManager.Instance.CommitTransaction();
            }
            catch //when you don't know what you are committing to.
            {
                NHibernateSessionManager.Instance.RollbackTransaction(); 
                throw;
            }
            finally
            {
                _transactionActive = false;
            }
        }

        public void Rollback()
        {
            _transactionActive = false;

            if (!NHibernateSessionManager.Instance.HasOpenTransaction())
                return;
            NHibernateSessionManager.Instance.RollbackTransaction();
        }
    }


Benefits:

1. When writing a method, you need not to worry about context of calling method. You can just begin transaction of SmartTransaction class. If calling method has started transaction already, SmartTransaction doesn’t begin the transaction, but if something goes wrong, it will rollback entire transaction (of calling method).


2. You need not to worry if method you are calling needs transaction wrapping. As with SmartTransaction class, if method you are calling needs transaction wrapping, it will have transaction wrapping using SmartTransaction class.