Replacing Non Alphanumeric Character in PHP

Wednesday, December 17, 2008

I use this when I want to change the filename uploaded by trusted user to server, it simply change non alphanumeric character (including space) into underscore.

<?php
$fileName = preg_replace ( '/[^a-zA-Z0-9]/u', '_', $fileNameStripped ); 
//code to upload the file
//...
?>
In my case, I strip the file from the extension 'cause I dont want the preg_replace to change the dot extension (ex: .jpg) into _jpg. It goes like
$fileNameStripped = 
substr($_FILES['thmbFile']['name'], 0,  strripos($_FILES['thmbFile']['name'], '.') )


Hope it helps.

Heredoc or <<<EOF in PHP

Saturday, December 6, 2008

Heredoc is a way to create string in PHP with more lines but without using quotations. Here's an example

<?php
 function some_function(){
  $content = '<a onClick="test(\'somevalue\')">Test</a>';  
  return $content;
 }
?>
can be written
<?php
 function some_function(){
  $content = <<<EOF
   <a onClick="test('somevalue')">Test</a>
  EOF;
  return $content;
 }
?>
Notice that using the heredoc we don't have to escape the quote('), that also apply to double quotes("). The following example also does the same thing.
<?php
 function some_function(){
  return <<<EOF
   <a onClick="test('somevalue')">Test</a>
  EOF;
 }
?>
The EOF itself can be replace by any string you want. Using a string like YHRGT is a good idea to make sure that string won't appear in your content.

Ajax Programming Common Errors

Friday, July 18, 2008

You might already know about it, but I think It's still worth mentioning, the common issue some developers stumble on:

1. GET Requests Caching on Browsers
Sometimes, when making repeated GET XMLHttpRequest to the same uRL can lead to the response coming from the browser cache and not from the server. Especially when you're using Internet Explorer. And this IS annoying.

With no-cache or similar HTTP headers, this problem can be solved, theoritically, but in a real life coding this cache is sure difficult to get rid off.

The most effective way to solve this problem is add an always update or random variable to the URL where the request is sent. So the browsers read this request as a different page request and returns the server page rather than the cached version.

So, if usually we send a request like this
var url="somescript.php?var1="+var1; XMLHttp.open("GET", url);
Now we just simply add a random varible like this
var url="somescript.php?var1="+var1+"&rand="+new Date().getTime(); XMLHttp.open("GET", url, true);


2. Escaping Variables
Remember, when creating GET or POST requests, you must escape every variables that have possibility to contain nontext characters or spaces. It's a good way to avoid crafted variables by people who like to mess or just test your codes. It goes simply like this:
XMLHttp.open("GET", url+escape(var1)+"?rand="+new Date().getTime(), true)

3. Permission Denied
Usually means that you have cross-domain scripting requests happen. Like what I've wrote earlier, an XMLHttpRequest object can't be made across different domains by default due to security matter. So by default, calls must be made to server scripts existing in the same domain as the calling scripts. And please notice that domain must be written EXACTLY in the same way, mydomain.com may be interpreted as different domain from www.mydomain.com, thus, permission will be denied. Here and here, you can find out how to solve this cross-domain issue.

Cross Domain Scripting with AJAX, Again

Thursday, July 17, 2008

I've wrote about how to overcome the cross-domain issue using Apache mod_rewrite. But that'll only work if you have administrator priviledge on your hosting server, most of us don't. So instead of tweaking the server we must tweak the code. Thus, JSON shows up.

JSON(JavaScript Object Notation) is just a way to structure object data.. in a way that is easily interpreted, primarily with Javascript. Some examples from wikipedia:
Javascript

bork({"menu": {
  "id": "file",
  "value": "File",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}});

and with different format:
XML :
<menu id="file" value="File">
  <popup>
    <menuitem value="New" onclick="CreateNewDoc()" />
    <menuitem value="Open" onclick="OpenDoc()" />
    <menuitem value="Close" onclick="CloseDoc()" />
  </popup>
</menu> 

Aha, so just like xML, JSON is just data representation part of things, but if XML can't handle cross-domain scripting, how can JSON ?

It's because the J letter on JSON, JSON is JavaScript. And we all(well, maybe not all) know that you can reference REMOTE Javascript source inside the <script> tag. So theoritically, if you create a dynamic script tag that references to a script on another domain, that script is executed imediately!. And if the remote script contains JSON, your cross-domain scripting problems days are over!. Yay.

For an even easier way, you can use a js file at Dan Theurer's blog for the dynamic adding of scripts elements.

And here's how you use it.

First, a server side file that creates the JSON outputs, named bork.php
<?php
 echo 'bork({"Image": { "Width":500, "Height":250, "Title":"Giant Cow", 
         "Thumbnail":{"Url":"http://someurl.com/image/1234", 
         "Height": 75, "Width": 150}}});';
