In a previous post entitled Associative Arrays in VB.NET I spoke of using a Collection Object to achieve similar functionality to associative arrays in PHP. Upon further inspection, I feel that the System.Collections.Generic.Dictionary Object (hereafter written as Dictionary Object) is a closer match.
The reason I initially chose to write about the Collection Object is because the Dictionary Object requires all keys to be of the same type, and all values to be of the same type. Of course .NET (both VB.NET and CSharp.NET) is a strongly typed language, whereas PHP is not.
The main advantage a Dictionary has over a regular Collection, is that you can edit items. It also provides a syntax to add items which is similar to that of PHP.
The first step is to add the System.Collections.Generic library to your file, with the following directive:
CSharp.NET
using System.Collections.Generic;
VB.NET
imports System.Collections.Generic
Then you can declare the Dictionary Object: CSharp.NET
<%
Dictionary dict = new Dictionary();
dict["one"] = "First Item";
dict["two"] = "Second Item";
dict["one"] = "Look, I just edited the first Item!";
%>
VB.NET
<%
Dim dict As Dictionary(Of String, String) = New Dictionary(Of String, String)
dict("one") = "First Item"
dict("two") = "Second Item"
dict("one") = "Look, I just edited the first Item!"
%>
Look at that! Aside from the missing dollar sign in front of variables, this looks like PHP!
Today I thought I would share with you what I consider to be a fantastic way to handle form validation in javascript. Of course you need to remember that you have to validate any user input on the server side, but it’s nice to do things on the client side also, so they don’t have to wait as long for a response.
My approach to form validation in javascript involves 2 parts. First off is a extensible object that includes a variety of validation functions that I can have at my disposal. Secondly, I always format my forms with particular IDs, so that I can easily add error messages in javascript. First off, lets discuss the form layout (the easy part). The general rule of thumb here is to create a spot below the form element that will hold the error message, and give it an ID that is the same as the element, with ‘_error’ after it. So
Email:
Here the class ‘msg’ simply defines it as being hidden. Then with javascript if we determine email to be invalid, we can set the spans innerHTML to the text we want, and the class to something that will make it appear.
The second part is the fun javascript. What I do is create an empty object which i then prototype out with validation functions. Here is the code:
function Validator()
{
}
/**
* Check Email Function
*/
Validator.prototype.checkEmail=function(ELEM, EVENT)
{
if(EVENT)
{
var scope = this;
YAHOO.util.Event.addListener(ELEM, EVENT, function(){scope.checkEmail(ELEM);});
return false;
}
try
{
var elem = this._getElem(ELEM);
var targetElem = this._findTarget(elem);
var email = elem.value;
var regex = /^[-_.a-zA-Z0-9]+@[-_.a-zA-Z0-9]+\.[a-zA-Z0-9]+$/
if (regex.test(email))
{
targetElem.className = "msg";
return true;
}
else
{
targetElem.innerHTML = "please enter a valid email address";
targetElem.className = "msgshow";
return false;
}
}
catch(e)
{
alert("Error in Validator() -> checkEmail(): " + e.message);
return false;
}
}
Here I create the object, and a email validation prototyped function. The function takes to arguments: an element, and an optional event. If an event is passed in, it is used to create a listener using the yahoo YUI library. This listener will fire on the given event, calling the same function without the optional argument (and thus running the validation).
The rest of the function is fairly straight forward. It first makes calls to getElem, and findTarget. if getElem is given a string, it returns the element with the given ID. If getElem is given an element, it simply returns the element. findTarget simply gets the ID of the passed in element, and appends ‘_error’, then gets the element with the new string ID.
From there is simply runs a regex expression, and if the regular expression matches it makes sure the error message is hidden, otherwise it sets the text and displays the error message.
This total solution is very portable and easy to use. After including the YUI libraries needed, and the validator code, one can add validation to an element by simply doing:
var validator = new Validator();
validator.checkEmail('email', 'change');
The only custom bit of code is two lines, and you have a regular expression checking the input field every time the field is changed, and will dynamically display an error message when incorrect.
Today I found something that made my day. I have always hated that you can’t have strings span multiple lines of code in ASP.NET. For VB.NET this makes since, because there is no semi-colon at the end of statements. To get strings to span multiple lines in VB.NET, you can add an ampersand + space + underscore to the end of each line, like so:
dim sample as string = "notice how " & _
"the string is on multiple lines!" & _
"just make sure you put double quotes on the" & _
"beginning and end of each line"
This works for VB.NET, but not so for C#.NET. I have tried changing the ampersand to a plus sign (c sharp’s character to concatenate strings) but this didn’t work. I had assumed it was impossible, until I came across a solution today. Simply put an ‘at’ sign (@) before the string!
string sample = @"notice how
the string is on multiple lines!";
As you can see, in c-sharp.net you don’t need to start and stop the string like you do in vb.net. The only thing that is slightly tricky, is if you start concatenating strings. Then you need to add the @ symbol to every section of string that will be on multiple lines. For example:
string sample = @"this string
is on multiple lines" + someVariable + @" notice
how i had to use an 'at' symbol again,
however i don't if the string section stays on one line,
such as" + here + "... get it?";
Enjoy this ability to word-wrap you sql queries, or any other code strings which need to span multiple lines!
The problem with most code escape plugins
After starting this blog, I quickly realized that I need a plugin that will automatically escape html in a code block. Otherwise, it is a big pain to go through and convert all symbols to their escaped equivalents (ex: less then signs to ‘<’). I looked into a couple different solutions, but there was a major problem with them all: they convert the code on input. What this means is after you write a code block, it escapes everything inside of it, then saves it to the database. This works fine, until you need to edit your post. When you go to edit, you see ‘<’ instead of ‘<’. Not only is confusing and hard to read, but when you save it again, then it escapes everything a second time, making what is displayed on your blog incorrect.
Why my wordpress code escape plugin is different
I decided to escape the code blocks right before it is output to the page. This means that whatever you type in a code block is saved that way in the database. Because of this, you can edit posts multiple times, with no errors. When editing a post, the code in the blocks looks exactly how you typed it in, so it’s nice and easy to read. However on page everything is escaped for you. This plugin also gets rid of the ‘Smart Quotes’ that wordpress annoyingly tries to use.
That’s it! Nice and easy to understand code, with nothing to configure. I’ll also post the code below so if you prefer, you can copy the code and paste it into a php file you create. Enjoy!
Came across a strange problem today. I was dynamically filling a dropdown list, and also was dynamically creating checkboxes from the database. Basically I have a list of options, and the user needs to select a primary choice (via dropdown) and then a bunch of alternates (via checkboxes). I assumed the best way to do this was:
CheckBoxList checkSet = new CheckBoxList();
ListItem leaf = new ListItem();
leaf.Text = categoryList[i].name;
leaf.Value = categoryList[i].categoryId.ToString();
checkSet.Items.Add(leaf);
//primaryCategory is the dropdownlist defined in aspx file
primaryCategory.Items.Add(leaf);
At first everything appeared great. However, when I tried to submit the form somtimes, i would get the following error: Cannot have multiple items selected in a DropDownList. This confused me, because I wasn’t trying to set the selected value through code. After some digging, I realized they when I select the checkbox item and then post back the form, asp.net sees that the checkbox was selected before, so sets it’s “selected” property to ‘selected’. My code then adds the item to both the dropdown and checkbox list. However, the dropdown had a selected value of it’s own, and therefore I get the error.
The solution, although it seems odd, is to create two different items in code: one for the dropdownlist, and one for the checkbox.
CheckBoxList checkSet = new CheckBoxList();
//add to checkboxlist
ListItem leaf = new ListItem();
leaf.Text = categoryList[i].name;
leaf.Value = categoryList[i].categoryId.ToString();
checkSet.Items.Add(leaf);
//add to dropdownlist
leaf = new ListItem();
leaf.Text = categoryList[i].name;
leaf.Value = categoryList[i].categoryId.ToString();
primaryCategory.Items.Add(leaf);
So I had a great post explaining how to get the value of a radio button if they are dynamically created (such as through a database query) and unforunatly it was lost. Just today I noticed that it was somehow changed to another post about breadcrumbs. I’d like to think I will come back and create another quality post on how to get values of dynamically created, database driven radio buttons.. but until then, here is the short version:
Basically what you are going to want to do it assign a loop counter variable, and add it to the end of each radio button name:
Now when we are error checking values, we can start at 0 and loop until the variable no longer exists.
while($_POST['radioSet' . $i])
{
//Error check value, post to database, whatever needs to be done
}
Here you can see, regardless of how many “radioSet” inputs we have, our error checker will get them all. In this example I only gave one radioButton for each input name. Of course for each loop, you can have multiple numbers of inputs. Also, you can give each element an ID using a similar naming tactic, which would allow you to control them all with javascript using document.getElementById.
First off, let me say that I love Yahoo’s YUI Library. It seems to be very well thought out, and makes many tasks much simpler.
For Example, let say you upgrade your web app with some tasty Ajax. Now lets assume some of these ajax requests are working a little slow. The proper thing to do would be inform the user that something is happening in the background, so they aren’t lost. YUI makes it easy to display an overlay window with a loading image during the requests.
To do this, we use a Panel object. A panel object is basically a DIV with methods to hide and display itself, as well as advanced display options. Here is some starter code:
What we did here is create a basic panel. The first argument is the elements ID. This can either be an ID of an existing DIV in your DOM, or can be a new ID which will be applied to a dynamically created DIV. The next argument is an Object containing configuration options. These are pretty self explanatory: we set a width, tell it to display in the exact middle of the screen, don’t display a close button, don’t allow the user to drag it, make it a model window, and have it fade in and out. (FYI – a model window just means that it fades everything else on screen).
Next, we fill the DIV with content. If you used an ID of a pre-existing DIV, you can skip this code:
Here we simply set the header and body content of the div, and then add it to the DOM as a child of the body tag.
Good News! We are almost done! The panel is created, now all we need to do is trigger it to open, and close. This is done with the following 2 methods:
ajaxLoadingPanel.show();
ajaxLoadingPanel.hide();
All you need to do is call the show method right before your ajax call, and then the hide method right after recieving your ajax response. Thats it!
I am a PHP programmer at heart (by that I mean it is what I know best). However I program in .NET for work (its hard to find php jobs). As such, I often find myself wanting to solve quick tasks with an associative array. Unfortunately, they don’t really exist in .net.
What I usually end up doing is create a Collection instead. A Collection allows you to add any object as an item, and you can also assign a String as a key to it. So for example, if I wanted to create a collection of my family, I could do something like:
dim myFamily as Collection = new Collection
myFamily.add("Leah","wife")
myFamily.add("Cal","father")
This is similar to a php associative array, but note that the first argument is the information, or Object, itself. The second argument is the key. In this case I am simply using strings for the Object, but I could have put anything there.
Now that I have my “Associative Array”, which is actually a Collection, I can lookup values like so:
If myFamily.Contains("dad") Then
Response.Write("My father is: " & myFamily("father").ToString)
End If
The downside to a collection is that you cannot edit items in a collection. A workaround is to delete the item, then create a new one with a same key. However, collections really seem to be meant more for static information you don’t want to change. If you are looking to change the items, check out my article The Dictionary Object: similar to PHP arrays.
Today I was working on an image editing program, and wanted to determine the x and y coordinates on an image. I knew that imagemaps will give you the coordinates that you clicked on, but I wanted to mimic this behavior in javascript.
It turns out there are 2 ways to do this: If you are using IE (then shame on you!) you can get the coordinates using an offsetX and offsetY.For example, an an onclick handler to your image, passing in the event (ex: <img onclick=’getCoords(e)’ …) then inside the getCoords function, you can use e.offsetX and e.offsetY.
But what If I am awesome, and thus don’t use IE, you might ask. Well, it is only slightly more work. Other browsers give you a pageX and pageY, so you simply have to compare those values with the images values, and do some math to get your coordinates. The image offsets can be found with offsetTop and offsetLeft so to get the x value, you would do:
var xOffset = e.pageX - document.getElementById("thePictureId").offsetLeft