March 2007 - Posts

JavaScript "Excel-like" Form Editing

A few days ago I was asked to generate a solution to enable the end-user to edit his or her web form in an excel-like mode. This means that he or she wouldn't have to click on a field in order to get focus to it, they will be doing so using the arrow keys instead.

And when in Web World, client side scripting means JavaScript! Yay!
The idea I had is to create a kind of a matrix and then figuring out which fields were on the sides in quite a simple calculation.

Once I had that in mind, the implementation went on quite easy... I decided to name each field using a single format: MyField_<row number>_<column number>. Then, when I have the field name, I'll be able to easily figure out who's next to it, using a simple calculation method.
Now to the code -

The HTML
As I said, all I did here was naming the fields in the format I had decided on and registering to the field's onkeydown event:

<form>
    <input type="text" id="field_1_1" onkeydown="move(this)" />
    <input type="text" id="field_1_2" onkeydown="move(this)" />
    <input type="text" id="field_1_3" onkeydown="move(this)" />
    <br /><br />

    <input type="text" id="field_2_1" onkeydown="move(this)"/>
    <input type="text" id="field_2_2" onkeydown="move(this)" />
    <input type="text" id="field_2_3" onkeydown="move(this)" />
    <br /><br />

    <input type="text" id="field_3_1" onkeydown="move(this)"/>
    <input type="text" id="field_3_2" onkeydown="move(this)" />
    <input type="text" id="field_3_3" onkeydown="move(this)" />
</form> 

The JavaScript
This wasn't tricky too. What I did here was to parse the field name, to get its row and column and then to calculate the next field to focus on, according to the arrow that was clicked:

var fieldConstName = "field_[ROW]_[COL]";

function move(object)
{
    var row = object.id.substring(object.id.indexOf("_") + 1, object.id.lastIndexOf("_"));
    var col = object.id.substring(object.id.lastIndexOf("_") + 1);
    var nextField;

    switch (event.keyCode)
    {
        case 40: /* Down arrow */
            row++;
            break;
        case 38: /* Up arrow */
            row--;
            break;
        case 39: /* Right arrow */
            col++;
            break;
        case 37: /* Left arrow */
            col--;
            break;
        default: /* This is not an arrow! */
            return;
    }

    var newFieldName = fieldConstName.replace("[ROW]", row).replace("[COL]", col);
    var nextField = document.getElementById(newFieldName);

    if (nextField != null)
    {
        nextField.focus();
    }
}

It is necessary to mention that this is only a POC and it has been tested only on my machine, with IE 7 and Windows Vista... I believe this will not work smoothly on Mozilla...

All the best,
Shay.

Posted by shayf | with no comments
תגים:,

"Installation stopped because the directory for template installation did not exist" Error

I ran into the "Installation stopped because the directory for template installation did not exist. Please run Visual Studio on this computer to create the template directories." error when trying to install the new Microsoft AJAX Control Toolkit Visual Studio templates.
It's a really irritating message because it doesn't really give you an idea of the problem's source. I found out that my workplace had changed the file server since I installed Visual Studio, and VS didn't know about it, so its paths were targeting the wrong server. This confused the template installer - It tried to reach the old server and couldn't find the target path...

The solution:
In Visual Studio, go to Tools-> Options..., select "Projects and Solutions" from the tree on the left and set all the locations there to the right ones.

"Installation stopped because the directory for template installation did not exist" Error

Voilà,
Shay.

Posted by shayf | 1 comment(s)

Return Type Generic Method

This time I'd like to introduce you with a sample code I've written... I'll be talking about creating a method with a generic return type.

Currently, the .Net Framework supports parameter overloading but does not support return type overloading. A method with a generic return type means that you can pass the return type to the method and get the result as this type (SampleMethod<string>() will return a string and SampleMethod<bool>() will return a bool value) - a little workaround for implementing a kind of return type overloading.
It is not really recommended to use this kind of method because of performance issues, but it is a good sample of the great power of Generics.

The declaration of our method is similar to regular method with generic parameters, we just put the return type as the generic type:

public T SampleMethod<T>()

Inside the method you code whatever you want to code, the only difference lies within the last lines, where you return a value to the caller.
There we should find out what is the requested return type, and generate a relevant return value. Then we should convert the return value to T which is the return type:

Type retType = typeof(T);
if (retType == typeof(bool))
{
    return (T)Convert.ChangeType(true, retType);
} 

On the first line I put the requested return value in a local variable.
On the second line, I compare the requested return type with a boolean type, which we support for this sample method.
On the fourth line, I convert the return value (true) to the requested return type. I had to do this so the compiler will be satisfied that I give the caller method the type of its desire.

Now all we have to do is to call our method, asking it to return us a boolean value:

Console.WriteLine(SampleMethod<bool>());


In conclusion, this method can be used in really extreme cases. For instance, if you want to create one method that searches for a specific value in a list. You want to know if the value exists for once (return bool value), and you want to know the indexes where the value exists for once (return a list).
You should avoid using this though. It is recommended to separate this kind of method to various different methods in order to ease code reviews and improve performance.

Shay.

The whole class:

public class SampleClass
{
    public SampleClass()
    { }
    public void RunMethod()
    {
        try
        {
            Console.WriteLine(SampleMethod<bool>());
            Console.WriteLine(SampleMethod<string>());
            Console.WriteLine(SampleMethod<float>());
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
    public T SampleMethod<T>()
    {
        /*
           Do something...
        */
        Type retType = typeof(T);
        if (retType == typeof(bool))
        {
            return (T)Convert.ChangeType(true, retType);
        }
        else if (retType == typeof(string))
        {
            return (T)Convert.ChangeType("Something to return", retType);
        }
        else
        {
            throw new NotSupportedException(typeof(T).FullName + " is not supported");
        }
    }
}  
Posted by shayf | 1 comment(s)