?>


And the html file ,bork.html
<html>
<head>
<title>JSON test</title>
<script src="jsr_class.js" type="text/javascript"></script>
<script>
function appendScript(){
 var json=new JSONscriptRequest('http://myotherdomain.com/bork.php?');
 json.buildScriptTag();
 json.addscriptTag();
}

function bork(data){
 var txt='';
 if(data==null)
  alert('error occured');
 else{
  txt='Image Title: '+data.Image.Title+'
'; txt+='Width: '+data.Image.Width+'
'; txt+='Height: '+data.Image.Height+'
'; txt+='Thumbnail Data: '+data.Image.Thumbnail.Url; txt+='('+data.Image.Thumbnail.Width+' x '+data.Image.Thumbnail.Height +')
'; } document.getElementById('bork').innerHTML=txt; } </script> </head> <body> <div id="bork"></div> <a href="#" onClick="appendScript();return false;">Get Bork</a> </body> </html>

Hope this helps.

Printer-Friendly Page With CSS

Monday, July 7, 2008

Ok, so you want to create a printer-friendly page without having to create another web page for that purpose. Here's how.

First, create a separate stylesheet with the rules for the page to be printed. Usually, this css is named print.css, so maybe you should name your it print.css too :D.

Second, link the stylesheet to the page and set the media property to print.
<link rel="stylesheet" type="text/css" href="base.css" media="screen" /> <link rel="stylesheet" type="text/css" href="print.css" media="print" />

You see, the default value for the media attribute is all, so if you don't specify the attribute the browser will apply the CSS rules to all media. There are actually ten media types:

Media Type Description
all Suitable for all devices
braille For Braille tactile feedback devices
embossed For paged Braille printers
handheld For handheld devices
print For paged material, documents viewed on-screen in print preview mode
projection For projected presentation, i.e projectors
screen Primarily for color computers screens
speech For speech synthesizers
tty For media using fixed-pitch character grid i.e teletypes, terminals, or devices with limited display capabilities
tv For television-type devices


If you want to define the stylesheet for several media, separate the media values with comma, like this
<link rel="stylesheet" type="text/css" href="dual.css" media="print, projection" />

And beside using link method, you can also use import, like the following line @import URI(dual.css) print,projection; And stil there's way to define stylesheet and media types, it's by using the @media, which enables writing css rules that can be set for different media, all in one stylesheet
<style type="text/css">
@media print{
 #container {
  font-size: 10pt;
  background: #FFFFFF;
  color: #000000 
 }
}

@media screen{
 #container {
  font-size: .8em;
  background: #0000FF;
  color: #FFFFFF 
 } 
}
</style>


Hope this helps.

Getting XML Data from Server Using AJX

Friday, June 27, 2008

Previously, we use AJAX to receive data from server using the responseText property, it's quite usefull but what if you want to get a complicated data like a bunch of names, addresses, numbers, and many more information in a single request? Sure, you can format your responseText, but why bother if you can use the responseXML property?

Accessing the responseXML will get you a response of HTTP request as XML DOM objects, and this only happen if the XML returned by the server is a valid XML, otherwise you get null.

Here's how we do it.

First, an example of XML file generated by PHP, you can generate more complex with database-driven data, but here's I just a simple plain XML.

<?php
header('Content-type: text/xml');
?>
<students>
 <student year="1999">
  <name>John Smith</name>
  <ssn>23132452</ssn>
 </student>
 <student year="2000">
  <name>Jane Smith</name>
  <ssn>23132453</ssn>
 </student>
</students>
and the javscript code to extract data from XML file.
function getXMLHttp() {
var XMLHttp = null;
if (window.XMLHttpRequest) {
  try {
    XMLHttp = new XMLHttpRequest();
  } catch (e) { }
} else if (window.ActiveXObject) {
  try {
    XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) { }
  }
}
return XMLHttp;
}

var XMLHttp = getXMLHttp();
XMLHttp.open("GET", "getstudents.php");
XMLHttp.onreadystatechange = function(){
if (XMLHttp.readyState == 4) {
  var xml = XMLHttp.responseXML;
  var student = xml.getElementsByTagName("student")[0];
  var year= student.getAttribute("year");
 var name, ssn;
 for (var i=0; i<student.childNodes.length; i++) {
    if (student.childNodes[i].nodeName == "name") {
      name = student.childNodes[i].firstChild.nodeValue;
    } else if (student.childNodes[i].nodeName == "ssn") {
      ssn= student.childNodes[i].firstChild.nodeValue;
    }
  }
  window.alert(name + " / " + ssn + " / " + year);
}
};
XMLHttp.send(null);
Screenie of the result


