Monday, February 8, 2010

How to Handle Session Expire in Ajax Call (Prototype Framework)

Steps:
1. Call is made to server using XMLHttpRequest either get or post method
2. Check string token like "session expired" or "sessionexpired" the result data. If so then it indicates that session is expired.
3. If session expired then redirect it to the Session Expire Page using following code:
var sessionExpiryURL="/global/sessionExpired.jspx";
window.location=sessionExpiryURL;


Sample Codes:

Note: Sample code uses prototype framework.

Script uses handling Session Expire:
var sessionExpiryURL="/global/sessionExpired.xhtml";

/*
    The following method checks if the session has expired or not
    Pre: Applicable for Ajax call only and the ajaxResponseText must pass the responseText from the AJax call
*/
function isSessionExpired_OnResponseText(ajaxResponseText){
    if (ajaxResponseText != null ){
        var lclAjaxResponseText = ajaxResponseText.toLowerCase();
        if (lclAjaxResponseText.indexOf("session expired") >=0 || lclAjaxResponseText.indexOf("sessionexpired") >=0 ){
            return true;
        }
    }
    return false;
}
/*
    The following method checks if the session expired and redirects to session expiry  page
    Pre: Applicable for Ajax call only and the ajaxResponseText must pass the responseText from the AJax call
*/
function handleSessionExpiry_OnResponseText(ajaxResponseText){
    if(isSessionExpired_OnResponseText(ajaxResponseText) == true){
            window.location=sessionExpiryURL;
    }
}

/*
    The following method checks if the session has expired or not
    Pre: Applicable for Ajax call only and the ajaxResponseText must pass the responseText from the AJax call
*/
function isSessionExpired(ajaxResponseObj){
    if (ajaxResponseObj!= null ){
            var contentText =ajaxResponseObj.responseText;
            return isSessionExpired_OnResponseText(contentText);
    }
   
}

/*
    The following method checks if the session expired and redirects to session expiry  page
    Pre: Applicable for Ajax call only and the ajaxResponseText must pass the responseText from the AJax call
   
*/
function handleSessionExpiry(ajaxResponseObj){
    if (ajaxResponseObj!= null ){
            var contentText =ajaxResponseObj.responseText;
            return handleSessionExpiry_OnResponseText(contentText);
    }
}

Script uses to post Ajax Call:

