Friday, September 29, 2006

Disabling Back Button and URL Blocking

This was a hot topic for web enable application when we were doing our programming assignments for our degree (maybe when the due dates getting nearer). Students always came across this problem and were unable find a better solution. This issue came when or after a registered user logs out from the member’s area after viewing some member’s only pages, non registered users should not be able to see the restricted pages which was meant to be only for members.

What happens in a browser is as we know that all the pages viewed get cached, so later it can be viewed by anyone. This is mainly a problem when a computer is shared by many people. So to eliminate this problem we are suppose to use some kind of a mechanism to stop caching of these pages. This I am talking in java server side scripting point of view.

A solution is to insert some header tags in the html,Servlet or jsp (java server page) pages for stop caching. First we will look at the html header tags.

<!-- Forces caches to obtain a new copy of the page from the origin server -->
<meta http-equiv="Pragma" content="no cache">
<!-- Directs caches not to store the page under any circumstance -->
<meta http-equiv="Cache-Control" content="no-store">

<!-- Directs caches not to cache the page under any circumstance -->
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="expires" content="-1">


The same tags can be inserted in a java servlet page using the response object as follows.

response.setHeader("Pragma","no cache");
response.setHeader("Cache-Control","no-store");

response.setHeader("Cache-Control","no-cache");
response.setHeader("Expires","-1");


The other solution is to have session variables to validate the user when entering a restricted page by directly typing the URL. Each page has to check the user type if there are many types of users (member, admin or moderator) who are authorized in accessing different kinds of pages which consist with different functions and for an user id. These values should be created in a successful login and stored in session variables to check them through out a session. Meanwhile intervals can be set to invalidate a session (session expire) when the session is not active for a particular moment.

First we’ll look at some servlet codes to set session variables for checking purpose.

HttpSession session = request.getSession(true); //creating a http session object
session.setAttribute("ID",""); //creating a session attribute to store the user’s id
session.setAttribute("Type",""); //another session attribute to store user type

try
{
//Authenticate the Member

if (user selection is equal to type Member)
{
*Get the password for the user’s input id and assign it to a string db_ password
if(user’s input password equals to db_ password)
{
//set session attribute ID with user’s ID
session.setAttribute("ID", **request.getParameter("ID"));
// Setting the type for security purpose - block browsing with an URL directly
//set session attribute type with user type
session.setAttribute("Type",request.getParameter("type"));
… //Any action to be performed
}
else
{
…//necessary action for the error
}
}
//End of If

else
{
... // Action for the error
} //End of Else

} //End of Try

catch(Exception e)
{

…//Action for the caught exception
} //End of Catch

* get the password through a method.
** getParameter is a method of the Request object to read a parameter.

Second, check these session variables in the restricted member’s page.

HttpSession session = request.getSession(true);
if (session.getAttribute("ID") == null)
{

... // necessary action
}
else
{
if (*String.valueOf(session.getAttribute("Type")).equals("Member"))
{
... // Rendering the page
}
else
{
... // necessary action
}
}


* Changing a session object to String type.

The same can be repeated to check the other member types too. I personally prefer to write these methods in a different class and invoke them every time using an object rather than writing in all the pages. And also I recommend write all restricted pages in jsp so that it can be used to write scripts to check the above.

Cheers!!!

Triple Menu Javascript

Populating dropdown values are always hard for me according to a chosen value for web applications. But most recently I went through a website which gave soem javascripts to build dropdowns. I'm saying hard because this involves in 3 dropdown menus. Second dropdown should populate according to the first dd's value and third according to the second.

This post post focuses only in creating triple menu and this needs a form and 3 dds. According to my script I have named form as '_form' and 3 dds accordingly 'menu','menuCat'and 'menuSubCat'. First dd should be filled with values and the script will populate the rest according to the selection.





/* ######## start of Triple menu code ############### */
function nullOptions(aMenu)
{
aMenu.options.length=0;
}