I'll write about using documentElement and JSON to do the same thing, but in an easier way, later. For now, I hope the code above suffices.

Dynamically Generate HTML Element Using Strings and Arrays

Thursday, June 26, 2008

Eventhough DOM is maybe the most powerfull technique to manipulate a page's content, sometimes we can get performance benefits by not using it and use core javascript objects instead. In the following example I'll use strings and arrays to generate a table. I'll show both way for comparison. Remember, minimizing your code's use of OM objects can always increase your page's performance. Here's an example of a DOM scripting technique:

function createTable(numRows, numCols) {
    var idRow = 0, idCol = 0;
    var oTable = document.createElement("TABLE");
    var oTBody = document.createElement("TBODY");
    var oTRow = null;
    var oTCol = null;

    for (idRow; idRow < numRows; idRow++) {
        oTRow = document.createElement("TR");
        oTRow.style.border="solid 1px blue";
        for (idCol = 0; idCol < numCols; idCol++) {
            oTCol = document.createElement("TD");
            oTCol.innerText = "("+idRow + ", " + idCol+")";
            oTRow.appendChild(oTCol);
        };
        oTBody.appendChild(oTRow);
    };
    oTable.appendChild(oTBody);
    document.body.appendChild(oTable);
};
Call the script on your page using onload="createTable(5, 5)" for example. And here's an example using the strings and arrays:
function createTable(numRows, numCols) {
    var idRow = 0, idCol = 0;
    var buffer = new Array();
    var bufferCount = 0;
    buffer[bufferCount++] = "<table><tbody>";

    for (idRow; idRow < numRows; idRow++) {
        buffer[bufferCount++] = "<tr>";
        for (idCol = 0; idCol < numCols; idCol++) {
            buffer[bufferCount++] = "<td>";
            buffer[bufferCount++] = "("+idRow;
            buffer[bufferCount++] = ", ";
            buffer[bufferCount++] = idCol+")";
            buffer[bufferCount++] = "</td>";
        };

        buffer[bufferCount++] = "</tr>";
    };

    buffer[bufferCount++] = "</tbody></table>";
    document.body.innerHTML += buffer.join("");
};
The outputs of both code is the same, but the second is faster than the first. It proves that manipulating page dynamically is faster using core javascript code than using the DOM API. In the second method, we used buffer array to store the HTML strings. This method avoids using more CPU cycles to concatenate new element separately like in the first method. In short, the second method is faster because it changes the element in one complete string while the first method does it per element. Hope this helps.

Loading JavaScript Files Dynamically

Wednesday, June 25, 2008

So, you want to load the javascript code on runtime, for example, you want a spesific javascript to be loaded depending on some user input. How to do that? You can always use the document.write to add a new <script> element to the page. But it's not recommended and it's not working with some browsers. The better approach is to use DOM. First, create a <script> element, set the attributes, then add this element to page's DOM. Here's the example code. Remember to put the element inside the <head> section.

<script language="JavaScript" type="text/javascript">
  var myjs = document.createElement("script");
  myjs.setAttribute("type", "text/javascript");
  myjs.setAttribute("language", "JavaScript");
  myjs.setAttribute("src", "myscript.js");
  document.getElementsByTagName("head")[0].appendChild(myjs);
</script>
In that example, the script will load external javascript file named myscript.js, all you have to do is define the trigger of the script. Javascript and DOM are maybe the most powerfull way to manipulate your pages. That's how I see it. But we will discuss about this opinion later. Hope this helps,

Back (And Forward) Button Problem in AJAX

Sunday, June 22, 2008

Last time I've wrote about how to solve the bookmark problem in AJAX, this time is how to handle the back(and forward) button problem. The issue remains the same, since the page's URL doesn't change(but the content does), the back and forward button will not work as expected. To solve this, here's a general method, merely a method since the implementation depends on how the system, the requirements, and the specs you use. 1. like the previous post, you must appy the information in location.hash when you load a page. 2. make sure that the browser stores the pages with the hash, if the browser doesn't then the back and forward button will not work. Mozilla derivatives browser do this, I don't know about Internet Explorer. To push the browser to save the page with hash history, you may use a hidden iframe with nothing in it, just to get an entry in browser's history. Here's the code

