Okay folks. I've found this interesting article on PC Magazine. Personally, I've been using Google's OpenSocial API recently, and actually is a blessing for developers, but what O'reilly have to say about it its a kick in the balls, and I gotta say, the man have a point!
http://www.pcmag.co.uk/vnunet/news/2202974/father-web2-denounces-google
Saturday, August 23, 2008
[.js] FormValidator v1.0
Hey folks!. I'm glad to announce that I finally finished my own version of a FormValidator for javascript. this is just a simple but well made class which is open to improvements.
the code comes well commented, but in case you have any doubt, please free to post it.
I'll post later some examples I've made using this class. hope you enjoy it. (it's not the most complete FormValidator on the web, but it's very easy to use and very functional.
I'll try to make some improvements to this class in the future so stay tuned for new versions.
By the way, at the moment, it supports simple callbacks after form has been validated. I think this'll help you to implement this code very easy without much changes to your original code.
another thing: this form uses the String.prototype.trim() function implementation posted before. so be sure to copy it and include it before including FormValidator:
<script language="javascript" type="text/javascript" src="trim.js"></script>
<script language="javascript" type="text/javascript" src="FormValidator.js"></script>
/////**** [mk]FORM VALIDATOR v1.0 ****\\\\\\
/////////////////////////////////////////////////
//by MasterKitano kitanosblog.blogspot.com 2008//
/////////////////////////////////////////////////
/*Use var myForm = new FormValidator("form"); to creat a new form validator, where "form" is your form id.
use myForm.addValidation(obj_id,val_type,message) to add a new validation.
obj_id : your object id to validate (your object most be inside the form).
val_type: type of validation-> null: checks if the value is empty
minlen: minimun value length (e.g "minlen=10")
maxlen: maximum value length (e.g "maxlen=10")
selected: (only for selects) checks if a option is selected (e.g. "selected=option_id")
nospaces: checks if value contains spaces (e.g. "nospaces")
alpha: checks if value contains only alphanumeric (letters and digits) (e.g. "alpha")
numbers: checks if value contains only numbers (e.g. "numbers")
mail: checks if value contains @, and a . after @.
message: the message that will be shown on the error messages window.
use myForm.addclearBtn("buton_id"); to automatically set a reset button.
use myForm.addSendBtn("buton_id",callback); to automatically set a send Button. this will perform validation, and if form is valid, then executes a callback to any function
use myForm.form.theElement or use myForm.form["element"] to access to any element in your form.
override myForm.prototype.displayErors() tho show the errors anyway yo want.
//HANDILNG ERROR MESSAGES
use myForm.invalid_form_msg ="error message"; to set default form error message.
use myForm.ERRORS_TAIL array to check all validation error messages.
use myForm.ERRORS_TAIL[index] to acces some specific message. (e.g. myForm.ERRORS_TAIL[0]);
*/
function FormValidator(form){
this.form = document.getElementById(form); //the handled form
this.invalid_form_msg = "data form error";
this.validation = true;
this.validationObjs = Array(); //objects to be validated
this.ERRORS_TAIL = Array(); //contains all error strings
this.addValidation = addValidation; //function to put a new validation on the validations tail
this.doValidation=doValidation; //checks al validations objects and confirms they're valid
this.addSendBtn = addSendBtn; //add send event to a button so we can send data (AJAX is supported) once is confirmed, second parameter defines a callback
this.displayErrors = displayErrors;//display the validation errors
this.clearData = clearData; //clears all the data information and restores it to the default
this.addClearBtn = addClearBtn; // add clear data event to a button so we can clear the form
}
function addValidation(obj_id,val_type,message){
var valid_exist = false;
if(message==null){
message = "unidentified error";
}
//make sure we create only one instance for every input object in the form
if(this[obj_id]==null){
this[obj_id]= new Object();
this[obj_id].elt = this.form[obj_id];
this.validationObjs.push(this[obj_id]); //add the object to the validations tail
this[obj_id].validations = Array(); //tail of validations to be performed to the object
this[obj_id].messages= Array(); //messages to be shown if validations didn't succeded
}
//make sure to have only one instance for every validation to be performed on the object
for(var i =0; i<this[obj_id].validations.length;i++){
var temp_value = this[obj_id].validations[i];
if(temp_value.indexOf("=")>=0){temp_value = temp_value.substr(0,temp_value.indexOf("="))}
var temp_value2 = val_type;
if(temp_value2.indexOf("=")>=0){temp_value2 = temp_value2.substr(0,temp_value2.indexOf("="))}
if(temp_value==temp_value2){
val_found=i;
valid_exist=true;
}
}
//create the validation instance only if it didn't existed before...
if(!valid_exist){
this[obj_id].validations.push(val_type);
this[obj_id].messages.push(message);
//or else, we just change the previos message to the newest (this can also be performed using attribute form.object.messages[validation number] = 'new message';
}else{
this[obj_id].validations[val_found]=val_type;
this[obj_id].messages[val_found]=message;
}
//alert(this[obj_id].validations);
}
function doValidation(){
this.validation = true;
//clear the errors tail;
this.ERRORS_TAIL = Array();
//START THE VALIDATION
for(var i=0; i<this.validationObjs.length;i++){
for(var j=0; j<this.validationObjs[i].validations.length;j++){
show_msg=false;
//CHECK IF INPUT OBJECTS VALUES ARE NULL OR UNCHECKED
if(this.validationObjs[i].validations[j] == "null"){
switch(this.validationObjs[i].elt.type){
case 'checkbox': case 'radio': if(!this.validationObjs[i].elt.checked){show_msg = true;}
break;
case 'password': case 'text': case 'textarea': if(this.validationObjs[i].elt.value==null || this.validationObjs[i].elt.value.trim().length<=0){show_msg = true};
break;
case 'select-one':if(!this.validationObjs[i].elt.value.trim()){show_msg = true};
break;
default :
//RADIO GROUPS
if(!this.validationObjs[i].elt.type && this.validationObjs[i].elt.length){
show_msg = true;
for(var x=0; x<this.validationObjs[i].elt.length;x++){
if(this.validationObjs[i].elt[x].checked){
show_msg=false;
}
}
}
break;
}
}
//CHECK INPUT OBJECTS VALUES MIN LENGTH
if(this.validationObjs[i].validations[j].substr(0,this.validationObjs[i].validations[j].indexOf("=")) == "minlen"){
var minlength = this.validationObjs[i].validations[j].substr(this.validationObjs[i].validations[j].indexOf("=")+1);
if(this.validationObjs[i].elt.value.trim().length<minlength){
show_msg = true;
}
}
//CHECK INPUT OBJECTS VALUES MAX LENGTH
if(this.validationObjs[i].validations[j].substr(0,this.validationObjs[i].validations[j].indexOf("=")) == "maxlen"){
var maxlength = this.validationObjs[i].validations[j].substr(this.validationObjs[i].validations[j].indexOf("=")+1);
if(this.validationObjs[i].elt.value.trim().length>maxlength){
show_msg = true;
}
}
//CHECK OPTION ON SELECT
if(this.validationObjs[i].validations[j].substr(0,this.validationObjs[i].validations[j].indexOf("=")) == "selected"){
var selected = this.validationObjs[i].validations[j].substr(this.validationObjs[i].validations[j].indexOf("=")+1);
if(this.validationObjs[i].elt[this.validationObjs[i].elt.selectedIndex].id==selected){
show_msg = true;
}
}
//CHECK INPUT OBJECTS WHITE SPACES
if(this.validationObjs[i].validations[j]== "nospaces"){
if(this.validationObjs[i].elt.value.trim().indexOf(" ")>=0){
show_msg = true;
}
}
//CHECK INPUT OBJECTS FOR NON ALPHANUMERIC CHARACTERS
if(this.validationObjs[i].validations[j]== "alpha"){
var string = this.validationObjs[i].elt.value.trim();
var regexp = /\W/;
var result = regexp.test(string);
if(result){
show_msg = true;
}
}
//CHECK INPUT OBJECTS FOR NON NUMBERS CHARACTERS
if(this.validationObjs[i].validations[j]== "numbers"){
var string = this.validationObjs[i].elt.value.trim();
var regexp = /\D/;
var result = regexp.test(string);
if(result){
show_msg = true;
}
}
//CHECK E-MAIL
if(this.validationObjs[i].validations[j]== "mail"){
var string = this.validationObjs[i].elt.value.trim();
var at = string.indexOf('@');
var dot = string.indexOf('.',at);
if(at>=0 && dot>at){
}else{
show_msg = true;
}
}
//IF ERROR HAPPENED THEN PUSH THE MESSAGE TO THE ERRORS TAIL
if(show_msg){
this.ERRORS_TAIL.push(this.validationObjs[i].messages[j]);
this.validation = false;
}
}
}
return this.validation;
}
function addSendBtn(btn,callback_function){
var send_button = this.form[btn];
send_button.parentObj = new Object();
send_button.parentObj = this;
send_button.onclick = function(){
var formValidation = this.parentObj.doValidation();
if(formValidation){
callback_function();
}else{
this.parentObj.displayErrors();
}
}
}
function addClearBtn(btn){
var clear_button = this.form[btn];
clear_button.parentObj = new Object();
clear_button.parentObj = this;
clear_button.onclick = function(){
this.parentObj.clearData();
}
}
function clearData(){
for(var i=0; i<this.form.length;i++){
switch(this.form[i].type){
case 'text': case 'password': case 'textarea': this.form[i].value = "";
break;
case 'radio': case 'checkbox': this.form[i].checked = false;
break;
case 'select-one': this.form[i][0].selected = true;
break;
}
}
}
function displayErrors(){
///MODIFY ONLY THIS PORTION OF THE CODE!
///THIS METHOD CAN BE OVERRIDED TO DISPLAY THE ERRORS THE WAY YOU WANT
var errors_msg = this.invalid_form_msg+"\n";
for(var i=0; i<this.ERRORS_TAIL.length;i++){
errors_msg+="\n-"+this.ERRORS_TAIL[i];
}
alert(errors_msg);
}
the code comes well commented, but in case you have any doubt, please free to post it.
I'll post later some examples I've made using this class. hope you enjoy it. (it's not the most complete FormValidator on the web, but it's very easy to use and very functional.
I'll try to make some improvements to this class in the future so stay tuned for new versions.
By the way, at the moment, it supports simple callbacks after form has been validated. I think this'll help you to implement this code very easy without much changes to your original code.
another thing: this form uses the String.prototype.trim() function implementation posted before. so be sure to copy it and include it before including FormValidator:
<script language="javascript" type="text/javascript" src="trim.js"></script>
<script language="javascript" type="text/javascript" src="FormValidator.js"></script>
/////**** [mk]FORM VALIDATOR v1.0 ****\\\\\\
/////////////////////////////////////////////////
//by MasterKitano kitanosblog.blogspot.com 2008//
/////////////////////////////////////////////////
/*Use var myForm = new FormValidator("form"); to creat a new form validator, where "form" is your form id.
use myForm.addValidation(obj_id,val_type,message) to add a new validation.
obj_id : your object id to validate (your object most be inside the form).
val_type: type of validation-> null: checks if the value is empty
minlen: minimun value length (e.g "minlen=10")
maxlen: maximum value length (e.g "maxlen=10")
selected: (only for selects) checks if a option is selected (e.g. "selected=option_id")
nospaces: checks if value contains spaces (e.g. "nospaces")
alpha: checks if value contains only alphanumeric (letters and digits) (e.g. "alpha")
numbers: checks if value contains only numbers (e.g. "numbers")
mail: checks if value contains @, and a . after @.
message: the message that will be shown on the error messages window.
use myForm.addclearBtn("buton_id"); to automatically set a reset button.
use myForm.addSendBtn("buton_id",callback); to automatically set a send Button. this will perform validation, and if form is valid, then executes a callback to any function
use myForm.form.theElement or use myForm.form["element"] to access to any element in your form.
override myForm.prototype.displayErors() tho show the errors anyway yo want.
//HANDILNG ERROR MESSAGES
use myForm.invalid_form_msg ="error message"; to set default form error message.
use myForm.ERRORS_TAIL array to check all validation error messages.
use myForm.ERRORS_TAIL[index] to acces some specific message. (e.g. myForm.ERRORS_TAIL[0]);
*/
function FormValidator(form){
this.form = document.getElementById(form); //the handled form
this.invalid_form_msg = "data form error";
this.validation = true;
this.validationObjs = Array(); //objects to be validated
this.ERRORS_TAIL = Array(); //contains all error strings
this.addValidation = addValidation; //function to put a new validation on the validations tail
this.doValidation=doValidation; //checks al validations objects and confirms they're valid
this.addSendBtn = addSendBtn; //add send event to a button so we can send data (AJAX is supported) once is confirmed, second parameter defines a callback
this.displayErrors = displayErrors;//display the validation errors
this.clearData = clearData; //clears all the data information and restores it to the default
this.addClearBtn = addClearBtn; // add clear data event to a button so we can clear the form
}
function addValidation(obj_id,val_type,message){
var valid_exist = false;
if(message==null){
message = "unidentified error";
}
//make sure we create only one instance for every input object in the form
if(this[obj_id]==null){
this[obj_id]= new Object();
this[obj_id].elt = this.form[obj_id];
this.validationObjs.push(this[obj_id]); //add the object to the validations tail
this[obj_id].validations = Array(); //tail of validations to be performed to the object
this[obj_id].messages= Array(); //messages to be shown if validations didn't succeded
}
//make sure to have only one instance for every validation to be performed on the object
for(var i =0; i<this[obj_id].validations.length;i++){
var temp_value = this[obj_id].validations[i];
if(temp_value.indexOf("=")>=0){temp_value = temp_value.substr(0,temp_value.indexOf("="))}
var temp_value2 = val_type;
if(temp_value2.indexOf("=")>=0){temp_value2 = temp_value2.substr(0,temp_value2.indexOf("="))}
if(temp_value==temp_value2){
val_found=i;
valid_exist=true;
}
}
//create the validation instance only if it didn't existed before...
if(!valid_exist){
this[obj_id].validations.push(val_type);
this[obj_id].messages.push(message);
//or else, we just change the previos message to the newest (this can also be performed using attribute form.object.messages[validation number] = 'new message';
}else{
this[obj_id].validations[val_found]=val_type;
this[obj_id].messages[val_found]=message;
}
//alert(this[obj_id].validations);
}
function doValidation(){
this.validation = true;
//clear the errors tail;
this.ERRORS_TAIL = Array();
//START THE VALIDATION
for(var i=0; i<this.validationObjs.length;i++){
for(var j=0; j<this.validationObjs[i].validations.length;j++){
show_msg=false;
//CHECK IF INPUT OBJECTS VALUES ARE NULL OR UNCHECKED
if(this.validationObjs[i].validations[j] == "null"){
switch(this.validationObjs[i].elt.type){
case 'checkbox': case 'radio': if(!this.validationObjs[i].elt.checked){show_msg = true;}
break;
case 'password': case 'text': case 'textarea': if(this.validationObjs[i].elt.value==null || this.validationObjs[i].elt.value.trim().length<=0){show_msg = true};
break;
case 'select-one':if(!this.validationObjs[i].elt.value.trim()){show_msg = true};
break;
default :
//RADIO GROUPS
if(!this.validationObjs[i].elt.type && this.validationObjs[i].elt.length){
show_msg = true;
for(var x=0; x<this.validationObjs[i].elt.length;x++){
if(this.validationObjs[i].elt[x].checked){
show_msg=false;
}
}
}
break;
}
}
//CHECK INPUT OBJECTS VALUES MIN LENGTH
if(this.validationObjs[i].validations[j].substr(0,this.validationObjs[i].validations[j].indexOf("=")) == "minlen"){
var minlength = this.validationObjs[i].validations[j].substr(this.validationObjs[i].validations[j].indexOf("=")+1);
if(this.validationObjs[i].elt.value.trim().length<minlength){
show_msg = true;
}
}
//CHECK INPUT OBJECTS VALUES MAX LENGTH
if(this.validationObjs[i].validations[j].substr(0,this.validationObjs[i].validations[j].indexOf("=")) == "maxlen"){
var maxlength = this.validationObjs[i].validations[j].substr(this.validationObjs[i].validations[j].indexOf("=")+1);
if(this.validationObjs[i].elt.value.trim().length>maxlength){
show_msg = true;
}
}
//CHECK OPTION ON SELECT
if(this.validationObjs[i].validations[j].substr(0,this.validationObjs[i].validations[j].indexOf("=")) == "selected"){
var selected = this.validationObjs[i].validations[j].substr(this.validationObjs[i].validations[j].indexOf("=")+1);
if(this.validationObjs[i].elt[this.validationObjs[i].elt.selectedIndex].id==selected){
show_msg = true;
}
}
//CHECK INPUT OBJECTS WHITE SPACES
if(this.validationObjs[i].validations[j]== "nospaces"){
if(this.validationObjs[i].elt.value.trim().indexOf(" ")>=0){
show_msg = true;
}
}
//CHECK INPUT OBJECTS FOR NON ALPHANUMERIC CHARACTERS
if(this.validationObjs[i].validations[j]== "alpha"){
var string = this.validationObjs[i].elt.value.trim();
var regexp = /\W/;
var result = regexp.test(string);
if(result){
show_msg = true;
}
}
//CHECK INPUT OBJECTS FOR NON NUMBERS CHARACTERS
if(this.validationObjs[i].validations[j]== "numbers"){
var string = this.validationObjs[i].elt.value.trim();
var regexp = /\D/;
var result = regexp.test(string);
if(result){
show_msg = true;
}
}
//CHECK E-MAIL
if(this.validationObjs[i].validations[j]== "mail"){
var string = this.validationObjs[i].elt.value.trim();
var at = string.indexOf('@');
var dot = string.indexOf('.',at);
if(at>=0 && dot>at){
}else{
show_msg = true;
}
}
//IF ERROR HAPPENED THEN PUSH THE MESSAGE TO THE ERRORS TAIL
if(show_msg){
this.ERRORS_TAIL.push(this.validationObjs[i].messages[j]);
this.validation = false;
}
}
}
return this.validation;
}
function addSendBtn(btn,callback_function){
var send_button = this.form[btn];
send_button.parentObj = new Object();
send_button.parentObj = this;
send_button.onclick = function(){
var formValidation = this.parentObj.doValidation();
if(formValidation){
callback_function();
}else{
this.parentObj.displayErrors();
}
}
}
function addClearBtn(btn){
var clear_button = this.form[btn];
clear_button.parentObj = new Object();
clear_button.parentObj = this;
clear_button.onclick = function(){
this.parentObj.clearData();
}
}
function clearData(){
for(var i=0; i<this.form.length;i++){
switch(this.form[i].type){
case 'text': case 'password': case 'textarea': this.form[i].value = "";
break;
case 'radio': case 'checkbox': this.form[i].checked = false;
break;
case 'select-one': this.form[i][0].selected = true;
break;
}
}
}
function displayErrors(){
///MODIFY ONLY THIS PORTION OF THE CODE!
///THIS METHOD CAN BE OVERRIDED TO DISPLAY THE ERRORS THE WAY YOU WANT
var errors_msg = this.invalid_form_msg+"\n";
for(var i=0; i<this.ERRORS_TAIL.length;i++){
errors_msg+="\n-"+this.ERRORS_TAIL[i];
}
alert(errors_msg);
}
Wednesday, August 20, 2008
[.js] Regular expresions
regular expressions are commonly used to automate tasks that involves strings treatments. they work the same in every language and the syntax is very similar.
in the next example I'll explain how to use basic regexp syntax to implement the trim() function on javascript. if you're interested on learning more about regular expression I suggest to search on google, it's a very common topic, so you'll find plenty information. to get full reference of regexp on javascript I recommend w3Schools
to implement the trim() function we'll use the next modifiers:
^ -> this search character at the beginning of the string.
$ -> this search character at the end of the string.
| -> to select multiple cases (in regexps this works like an OR)
+ -> search for 1 or more matches but not 0.
/ -> end and beginning of a regexp.
g -> Global search. Search all occurrences of the regular expression in a string
there are two ways of creating a regexp on javascript:
1.- creating a regExp object instance: myExpression = new regExp("regexp","patternFlag")
where regexp is our expression and patter flag is a pattern modifier. (se w3schools for full reference).
2.- usign slashes: /myregexp/.
for setting pattern flags just use this syntax> /myregexp/patternflag
e.g. /\s/g
so lets go to the trim example:
we'll use the String replace method to replace a white space with a '' null character.
first we add new method to String.prototype so we can work on it as a native method of String.
String.prototype.trim = function(){
}
then, we start our replace method, as first parameter, leave it in blank, and as second parameter put simply '' and we set it as a return value:
String.prototype.trim = function(){
return this.replace("yet_to_be_defined",'');
}
the first parameter is our regular expression and the second one, the character we want to put instead of the character to be replaced.
to find a white space we use \s, to find white space at the beginning of the string, we use ^\s, to find all characters at the beginning of the string we use ^\s+.
same for the ending characters, but changing the position match character to $ :
\s+$
to check either beginning and ending white spaces, we use | (or) to select between options and the g pattern flag.
/^\s+|\s+$/g
if we don't use the g pattern flag, replace() would only make the match once, and, since we are specifying /^\s+ or \s+$ but not both, it will only trim or the beginning or ending white spaces (by default it selects the first option).
so we use g to specify a global search and find both matches.
so our final code looks like this:
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '');
}
in the next example I'll explain how to use basic regexp syntax to implement the trim() function on javascript. if you're interested on learning more about regular expression I suggest to search on google, it's a very common topic, so you'll find plenty information. to get full reference of regexp on javascript I recommend w3Schools
to implement the trim() function we'll use the next modifiers:
^ -> this search character at the beginning of the string.
$ -> this search character at the end of the string.
| -> to select multiple cases (in regexps this works like an OR)
+ -> search for 1 or more matches but not 0.
/ -> end and beginning of a regexp.
g -> Global search. Search all occurrences of the regular expression in a string
there are two ways of creating a regexp on javascript:
1.- creating a regExp object instance: myExpression = new regExp("regexp","patternFlag")
where regexp is our expression and patter flag is a pattern modifier. (se w3schools for full reference).
2.- usign slashes: /myregexp/.
for setting pattern flags just use this syntax> /myregexp/patternflag
e.g. /\s/g
so lets go to the trim example:
we'll use the String replace method to replace a white space with a '' null character.
first we add new method to String.prototype so we can work on it as a native method of String.
String.prototype.trim = function(){
}
then, we start our replace method, as first parameter, leave it in blank, and as second parameter put simply '' and we set it as a return value:
String.prototype.trim = function(){
return this.replace("yet_to_be_defined",'');
}
the first parameter is our regular expression and the second one, the character we want to put instead of the character to be replaced.
to find a white space we use \s, to find white space at the beginning of the string, we use ^\s, to find all characters at the beginning of the string we use ^\s+.
same for the ending characters, but changing the position match character to $ :
\s+$
to check either beginning and ending white spaces, we use | (or) to select between options and the g pattern flag.
/^\s+|\s+$/g
if we don't use the g pattern flag, replace() would only make the match once, and, since we are specifying /^\s+ or \s+$ but not both, it will only trim or the beginning or ending white spaces (by default it selects the first option).
so we use g to specify a global search and find both matches.
so our final code looks like this:
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '');
}
[.js] String.prototype.trim()
trim() is a very common and very useful function in almost every programming language. basically, it's used to trim or suppress all white spaces at the begging and the end of a given string. e.g: myString = " hello world "; myString.trim() returns: "hello world".
why is this so useful? well, there are many reasons, perhaps the most important is to ensure in the string, that a formal null value is actually a non formal null value. how so? imagine this:
myString = "": the value of myString is a formal null value due to it has no reference to any reserved space on memory.
myString = "hello world": the value of myString is 'hello world';
myString = " ": ??? the value is null?? or not null?;
well it obviously isn't null, due to the character " " is actually A CHARACTER.
but for real purposes, it does seems like a null value, since it has no relevant data. that is a non formal null value.
we use non formal null value in most of our forms: login, register, contact, etc. and we do need to ensure that a non formal null == a formal null.
so how to solve this:
1.- using a for or any kind of cycle to go trough the whole string and check for any white spaces, comparing at the end if whites paces==string length, if so, it means all characters are white spaces therefore its a non formal null.
2.- other way is to check if at least one character of the string is different of white space, else, it's a non formal null.
using any of this two methods isn't quite appropriate and will present a problem:
" hello world " is neither a non formal neither a formal null, how ever, we'll have problems handling this value in case of passwords (e.g. getting max length), or name searches or any sorting methods since it has white spaces at the beginning of the string.
so, trying to implement all methods to solve both problems will take us long time, effort and it'll result an unpractical solution.
so here goes the best solution for solving those problems: using trim(), by suppressing white spaces at the beginning and at the end, we solve both problems at once, e.g.:
myString = " "; myString.trim() returns null; (non formal null solved!)
myString = " hello world "; myString.trim() returns "hello world" (there are no white spaces that provoke future problems like sorting).
that is just great isn't? so go on and try it on any language or script! just type yourString.trim()!.
oh, wait, it just happened you're using javascript? guess what... it has no trim() function implemented on the String object!. sorry folks =(.
but hey, take off those long faces, there is a way to implement it yourself and that is using the prototype of String to add new methods. there are two ways to do this:
1.- using a for or any kind of cycle.
2.- using regular expressions.
I'll let yourself figure out the first one since is quite boring for me to do it =P.
and I'll post the second bellow since is the best and most optimum way and it takes just a simple line!.
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '');
}
I'll make a detailed explanation of the code on my next post, so stay tuned.
mean wile enjoy it =P.
why is this so useful? well, there are many reasons, perhaps the most important is to ensure in the string, that a formal null value is actually a non formal null value. how so? imagine this:
myString = "": the value of myString is a formal null value due to it has no reference to any reserved space on memory.
myString = "hello world": the value of myString is 'hello world';
myString = " ": ??? the value is null?? or not null?;
well it obviously isn't null, due to the character " " is actually A CHARACTER.
but for real purposes, it does seems like a null value, since it has no relevant data. that is a non formal null value.
we use non formal null value in most of our forms: login, register, contact, etc. and we do need to ensure that a non formal null == a formal null.
so how to solve this:
1.- using a for or any kind of cycle to go trough the whole string and check for any white spaces, comparing at the end if whites paces==string length, if so, it means all characters are white spaces therefore its a non formal null.
2.- other way is to check if at least one character of the string is different of white space, else, it's a non formal null.
using any of this two methods isn't quite appropriate and will present a problem:
" hello world " is neither a non formal neither a formal null, how ever, we'll have problems handling this value in case of passwords (e.g. getting max length), or name searches or any sorting methods since it has white spaces at the beginning of the string.
so, trying to implement all methods to solve both problems will take us long time, effort and it'll result an unpractical solution.
so here goes the best solution for solving those problems: using trim(), by suppressing white spaces at the beginning and at the end, we solve both problems at once, e.g.:
myString = " "; myString.trim() returns null; (non formal null solved!)
myString = " hello world "; myString.trim() returns "hello world" (there are no white spaces that provoke future problems like sorting).
that is just great isn't? so go on and try it on any language or script! just type yourString.trim()!.
oh, wait, it just happened you're using javascript? guess what... it has no trim() function implemented on the String object!. sorry folks =(.
but hey, take off those long faces, there is a way to implement it yourself and that is using the prototype of String to add new methods. there are two ways to do this:
1.- using a for or any kind of cycle.
2.- using regular expressions.
I'll let yourself figure out the first one since is quite boring for me to do it =P.
and I'll post the second bellow since is the best and most optimum way and it takes just a simple line!.
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g, '');
}
I'll make a detailed explanation of the code on my next post, so stay tuned.
mean wile enjoy it =P.
Sunday, August 3, 2008
[.js] hiding GET query string
yesterday, a friend asked me if it was possible to hide the GET query string (the string followed by the '?' question mark =P) from the URL, so users visiting the website wouldn't be able to see or catch the sent variables. I came out with various ideas:
The firs and most recommended: use POST instead of GET method xD. while GET shows all query string in the URL and can only send a limited 1kb string, POST method have no limitations and sent variables are hidden.
However, if still you're enough stubborn, I figured out two methods using JS that allows you to hide the GET string:
1.- using AJAX (the hard but preferred method)
use AJAX to send a request, this allows you to send both, GET and POST and get the response
without user can see anything. (I'll submit the code for this latter)
2.- using the BOM (the easy and fast method)
the BOM (Browser Object Modeling) has an object called 'location' which contains the full string of the actual browser location (example: 'http://www.example.com'). location has an attribute called search, the search returns the location starting from the question mark '?' which in our case will be the GET query string.
search can return or set data:
if used as: var query = document.location.search;
will return the search stirng.
if used as: document.location.search="something";
will set the search string to "something".
in this example I used both.
//Clean Search
function cleanSearch(){
if(document.location.search.length>1){
document.location.search="";
}
}
first we check if variables has been sent with GET method:
document.location.search.length>1
if so, then we just clean the search:
document.location.search="";
that easy.
note that:
1.-JS most be enabled in the navigator and the GET query will be shown while the js loads (in any case this will takes a reaaaaaaaaaally few moment to load since are just 6 lines of code).
2.- since you're using document.location.search="", this will cause a web refresh. so the only way to use this code is: geting GET string, using it and then obligatory beeing refreshed. (so if you got the point, you'll realize this has lots of limitances)
any other suggestions are welcome.
hope this'll help.
The firs and most recommended: use POST instead of GET method xD. while GET shows all query string in the URL and can only send a limited 1kb string, POST method have no limitations and sent variables are hidden.
However, if still you're enough stubborn, I figured out two methods using JS that allows you to hide the GET string:
1.- using AJAX (the hard but preferred method)
use AJAX to send a request, this allows you to send both, GET and POST and get the response
without user can see anything. (I'll submit the code for this latter)
2.- using the BOM (the easy and fast method)
the BOM (Browser Object Modeling) has an object called 'location' which contains the full string of the actual browser location (example: 'http://www.example.com'). location has an attribute called search, the search returns the location starting from the question mark '?' which in our case will be the GET query string.
search can return or set data:
if used as: var query = document.location.search;
will return the search stirng.
if used as: document.location.search="something";
will set the search string to "something".
in this example I used both.
//Clean Search
function cleanSearch(){
if(document.location.search.length>1){
document.location.search="";
}
}
first we check if variables has been sent with GET method:
document.location.search.length>1
if so, then we just clean the search:
document.location.search="";
that easy.
note that:
1.-JS most be enabled in the navigator and the GET query will be shown while the js loads (in any case this will takes a reaaaaaaaaaally few moment to load since are just 6 lines of code).
2.- since you're using document.location.search="", this will cause a web refresh. so the only way to use this code is: geting GET string, using it and then obligatory beeing refreshed. (so if you got the point, you'll realize this has lots of limitances)
any other suggestions are welcome.
hope this'll help.
greetings!
welcome in pals!. this is my personal web log of the web programming, in which I intend to show all the tips I've learned in my web programmer experience, and from all other programmers I've met.
some of you, will find them quite basic. but I'll try to submit from the most obvious techniques (data structures, binary search, coding-decoding algorithms, recursive methods) to the most complex and creative ones (design patterns, extreme programming, automates, ANN).
so feel free to send new content and suggestions.
some of you, will find them quite basic. but I'll try to submit from the most obvious techniques (data structures, binary search, coding-decoding algorithms, recursive methods) to the most complex and creative ones (design patterns, extreme programming, automates, ANN).
so feel free to send new content and suggestions.
Subscribe to:
Comments (Atom)