/* ########### Category starts here ########### */
/* Category for A */
function Cat1(aMenu)
{
nullOptions(aMenu);
with (aMenu){
options[0]=new Option("","");
options[1]=new Option("A.1.0","A.1.0");
options[0].selected=true
}
}
/* Category for B */
function Cat2(aMenu)
{
nullOptions(aMenu);
with (aMenu){
options[0]=new Option("","none");
options[1]=new Option("B.1.0","B.1.0");
options[2]=new Option("B.2.0","B.2.0");
options[3]=new Option("B.3.0","B.3.0");
options[0].selected=true
}
}
/* ############ Category Ends here ########### */

/* ########## Sub Category starts here ########### */

/* ########## lists of values for option 3 SubCategory:A.1.0 ######### */
function SubCat1c(aMenu)
{
nullOptions(aMenu)
with (aMenu){
options[0]=new Option("","");
options[1]=new Option("A.1.1","A.1.1");
options[0].selected=true
}
}
/* ######### end of values for option 3 SubCategory:A.1.0 ###### */

/* ########## lists of values for option 3 SubCategory:B.1.0 ########## */
// start of files for main option 3 B.1.0
function SubCat1(aMenu){
nullOptions(aMenu)
with (aMenu){
//Rewrites the text and values
options[0]=new Option("","");
options[1]=new Option("B.1.1","B.1.1");
options[0].selected=true
}
/*//Netscape likes a refresh, but Microsoft doesn't
if (navigator.appName.indexOf("Netscape")>-1)
history.go(0)*/
}
// Sub Category for B.2.0
function SubCat2(aMenu)
{
aMenu.options.length=0;
with (aMenu){
options[0]=new Option("","");
options[1]=new Option("B.2.1","B.2.1");
options[2]=new Option("B.2.2","B.2.2");
options[3]=new Option("B.2.3","B.2.3");
options[0].selected=true
}
}
// Sub Category for B.3.0
function SubCat3(aMenu)
{
aMenu.options.length=0;
with (aMenu){
options[0]=new Option("","");
options[1]=new Option("B.3.1","B.3.1");
options[2]=new Option("B.3.2","B.3.2");
options[3]=new Option("B.3.3","B.3.3");
options[0].selected=true
}
}
/* ######### end of values for option 3 SubCategory:B.1.0 ####### */

/* ########## Sub Category ends here ######### */

/* ############# change Categories ########### */
function changeCat(){
aMenu=document._form.menuCat;
aMenu2=document._form.menuSubCat;
aMenu3=document._form.menu;
with (aMenu3){
switch (selectedIndex) {

case 0:
nullOptions(aMenu)
nullOptions(aMenu2)
aMenu.options[0]=
new Option("","none")
aMenu3.options[0].selected=true;
break

case 1:
nullOptions(aMenu)
nullOptions(aMenu2)
aMenu2.options[0]=
new Option("","none")
aMenu2.options[0].selected=true;
Cat1(aMenu)
break

case 2:
nullOptions(aMenu)
nullOptions(aMenu2)
aMenu2.options[0]=
new Option("","none")
aMenu2.options[0].selected=true;
Cat2(aMenu)
break
}
}
}
/* ############ end of change Categories ################ */