<iframe src="container.html" name="container" style="display: none" ></iframe>
Whenever the state changes on the page, the container frame should be forced to load again, with the state appended to the URL.
if (window.ActiveXObject) {
  window.frames["container"].window.location.search = "?" + escape(data);
}
We use only the ActiveXObject since this only necessary in IE, mozilla saves the pages with hash info in history automatically. Last, the container frame applies the state to the main page, again, this only needed in Internet Explorer, sice the browser back button change the contents of the iframe.
window.onload = function(){
 if(location.search.length>=2){
  var data = unescape(location.search.substring(1));
  top.applyState(state);
 }
}
Yes, it's a tiring process especially when there are many different AJAX requests on the page. But it's sure worth it. Hope this helps.

Bookmark Problem in AJAX

Saturday, June 21, 2008

Since AJAX applications use XMLHttpRequest calls to change the code of the page, the URL stays the same. Therefore, it's not possible to bookmark a page with AJAX applications on it. There's a way to solve this. The trick is to append data that identifies the current state of the page to the URL. And that would not be in the form of GET parameter since we dont' want to refresh the page, but in the form of hash. http://myserver/myfile.html#state The data denoted with state is used to identify the current page status. It's depending on how you use AJAX in your page. So, whenever a state of the page changes, the page's hash must be updated too (it's in location.hash javascript). Then, a code like the following will read in this hash information AFTER the page is loaded. Then the applyState() function will take care of transforming the the information in location.hash into actual content of the page.

window.onLoad = function(){
if(location.hash.length >= 2){
 var state = unescape(location.hash.substring(1));
 applyState(state);
}
};
I will give an example of the applyState later (If I have the time). But I hope you get the idea here. Sure, it increases the amount of work to be done, but it's worth it, especially for the user. But remember, putting JSON into the hash then calling eval(); could be dangerous. An attacker could exploit it to a Cross-Site scripting(XSS) attack, so always validate data before using it. Hope this helps.

Hiding Ajax and Javascript Code

Friday, June 20, 2008

We all know it's very easy to look at javascript code of a page just by viewing the source code, or download the imported .js files, with Firebug in Firefox it may be even easier. And some companies or developers don't want to give it away or expose their code, whether it's because they worry about the security or they simply don't want other people to copy-paste and reuse their code.

For this purpose, there are freeware and commercial software that able to make the source code very to read, but stil work in the browser. They are called the code obfuscators. You can easily find them by type keyword like "javascript obfuscator" in google, in this article we will use the software called Javascript Chaos Edition (JCE) from Syntropy Development, we'll use the free version distributed as JAR file.

To use JCE, you simply launch the JAR by running java -jar jce.jar, and a GUI like this will show:

Copy the script you want to be obsfucated and paste it into the main window. Here's an example sceript code from http://www.sislands.com/jscript/week2/clock1.htm Click Next and a screen like this will be showed up:
Click Next again, copy the result script there, and paste it to your page to replace your original code. The program is simply change the code from this

var now;

function showMilitaryTime() {
     if (document.theForm.showMilitary[0].checked) {
          return true;
     }
     return false;
}

function showTheHours(theHour) {
     if (showMilitaryTime() || (theHour > 0 && theHour < 13)) {
          return (theHour);
     }
     if (theHour == 0) {
          return (12);
     }
     return (theHour - 12);
}

function showZeroFilled(inValue) {
     if (inValue > 9) {
          return ":" + inValue;
     }
     return ":0" + inValue;
}

function showAmPm() {
     if (showMilitaryTime()) {
          return ("");
     }
     if (now.getHours() < 12) {
          return (" am");
     }
     return (" pm");
}

function showTheTime() {
     now = new Date();
     document.theForm.showTime.value =
     showTheHours(now.getHours()) +
     showZeroFilled(now.getMinutes()) +
     showZeroFilled(now.getSeconds()) +
     showAmPm();
     setTimeout("showTheTime()", 1000);
}

to this
<!-- This script has been obfuscated with Syntropy's JCE - Javascript Chaos Engine which can be downloaded at http://www.syntropy.se. JCE is free to use if this comment is not removed. -->

var qZ;function sW() {if (document.theForm.showMilitary[0].checked) {return true;}return false;}function vU(Zd) {if (sW() || (Zd > 0 && Zd < 13)) {return (Zd);}if (Zd == 0) {return (12);}return (Zd - 12);}function nu(Bd) {if (Bd > 9) {return ":" + Bd;}return ":0" + Bd;}function PN() {if (sW()) {return ("");}if (qZ.getHours() < 12) {return (" am");}return (" pm");}function pH() {qZ = new Date();document.theForm.showTime.value =;vU(qZ.getHours()) +nu(qZ.getMinutes()) +nu(qZ.getSeconds()) +PN();setTimeout("showTheTime()", 1000);}