var jScript = Class.create();
    jScript .prototype =  {
    initialize: function()
    {
          // Initialization Stuff, It is called before calling any mothod of jScript
    },


/* funtion defination
@ URL - URL to be submitted to server
@ params-Associative array (Hash) to carry data from client to server
@ sourceObj- Ideally onchange of source object event; it posts the ajax request
@ targetObj- Ideally  targetObj is the placeholder for the response like populating some data into it.
/*
post: function(URL, params, sourceObj, targetObj) {
        var url = strURL ;
        var responseText = "";
        new Ajax.Request(strURL, {
                parameters: parameters,
                method:'post',
                onSuccess:function(transport) {
                    try {
// Algorithm uses to extract data from response and populate to the targetObj
                        }
                     }catch(e) {
                            if(isSessionExpired(transport)==true) {
                                handleSessionExpiry(transport);
                                return;
                            }
                            alert("System Error" );
                     }
                },
                 onFailure:function(transport) {
                    alert("An  error occurred");
                    alert("Error occurred: " + transport.responseText);    //Debug purpose only
                    //TODO handle errors
                 }
        });
    },


//AJAX Function
    loadStates: function (){
   var sourceObj = $('countryName'); // country name selected in dropdown
    var targetObj = $('stateNames'); // dropdown list box to  hold state names
    var parameters = new Hash();

    var strURL="../Country/getStates.xhtml"; // Servlet to provide state names
    parameters['countryName'] = sourceObj.value;
    parameters.set('ajaxParam', '1');
    this.post(strURL, parameters,  sourceObj , targetObj );
    }
};

jScript .Initializer = function() {
        jScript = new jScript ();
}

Event.observe(window, 'load', jScript .Initializer);

Tuesday, February 2, 2010

jQuery Autocomplete Field Sample Code (Using Plugins)

1. Auto complete plugin - http://www.pengoworks.com/workshop/jquery/autocomplete.htm
2. Javascript:
<script type="text/javascript">

/** AJAX - Call back
This function will submit the form when any item is selected from the autocompleted text field
@param li - item submited from the autocomplete field
*/

function findValue(li) {
if( li == null ){
return;
}

var selectedValue;
if( !!li.extra ){
selectedValue = li.extra[0];
}
else {
selectedValue = li.selectValue;
}
j$("studentNameQS").value=j$("studentName").value;
// Action class method name
j$("testForm").action = "showStudentDetailsById.xhtml";
j$("testForm").submit();

}

/** AJAX - Call back
A JavaScript function that will be called when an item is selected. The autocompleter will specify a single argument, being the LI element selected.
This LI element will have an attribute "extra" that contains an array of all cells that the backend specified.
@param li - item submited from the autocomplete field
*/
function selectItem(li) {
findValue(li);
}


/** AJAX - Call back
A JavaScript function that will be called when item are populated in the select box.
@param row - item in string format laying inbetween line separator.
*/

function displayItem (row) {
return row[0];
}

/** AJAX - Call back
A JavaScript funcion that can provide advanced markup for an item. For each row of results, this function will be called.
The returned value will be displayed inside an LI element in the results list.
Autocompleter will provide 3 parameters:
the results row,
the position of the row in the list of results,
and the number of items in the list of results.
@param row - item in string format laying inbetween line separator.
*/

function formatItem(row) {
return row[0];
}

j$(document).ready(function() {
// Register autocomplete plugin with the given textfield id i.e. #studentNameQS once the DOM is ready.
j$("#studentNameQS").autocomplete(
"findStudentDetails.xhtml", // URL
{
delay:10,
minChars:4,
matchSubset:1,
matchContains:1,
cacheLength:10,
maxItemsToShow:10,
formatItem:formatItem,
onItemSelect:selectItem,
onFindValue:findValue,
lineSeparator:'|',
cellSeparator: '~',
autoFill:true
}
);
});
</script>

3. Form:

<s:form name="ajaxStudentForm" id="ajaxStudentForm" action="showStudentDetailsById.xhtml">
<s:hidden name="studentNameQS"/>

</s:form>

<input id="studentName" type="text" maxlength="254" size="55"/>

4. Action Class

/**
* Method to get Student Name based on the Search criteria
* It is used for the Student Name Quick search functionality i.e. to show available names during typing
*
* @return String
* @throws Exception
*/
public String findStudentNames() throws Exception{

response.setContentType("text");
response.setHeader("Cache-Control", "no-cache");
// "searchQuery" is constructed by jquery-autocomplete.js - makeUrl()
// Should be verify in makeUrl(); what is used for the parameter
studentNameWildCard = request.getParameter("searchQuery");

// There is nothing supplied for RoleName
if (studentNameWildCard == null) {
response.getWriter().write("");
return null;
}

//Get the data from DB Based on the wild card chars

StringBuilder studentNameIds = new StringBuilder();

// Going to construct (ROLENAME~ID) like "|ABC~123|BCD~234|CDE~345|"
String[] staticNames = new String[ABC~123|BCD~234|CDE~345|]
// Put pipeline (|) as a line separator
studentNameIds.append("|");
studentNameIds.append("Ram");
// Put tild (~) as a cell separator
studentNameIds.append("~");
studentNameIds.append(1);
studentNameIds.append("|");
studentNameIds.append("Shiv");
// Put tild (~) as a cell separator
studentNameIds.append("~");
studentNameIds.append(2);

response.getWriter().write(studentNameIds.toString());
return null;
}