/* ################ change SubCategories ############# */
function changeSubCat()
/** bookmark: starting { sign for the final } **/
{
aMenu=document._form.menuCat;
aMenu2=document._form.menuSubCat;
aMenu3=document._form.menu;

/* ######## set of values for option 3 - Sub Category for B.1.0 ###### */
if (aMenu3.selectedIndex==2)
{
with (aMenu){
switch (selectedIndex) {
case 0:
aMenu2.options.length=0;
aMenu2.options[0]=
new Option("","")
aMenu2.options[0].selected=true;
break

case 1:
SubCat1(aMenu2)
break

case 2:
SubCat2(aMenu2)
break

case 3:
SubCat3(aMenu2)
break
}
}
}

/* ######## set of values for option 3 Sub Category for A.1.0 ###### */

if (aMenu3.selectedIndex==1)
{
with (aMenu){
switch (selectedIndex) {

case 0:
aMenu2.options.length=0;
aMenu2.options[0]=
new Option("","")
aMenu2.options[0].selected=true;
break

case 1:
SubCat1c(aMenu2)
break
}
}
}

}
/* ############# end of Triplemenu code #############

For now I like to leave the exaplanation part. Will edit this post soon :).

Cheers!

Wednesday, September 27, 2006

SPS 2003 Installation Problem

We were installing SPS2003 in a freind's machine last time and came across a weird problem saying 'Service Unavailable'. Trying installing and uninstalling it over and over again, we got fedup. Ofcourse we got some solutions as a result of googling but they didn't help us at all. Strange! we had the same problem as they were saying but the workaround didn't help us at all.

The solutions were to check the credientials, specify the correct application pool, etc. We did all we could but still the answer was nope.

Finally we figured that this shows up if the operating system (Windows 2003 Server) is installed from an image. Yes! Installation and configuration is a time consuming task. IT department usually install the image file to the new machine so that the OS gets installed and ready to run in no time.

Unfortunately and sometimes, sharepoint doesn't go with this where it creates "Service Unavailable" problem. Once they installed the OS from the CD, we tried installing sharepoint again. Bingo! that worked. I still wonder whether this is sometimes or always???

For more information regarding operating system images refer Managing Your Operating Systems which was written by Douglas Steen.

Show/Hide html elements

Lot of sharepoint beginners have a problem in hiding the toolbar from the other users while rendering the page. This can be acheived by applying a style or a javascript to the element they want to hide.

The toolbar is always placed inside a column on a table. So the first method is applying a style to the column.

<!-- Column where the the toolbar is -->
<td style="display:none">


Or the second method where writing a javascript.

<script language="javascript">
document.getElementById(<column id>).style.display = 'none';
</script>


These two can apply to hide any element in a html file. But what if we want to display when its necessary or to display with a click event. For that, here goes the script;

<script language="javascript">
document.getElementById(<column id>).style.display = 'inline';
</script>


Simple isn't it? :)

Cheers!

Tuesday, September 26, 2006

Javascript to compare dates

When I came across this scenario, I went through many sites for a solution. I came to notice one thing, which some of them have taken a long path to convert a string to a date object. This can be achieved through simple one line of code.

say,

form name - form ; field name - txtDate

date1 = new Date(form.txtDate1.value); //line to convert a string to a date

This simple javascript will convert the string to a Date.

To compare two dates we can simply write javascript as below.

if (date1 > date2) //where date2 is another date converted from a string

{
//Action
....
}

Below is a sample script.

<script language="javascript">
function check(form)
{
date1 = new Date(form.txtDate1.value);
date2 = new Date(form.txtDate2.value);

if(date2 < date1)
{
alert("Date Range Invalid");
form.txtDate2.focus();
return false;
}
}
</script>

Embedded Font

Until yesterday, I did not know that we can embedd a font into a css file where it can be used to render a webpage with the any desired fot we like. Thanks to my buddy alf, I got to know this css tip. Yes! Now we can display a webpage with the font we like. It need not to be in the client's machine like the other default fonts. We have seen webpages with Times New Roman, verdana, Tahoma mostly but what if want something else which client doesn't have installed?

This tip was written by Larisa Thomason in netmechanic site. According to the tip, we're suppose to create an embedded font file which will be downloaded to the client machine while rendering the page. This can be achieved using a third party tool.

Create embedded fonts using one of 2 available formats:
  • Portable Font Resources (.pfr): TrueDoc technology was developed by Bitstream and licensed by Netscape. It can be viewed by Navigator 4.0+ and Explorer 4.0+ on Windows, Mac, and Unix platforms.
  • Embeddable Open Type (.eot): Compatible only with Explorer 4.0+ on the Windows platform. Create .eot files using Microsoft's free Web Embedding Font Tool (WEFT).
After creating this, we can attach it to the css
Attaching a TrueDoc file, by inserting the below between the head tag.


<LINK rel = "fontdef" src="url/YourFontName.pfr">

Attaching An OpenType File, by inserting the below in the stylesheet.

<STYLE TYPE="text/css">
<--!
@font-face {
font-family: Arial;
font-style: normal;
font-weight: normal;
src:url(http://www.SiteAddress.htm/EOTfileName.eot);
}
-->
</STYLE>


It is mentioned that opentype files are accessed by the user's OS.

There are two drawbacks as mentioned in the article.First is the download time which will take some more time to download the font file.Second is the security warnings which depends on client's individual browser. Client may see a warning everytime when the page accesses an embedded font.

For complete details : Get Any Font You Want