You can obviously see that the resulting code is a non friendly code(Okay, I know the original code is a non friendly too, but it's my fault, not the script, I have to rewrite the css rule for this page for the .code part). To figure out what the code does is not impossible, but it sure as difficult as hell, especially if your code is much larger than the example. And JCE here is just an example, you can find many more obsfucator through google and find one that suits best for your needs.

Hope this helps.

Apache Setting On XMLHttpRequest Cross-Domain Issue

Thursday, June 19, 2008

You may all know that XMLHttpRequest does not work automatically across domain. Which means that when you load a page, you can't make a request to a domain that is different from that page's domain. So your script on myserverhere.com can't request object to myserverthere.com, for example.

But there's always a cure for everything, and here we have the solution on Apache's mod_rewrite, this is a module that uses a rule-based rewriting engine, we usually used it to make a clean URL, to rewrite requested URLs on the fly, it's basically a regex parser.

Cross domain request happens if you have a code like this on myserverhere.com

var XMLHttp = getXMLHttp();
XMLHttp.open("POST", "http://myserverthere.com/something.php?value="+somevalue);

We run this script on myserverhere.com, but we make a post request to myserverthere.com. The domain mismatch is the cause of the problem.

IE and Mozilla-based browser have different way of handling this cross-domain requests. In IE, you can do cross-domain request, but you have to change browser's default security. While Mozilla, they have this signed-script. You must enable the UniversalBrowser privileges depending on the different domains involved in the cross-domain request. Therefore, there are no simple browser-based solution for this problem.

Fortunately, mod_rewrite has solution for this, with its RewriteRule directive. Here are the quick steps:

1. Configure your apache with proxy enabled
./configure --enable-proxy
2. Enable RewriteEngine at httpd.conf
RewriteEngine On
3. Add this rule:
RewriteRule ^/something.php$ http://myserverthere.com/something.php [P] The [P] indicates pass-through proxy.

With that, instead of sending request to http://myserverthere.com/something.php you can use /something.php URL in the javascript code, like this:
var XMLHttp = getXMLHttp();
XMLHttp.open("POST", "/something.php?value="+somevalue);
There is one problem though. You HAVE to have access to your Apache configuration. If you're a programmer that doesn't have access to Apache, you'll have to tell your webserver administrator about this hack.

Hope this helps.

Creating Simple Auto-Complete Field with AJAX

Wednesday, June 18, 2008

I noticed the ajax auto-complete field for the first time when I type a keyword in google suggest, the field automagically giving me suggestion by displaying options to what word i might looked for beneath the text field, and now you can find this auto-complete variation very popular on search page. Here's a screenshot that I only typed "open" and google suggest me of what word may related to it and the amount of result accordingly. Here's a screenie.

What I will show you here is a simple quick way to do it. I will write a simple script that would auto-complete a word that user inputted with the stored words on database and returns the first match. Here's a complete list of the code

<head>
<script language="javascript">
function getXMLHttp() {
var XMLHttp = null;
if (window.XMLXMLHttpRequestuest) {
try {
XMLHttp = new XMLXMLHttpRequestuest();
}  catch (e) { }
}  else if (window.ActiveXObject) {
  try {
   XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (e) {
  try {
  XMLHttp = new ActiveXObject(
    "Microsoft.XMLHTTP");
  } catch (e) { }
 }
}
return XMLHttp;
}

function autocomplete (from, ev) {
   if (( ev.keyCode >= 48 && ev.keyCode <= 57 ) ||  ( ev.keyCode >= 65 && ev.keyCode <= 90 )) {        
var XMLHttpRequest = getXMLHttp();        
XMLHttpRequest.open
("GET", "suggest.php?word="+document.getElementsByName("txtWord")[0].value, true);               
XMLHttpRequest.onreadystatechange = function (  ) {            
if (XMLHttpRequest.readyState == 4) {                
var suggestion = XMLHttpRequest.responseText;                
var txtWord = document.getElementById ('txtWord');                 
if ((suggestion) && (txtWord.value == original_text)) {                    
//Gecko and Opera                    
if (document.getSelection) {                        
var initial_len = txtWord.value.length;                         
txtWord.value += suggestion;                         
txtWord.selectionStart = initial_len;                        
txtWord.selectionEnd = txtWord.value.length;                     }                    
//IE <= 6                    
else if (document.selection) {                        
var sel = document.selection.createRange (  );                        
sel.text = suggestion;                                   
sel.move ("character", -suggestion.length);                        
sel.findText (suggestion);                         sel.select (   );                    
}                
}
}        
}        
XMLHttpRequest.send (null);    
}
}
</script> </head> <body> <input style="position: absolute" type="text" name="txtWord" 
id="txtWord" onKeyup="autocomplete(this, event)" /> </body> 


At the server side, you have to create a php (or whatever server-side programming language) file that find the first match of text inputted by user and simply prints that value. The code in javascript will get that value via XMLHttpRequest.responseText and send it to input field. The remaining script in that javascript is meant to graft the end of the word we get from the responseText onto the beginning of the word, and select it.

The screenshot above shows that the code auto-completes my input from "au" to "automatic" and select the "tomatic" word. It's different presentation since google puts the options into a drop-down menu but I hope it gives a clue of how we get the completion words back.

Hope that helps.

Aborting XMLHttpRequest on Timeout

Tuesday, June 17, 2008

When your application is using ajax, there are possibilities that you made many HTTP request at a time, especially if you have a page with multiple ajax components or what they call mashup. And that might be a problem. You have to know whether your request has been done or not.

The simplest way to do it is by defining a timeout period for the request, if a request takes longer time than the period defined, then you have to abort the request, and rolling back the condition to before the request is sent(if any).

The method used here is abort(), XMLHttp.abort(). The following code will show you how to abort the request if it has not been fully executed after 7 seconds. The file sleep.php here is only a dummy file which took 10 seconds to execute, therefore the request will be aborted for sure.

Here's the code for the sleep.php file

<?php
sleep(10);
echo "this text only appeared after 10 seconds";
?>

And here's the html file with a code to abort the request if it took longer than 7 seconds

<script language="JavaScript" type="text/javascript">
function getXMLHttp() {
 var XMLHttp = null;
 if (window.XMLHttpRequest) {
   try {
     XMLHttp = new XMLHttpRequest();
   } catch (e) { }
 } else if (window.ActiveXObject) {
   try {
     XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
   } catch (e) {
     try {
       XMLHttp = new ActiveXObject(
         "Microsoft.XMLHTTP");
     } catch (e) { }
   }
 }
 return XMLHttp;
}

var XMLHttp = getXMLHttp();
XMLHttp.open("GET", "sleep.php");
XMLHttp.onreadystatechange = function() {
 if (XMLHttp.readyState == 4) {
   window.alert("Returned data: " +
                XMLHttp.responseText);
 }
}
XMLHttp.send(null);
window.setTimeout("timeout();", 7000);

function timeout() {
 if (XMLHttp.readyState != 4 &&
     XMLHttp.readyState != 0) {
   XMLHttp.onreadystatechange = function() { };
   XMLHttp.abort();
   window.alert("Request aborted");
 }
}
</script>
Wait until 7 seconds and a javascript alert will tell you that request is aborted.

Hope this helps.

Accessing CSS Styles Using JavaScript

Monday, June 16, 2008

Almost any css properties can be set by javascript using the name of the css property as the Javascript property. The problem is, some characters like the dash("-") are not allowed within a JavaScript property. And we all know that CSS has many properties that contain dash in them, like font-family and border-right. Therefore, Javascript uses a lowerCamelCase syntax, which means that every component starts with an uppercase letter, but not the very first one. So font-family in CSS can be set using fontFamily property in Javascript.

There are 2 common ways to access CSS on the page: 1. using event handlers of HTML attributes and submitting a reference to the current element as parameter, like onClick="handler(this)". 2. accessing the element directly using document.getElementById("elementName")

Here's an example of the first approach:

<script language="javascript">
function useVerdana(elementName){
elementName.style.fontFamily="verdana";
}
</script>
<p id="myelement" onClick="useVerdana(this)">This is the element content</p>


And here's an example of the second approach, doing exactly the same thing:
<script language="javascript">
function useVerdana(){
var elementName=document.getElementById("myelement");
elementName.style.fontFamily="verdana";
}
</script>
<p id="myelement" onClick="useVerdana()">This is the element content</p>


And remember, there's NO DASH in javascript property!. That's actually the moral of this story.

Hope this helps,

AJAX In A Glance

Sunday, June 15, 2008

You can find a bunch of definition and AJAX howtos through google, I'm just adding up with this simple and quick of what, how, and why should you use AJAX in your web application.

The heart of AJAX is XMLHttpRequest object. It's supported by all AJAX-enabled browser natively, except in IE before version 7 you need to use the ActiveX object. Therefore, while in other AJAX-enabled browser we use
XMLHttp = newXMLHttpRequest();
in IE version 6 and earlier we use
> XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
And so the best approach to create the object in cross-browser application is by using try... catch to instantiate the native object first, and then the activeX version, simply like this

>
function getXMLHttp() {
var XMLHttp = null;
if (window.XMLHttpRequest) {
 try {
   XMLHttp = new XMLHttpRequest();
 } catch (e) { }
} else if (window.ActiveXObject) {
 try {
   XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (e) {
   try {
     XMLHttp = new ActiveXObject(
       "Microsoft.XMLHTTP");
   } catch (e) { }
 }
}
return XMLHttp;
}

And here's how you use it, take a look at how AJAX send a GET method
<script language="JavaScript" type="text/javascript">

function getXMLHttp() {
var XMLHttp = null;
if (window.XMLHttpRequest) {
 try {
   XMLHttp = new XMLHttpRequest();
 } catch (e) { }
} else if (window.ActiveXObject) {
 try {
   XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (e) {
   try {
     XMLHttp = new ActiveXObject(
       "Microsoft.XMLHTTP");
   } catch (e) { }
 }
}
return XMLHttp;
}

var XMLHttp = getXMLHttp();
XMLHttp.open("GET", "somefile.php");
XMLHttp.onreadystatechange = function () {
if (XMLHttp.readyState == 4) {
  window.alert("Returned data: "+XMLHttp.responseText);
}
else
//here's where you put your loading message.
}

XMLHttp.send(null);

</script>

The above code is just a simply do a GET method from file somefile.php and show the value on javascript alert. Without having to reload the whole page, you just send the request using XMLHttp.send and get the returned data from XMLHttp.responseText.

The XMLHttp.readystate==4 means that the request had been done, the complete state is:
0-Uninitialized
1-Loading
2-Loaded
3-Waiting
4-Complete
I won't go deeper, for the complete reference of AJAX I recommend http://www.w3schools.com, it's just a glance afterall.

Hope this helps.

Detecting Browser Type

Saturday, June 14, 2008

Since some css/don't run the same way on every browser, sometimes you have to detect what browser type is your visitor using, then decide what to do to your visitor accordingly.

The navigator JavaScript object provides browser informations, the most useful, but also sometimes not-easy to parse, is its userAgent property, which contains the complete browser identification string that is also sent in the HTTP User-Agent header with each request.

If you just want to determine the browser type, the window.alert(navigator.appName) will suffice, however the value returned is not always correct so you still have to look to the navigator.userAgent like this:<> br /

<script language="JavaScript" type="text/javascript">
var uA = navigator.userAgent;
var browserType = "unknown";
if (uA.indexOf("Opera") > -1) {
 browserType = "Opera";
} else if (uA.indexOf("Safari") > -1) {
 browserType = "Safari";
} else if (uA.indexOf("Konqueror") > -1) {
 browserType = "Konqueror";
} else if (uA.indexOf("Gecko") > -1) {
 browserType = "Mozilla";
} else if (uA.indexOf("MSIE") > -1) {
 browserType = "Internet Explorer";
}
window.alert(browserType);
</script>

As you can see, opera is checked first since the browser can identify itself as another browser. The point here is, with some effort to userAgent you can extend the script to detect more than just the name of the browser type, you can even get the version or the derivatives(with example as mozilla: k-meleon, firefox, ephipany, camino, etc).

More references can be found in http://www.webreference.com/tools/browser/javascript.html and http://gemal.dk/browserspy/basic.html

Hope this helps.

Debugging CSS and Browser Issues

Friday, June 13, 2008

Perhaps, the best tool I can recommend to debug CSS is firefox's Firebug and Web Developer Add-Onns. But sometimes they're just not enough, so I will give you a quick step by step manual of how to debuggin your css code and browser issues.

First, validate your HTML code. Go to http://validator.w3.org/ and simply correct every errors you may find. just copy paste the error to google and with some efforts you'll get the solution how to fix them.

Second, validate your CSS. Go to http://jigsaw.w3.org/css-validator/ and do the same thing as you do with your HTML code.

Third, simplify your CSS. Add new rule at the end of your stylesheet, using global selector and set properties for all elements, like this:

*{
margin: 0;
padding: 0;
}

Then, give border to every block-element so it become like this:
*{
margin: 0;
padding: 0;
border: solid 1px #000000
}

Comment out any css rule you suspect causing the errors, do it one-by-one until the problem recurs, and finally:

Find and research any similar problem through google. You may found some css bugs are well mentioned at expert-exchange. and http://www.positioniseverything.net/.

Hope that helps.

Ampersand(&) Issue on Oracle/PLSQL

Wednesday, June 11, 2008

Have you ever tried to insert a value to a column that contains ampersand(&) character? I have, and it's not working when i use the usual way. Ampersand character is made for input variable, so If you write query like
insert into tbl_name(column1, column2) values('me & you', 'him & her' )
a menu popup will show up asking you for a value.

A workaround for this annoying problem is using SET DEFINE OFF before the query, or using the SET ESCAPE, or editing the [orahome]/sqlplus/admin/glogin.sql to SET SCAN OFF, but those methods only work on SQL*Plus,unfortunately.

Other simple solution for this is by putting the ampersand at the end nex to a single quote, so the the previous query above would rather be insert into tbl_name(column1, column2) values('me &'||' you', 'him &'||' her). Don't ask me why.

If you're using ASP/PHP/{insert your favorite programming language here}, don't forget to replace the ampersand with the %26 character. It would be even better if you double check it on client side and server side. I believe every programming language out there have a built-in function for string replacement, eh ?

Anyway, hope this helps,

!important on CSS

Friday, June 6, 2008

When a css rule is specified two or more in a document, browser will use the last one. So if we have code like this

body{
text-align: center;
text-align: justify
}
The browser will make text alignment inside the body to be justified. Overriding the text-align: center; part before. With !important, you can define a rules without having to worry some other rules will override it. So if you make the code like this
body{
text-align: center !important;
text-align: justify
}
The text alignment inside the body will be centered, even when it's defined justify on the line below it.

But here comes the best part..

IE6 and the previous versions ignores the !important code (IE7 doesn't ignore it though.)

But you'll survive, I know I did.

Todo so, you have to use the !important code to avoid non-standard CSS expressions. Here's a classic example of how to specify max/min width with IE6> and other browser. As you may know, IE6 doesn't support the max-width declaration.
body {
margin: 0 auto 0;
max-width: 800px;
min-width: 600px;
width:auto !important;
width:800px;
}
It may not solve the problem entirely, but IMHO, it's better than using non-standard code for IE6 like _width or _height. Happy coding

Fieldset and legend on IE6 and Firefox

Wednesday, June 4, 2008

Take a look at this simple css and html code, here's the css code:

fieldset{
background-color: #c0c0c0;
}
and here's the HTML part:
<fieldset>
<legend>Legend</legend>
<label for="something">something</label>
<input name="something" type="text">
</fieldset>
On firefox, it will be viewed like this:
fieldset standard in firefox
While on IE6, it will be viewed like this:
fieldset standard in IE6
And that's quite irritating. I don't know about other browser like safari and opera, but so far, here's a a quick code to solve the problem. You only need to change the css code.
fieldset {
display: block;
background-color: #c0c0c0;
position: relative;
}

legend {
padding: 0;
position: relative;
/* this works for IE6, to move up the legend */
top: -0.7em;
}

/* Hide this rule from IE */
legend {
/* on Gecko based browser we move the legend up with this */
margin-bottom: .3em;
}
The result is like this in Firefox:

And in IE6:

Finally, the background color in IE6 is not exceeded the top border, you can adjust the position of the content by adjusting the number yourself, I'm sure everybody is quite familiar with that.

SetAttribute on IE6 and firefox

Thursday, May 29, 2008

Say, you want to create an element using javascript with code like

<div class="myClass" onClick="myFunction()">inner HTML</div>
Now, the way to do it in firefox is by simply using javascript setAttribute like this:
<script language="javaScript">
element = document.createElement("div");
 element.appendChild(document.createTextNode("inner HTML"));
 element.setAttribute("class", myClass");
 element.setAttribute("onClick", "myFunction()");
</script>

But on Internet Explorer, that code won't work. It's broken. The class part should be written className on IE, so instead of >element.setAttribute("class", myClass"); it should be >element.setAttribute("className", myClass");, and what if you have many element attributes that you don't know whether they're applied the same way on IE and firefox ? like >style, id, name, on{Change, MouseOver, etc} ?

So far, here's the quick solution to do it, it's only a try catch block actually :
>
<script language="javaScript">
try {
   element = document.createElement("<div class=\"myClass\" onclick=\"myFunction()\">");
   element.appendChild(document.createTextNode("inner HTML"));
 } catch (e) {
   element = document.createElement("div");
 element.appendChild(document.createTextNode("inner HTML"));
 element.setAttribute("class", myClass");
 element.setAttribute("onClick", "myFunction()");
 }
</script>


Quite quick, eh ?