
I just hit this barrier and for a moment lapsed into a state of complete despair. I thought "surely there must be a way for me to assign my own javascript events to ASP controls that I create at runtime". I know it's possible to assign an .OnClientClick property to an ASP:Button but there is mysteriously no such property on ASP:CheckBox controls.
But I wasn't finding anything. There are a few hackish workarounds, that involve creating control trees with overlapping controls that can receive onclick events, and tricking the end user into thinking they are clicking your checkbox when in fact they are are clicking something else, that then does a bunch of voodoo behind the scenes and "solves" your problem; but looking at those solutions started making me seasick. I tend to be overly optimistic in my belief that all of these things are possible and even easy, to someone who looks hard enough.
Now the core of my dilemma is the runtime part. One of the more simple hackabout fixes involves just sticking an onclick="alert('chowder');" into the ASP:CheckBox tag on the designer form, however if you're psychotic like me and create the majority of your controls dynamically at runtime, you have no such luxury.
<ASP:CheckBox runat="server" ID="myCheckBox" onclick="alert('chowder');" />
This one works because the CheckBox control doesn't have an onclick event (like the Button does), so the ASP engine just ignores the attribute and sends it to the browser as is. Some folks who are much smarter that I am explain it pretty well here.
After some poking around with the internet without any luck, the answer struck me. The onclick attribute is just that, an attribute! So all I needed to do was use the .Attributes collection that is a part of any WebControl, since it is part of the base WebControl type.
Therefore, my solution in the end was frighteningly simple:
myCheckBox.Attributes["onclick"] = "Alert(\"chowder!\");";
By using the .Attributes collection, the attribute was handed down directly to the HTML without any tinkering from ASP. Using that, you can add just about any attribute to your HTML when it renders, all at runtime!
I've seen this question come up a couple of times and so I thought I'd take a shot at it.
"How do I change the text in a password field from readable text to the password dots in real time?"
Of course the first answer is to use jquery, and that would be a good solution. However, where is the fun in doing that? Not to mention all the overhead of loading in a huge JS library to perform one simple task.
So enter the raw solution, no libraries just JavaScript, naked and beautiful. Normally, this would be an even easier solution, all you have to do is switch the "type" property of the text box from "text" to "password" on the fly and you're done, however that won't work in IE thanks to a clever decision in Seattle to make the "type" property read only once an element has been added to the DOM. So what we have to do is actually remove the element and create a replacement, and then swap in the replacement on the go.
HTML:
<input type="text" name="inpPass" id="inpPass" value="Password"/>
JavaScript:
var inpPass = document.getElementById("inpPass");
inpPass.onfocus = function() {
if(this.getAttribute("type") == "text") {
var newInp = document.createElement('input');
newInp.onfocus = this.onfocus;
newInp.onblur = this.onblur;
newInp.ID = 'inpPass';
newInp.name = 'inpPass';
newInp.setAttribute('type', 'password');
this.parentNode.appendChild(newInp);
this.parentNode.removeChild(this);
newInp.focus();
}
}
inpPass.onblur = function() {
if(this.value == "") {
var newInp = document.createElement('input');
newInp.onfocus = this.onfocus;
newInp.onblur = this.onblur;
newInp.ID = 'inpPass';
newInp.name = 'inpPass';
newInp.setAttribute('type', 'text');
newInp.value = "Password";
this.parentNode.appendChild(newInp);
this.parentNode.removeChild(this);
}
}
If you read through the above code you can see that a new element is created, it borrows the event handlers from its predecessor, we set its name and ID, and we place it on the form right after we blow up the original.
The necessity of keeping myself employed has forced me to have to learn several programming languages over the years and I find myself rapidly jumping back and forth between them as I swing from project to project. Naturally this creates a whole variety of entertaining issues and syntax errors as I sort myself out each time; and one of the most frequent things that I get myself tripped up with is the lack of a reliable trim function in JavaScript. Now you may contend here that FireFox has a trim function for JavaScript and I'm pretty sure Chrome does too, and that's just swell - but IE does not. In the way I like to work if something is not supported by all of the major browsers its off the table for my projects; this idea may seem a little limiting because that means throwing out a whole assortment of cool stuff that each browser can do but I don't like the idea that each visitor may have a different experience depending on their browser selection. I'll be honest here and say this stems from not a small amount of laziness too, because I hate to have to write in error handling with comments next to it like "This only works in IE so we have to trap the exception for other browsers."
Stepping down from the soapbox and back to my idea: Most other major languages have some kind of trim function built in (that is a function that you can run against a string to "trim" the whitespace off of the start and end of it) and I tend to get a little spoiled by them, so recently when I was back working in JS and hit this same issue I decided it was time to write my own and rid myself of this issue once and for all.
This is where it gets fun. To break down what a trim function does is pretty straight forward, we want it to first remove any whitespace from the beginning of a string and then second remove any whitespace from the end of it. The best way to do this quickly and efficiently is with regular expressions.
The JavaScript RegEx I wrote for this looks like this:
string.replace(/\s*/, "").replace(/\s*$/, "");
So that's the first half, now the cool part.
You can do this in two ways, either create a traditional function that takes a string as an argument and returns the trimmed string like so:
function trim(InputString) {
return InputString.replace(/\s*/, "").replace(/\s*$/, "");
}
Or you can use the JavaScript prototype property and add the trim function to the String base type, like so:
String.prototype.trim = function() {
return this.replace(/\s*/, "").replace(/\s*$/, "");
};
Using the prototype method, you have done two things that I think are pretty cool: you have added the ability to quickly trim any string, and you have added that ability to your JavaScript code no matter what browser you are using. Now whenever you have a String type variable you can simply call your variable with .trim() and viola: you have a trimmed string. For example:
var MyString = " this is my string with lots of white space ";
alert("No Trim: [" + MyString + "]");
alert("Trim: [" + MyString.trim() + "]");
Type some text with whitespace around it into the field below and click here to see it get trimmed.
Earlier today I was trying to test something on my Linux server and to do so I needed a way to do a quick, custom MD5 hash and look at the output. My first thought was to write a simple PHP page and toss it up on my web server and look at it there, but then I got to thinking that there is no reason I shouldn't be able to just do it form the command line. PHP after all is just a CGI engine and can parse your scripts whether they come from the command line or Apache.
After a little digging by doing a var_dump($GLOBALS) I found a global variable called $argv, this variable holds an array of all of the command line arguments that were passed, including the filename, to the php script in order.
So if you call your script like this:
./script.php 1 two horse plant
You will have an array in $argv that looks like this:
array(5) {
[0]=> string(12) "./script.php"
[1]=> string(1) "1"
[2]=> string(1) "2"
[3]=> string(5) "horse"
[4]=> string(5) "plant"
}
Using the $argv array, you can easily capture anything that is passed to the script and then do whatever you please with it, allowing for quick and easy command line scripts using the simplicity and power of PHP.
In the end my script (named md5.php) looked like this:
#!/usr/bin/php
<?php
echo $argv[1].':['.md5($argv[1]).']'."\r\n";
?>
This script returns a hash of the first argument plus the argument itself in this form ARG:[HASH].
For example:
./md5.php taco
Returns:
taco:[f869ce1c8414a264bb11e14a2c8850ed]
I've worked a variety of projects on a variety of platforms with a variety of other developers and I've noticed a distressing trend: passwords stored in plain text. Hashing passwords is an old concept but it's one that seems to be forgotten frequently.
The usual reasoning for plain text passwords is pretty straightforward: the database is secure, usually buried behind a battery of firewalls, armed guards, snake pits, and ancient riddles - ergo the passwords are secure. Secondly and almost as importantly: it's so much easier for a developer to work with passwords that are stored in plain text, so why create all the overhead and grief of having to handle encryption when you don't have to?
There are more reasons why this is a bad practice beyond the obvious.
First (the obvious) is your passwords are in plain text, and above the simple unethical nature of the developer being able to see what everyone's password is, anyone who can query the database can read everyone's passwords. Why is this a big deal? Most end users will use the same password for just about everything, so while you are developing a system to do some simple business task the password they are using for it will be the same password they have on their email, social sites, and frighteningly their bank. But I have snake pits and firewalls that protect my database, nobody malicious will get at them right? Perhaps, but what about all the developers in your environment? Infrastructure people who run backups? Contractors who are adding to your IT environment and get access to your databases? End users who have been given direct permissions to the database for reporting or some other need? The larger your environment the more people that can likely see into that data if they try hard enough.
Now, the less obvious and more technical reason: a hashed password does not need to be cleaned and checked as vigorously as text would be for attempts at data insertion attacks such as SQL injection. So in a system where we are hashing our passwords I can make my password ");DROP TABLE users;" and it would work just fine without causing any trouble, since that string never makes it to the database. This actually makes life easier on the developer than dealing with the passwords in plain text.
Secondly, when you use a known algorithm to hash your passwords, you will know exactly what the character length will be for storing the value in your database so you can set the length of the database field to be just what you need and have nice predictable data in it, making integrity checks and the like much easier.
Why hash, and why salt, and why oh why?
When we say "hash" what we mean is to run the password string through a known algorithm such as MD5 or SHA1. Each of these will translate any binary string into a new fixed-length string that fits within a certain range of values; in short this means you translate the password into something unreadable and easily storable. A hash is one-way, which means once you hash you cannot un-hash - there is no means to generate the original string from a hash value. This means that if someone queries your database and gets a list of users and passwords, they can't do anything with the passwords, they'll all effectively be junk.
As I've said, a hashed value cannot be un-hashed, so when you are writing your login system you clearly will not be able to compare the text of the entered password to the hash in the database, but you can compare a hash of the entered password to the value stored in the database: if they match, you've got a good login and you never need to store the plain text password.
Back in the world of the attacker, there are things called Rainbow Tables that force us developers to take an extra step in securing our passwords. A Rainbow Table is very simply a tremendous list of potential passwords, dictionary words, etc that have all been matched with an MD5 hash. If an attacker has been able to query your data, they can then use their Rainbow Table to compare the hashes stored in your database against the hashes on their table, and match up passwords from there. To prevent this we have to "salt" our hashed passwords, meaning we take a known value and append it to the password before we hash it and store, then do the same when comparing for authentication; this prevents matching against a Rainbow Table since the hash results of your users passwords will be varied by the salt you applied.
Following this process is relatively simple and can prevent a lot of headache later on down the road. As always these techniques should be coupled with strong password requirements and other security policies in your environment - and remember the golden rule: No application is too small or too insignificant to apply good security techniques.
For any developer one of the most tedious things while developing sites is form validation, and beyond the tedium is a way to make it look good and interact well with the end user. We built the Tk Validation library to make some of this validation easier, specifically for the client side. Naturally, a JavaScript solution is not by any means a replacement for server side validation but often times we want the end user to complete more fields than what is truly necessary to ensure the integrity of the post receiver process.
Enter the Tk Validation library. To use it all you need to do is add it (of course) to your page, and then append the appropriate class name to each input field that you want to validate. The idea is to minimize the amount of JS that actually needs to be inserted into the page, so by using the class names for each input (which will legally accept multiple values) it simplifies the process for the developer. In fact, you do not need to know anything about JavaScript to use this!
The various classes that we can add are:
| Class Name | Validation Function |
|---|---|
| tk_text | Simply require some kind of string value in the input |
| tk_posint | Require a positive integer value |
| tk_anynum | Any numeric value |
| tk_currency | Require a currency value, and will convert any numeric value to currency or a non numeric value to 0 |
| tk_email | Email address |
| tk_match([id of object to match]) | Match another input (good for email confirmation or password confirmation); enter the ID of the other input in parentheses to check against. This works best if you set the other input to require a value. |
| tk_dropdown([value that is not valid])etc) | Force a selection from a dropdown |
| tk_chars([integer number of minimum characters]) | Require a certain number of characters (set the number with an integer in parentheses |
| tk_phone([delimeter to be inserted after validation]) | Require a phone number, this will format using the delimiter that you enter inside the parentheses |
| tk_submit | This is the submit button on the form, setting this will force a check of all fields before the form is submitted. Additionally this inpu will be enabled on page load, so you should set it to be disabled by default. This way, if someone has JavaScript disabled they will not be abe to submit the form. |
Give Infotekka the thumbs-up on Facebook and share it with your friends!
Download a copy of Infotekka's super-high-budget self signed wildcard certificate to eliminate all those pesky SSL warnings. It's OK, you can trust us.
Click here to download the compressed certificate and then install it on your computer.
Infotekka's JavaScript real time form validation library, Tk Validation, is available for review and release here!