Disabled buttons on long postbacks in ASP.NET

January 6th, 2010

Some users don't realize that when a long query is executing, they should not hit a button again. It can sometimes make an application to crash, for instance if it's a delete button.

To prevent this scenario, here is a script that you can embed with every page. It requires jQuery and ASP.NET Ajax.

var delay = 500; // milliseconds

function pageLoad() {
    Sys.WebForms.PageRequestManager.getInstance().add_endRequest( function() {
        requesting = false;
        $(":input[type=submit]").removeAttr('disabled');
    });

    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function() {
        requesting = true;
        setTimeout(function() {
            if (!requesting) return;
            $(":input[type=submit]").attr('disabled', 'disabled');
        }, delay); 
    });
}

Microsoft China writes about NCalc

December 22nd, 2009

It happens that there is an article about NCalc on the Chinese version of Msdn. Here is the translation in English.

It can be interesting if you don't know how you could use it in your applications. Even more if you work in the banking area.

Blueprint CSS and ASP.NET

December 7th, 2009

Last Thursday with some colleagues we participated in a small contest which runs a night long to deliver a functional Web application. We used this event to try some tools we were not used to putting it place four our customers.

Blueprint CSS (http://www.blueprintcss.org/) is one of them. It's a CSS framework which defines a set of predefined CSS classes and styles. The benefits are that it resets browsers defaults to start with a common set of attributes, and also defines helper classes to arrange the content easily.

However, we faced an issue with ASP.NET as it comes to arrange form's elements. We used a Master Page where the CSS links were defined, and in order to use some forms specific designs we had to set an inline class to the form tag. This broke the overall design of our pages as in standard ASP.NET every content in inside the main form object.

The solution was simply to remove the form specific declaration on the inline class, and add another div to set the form elements boundaries like this:

.inline {line-height:3;}
.inline p {margin-bottom:0;}

Instead of :

form.inline {line-height:3;} 
form.inline p {margin-bottom:0;} 

I had almost decided to remove this CSS when I saw the issue, so I think it's an important tip, all the more so I think it's a very useful framework. If you don't know it yet, take a look at this article. And if you like it, you will need this cheat sheet, invaluable.

ECS5 – ECMAScript 5th edition released

December 5th, 2009

December 3, 2009
The 98th General Assembly held in Mountain View, December 3, 2009, approved the following documents:

ECMA-262 5th edition - ECMAScript Language Specification

The long awaited new version of ECMAScript has been approved by the committee. It means browsers editors have a common procedure for implementing new compatible JavaScript functionalities, Web developers have something new to learn, and that I have another set of tasks to add on the current Jint's one stack.

The Homer Car Syndrome

October 27th, 2009

This morning I had a new mail from a customer asking for some advice. Currently we have to develop a new system and had a few meetings to discuss about the project, it's feasibility, and also to define a plan. The next step now is to gather the business requirements. But the question which arises is : "Who has to do the business requirements".

[The_Homer_by_Carlos_Bisquertt.jpg]

The answer we had was obvious: "The business people". But it reminded me of an episode of The Simpsons. In this episode Homer discovers he has a half-brother, Herb, who is also the head of a big automobile manufacturer. During this episode Herb asks Homer to design a brand new car and that he has full power to decide. He defines the requirements, and the engineers produce it, as requested. The car was produced, as requested. Disaster.

What I want to say is that when a house is built, an architect should be in the process because he has some experience of the domain, has already faced a lot of problems and thus their solutions. When a car is designed it's the same. And for software ?

The business should not define requirements alone. Because Software Architects or Program Managers are paid for that, and because an advice is better to be given before everything is done than after. This could be to prevent from failure, but also to suggest features or behaviors that business wouldn't have imagined. And with a little chance, it can also make the difference between delivery and success.

How to create a template engine in 1 hour

October 21st, 2009

Today I needed to create a mass email sender application for a customer, in order to warn the users of their personal data. The template had some complexity like loops for multi-valued information, thus I needed a template engine.

The goal was to have a text processor which could take an external object model (actually a CSV file) and a template file like ASP.NET does:

Dear <%= firstname %> <%= lastname %>,

This is a set of squares:
<% for (var i=0; i<3; i++) { %> 
    <%= i %> * <%= i %> = <%= i * i %> 
<% } %>

Regards

And the result should look like this:

Dear Sébatien Ros,
This is a set of squares:
0 * 0 = 0
1 * 1 = 1
2 * 2 = 4

Regards

I quickly searched for this sort of tool when I wondered how they would be made. Actually ASP.NET changes the ASPX file into code files which is I suppose the best approach. The only thing I needed was a way to execute this generated code. And guess what, I already have it, it's Jint, again ;)

So the only thing to do is use a simple state machine and a regular expression to convert the previous template to this script :

write('Dear '); write( firstname ); write(' '); write( lastname ); 

write(',\r\n\r\nThis is a set of squares:\r\n');  
for (var i=0; i<3; i++) { 
    write(' \r\n    '); 
    write( i ); 
    write(' * '); 
    write( i ); 
    write(' = '); 
    write( i * i ); 
    write(' \r\n');  
} 

write('\r\n\r\nRegards'); 

I also configured Jint so that the write method appends its parameter to a local StringBuilder instance, and took all variables like firstname and lastname to declare them locally in the script. Then I ran the script using Jint and emailed the resulting string to the recipient.

I'm sure I will find even more usages for Jint in the future.

First bits of Euss 2.0

October 14th, 2009

The development of Euss 2.0 is progressing (Nicolas is working hard), and I can already show you some working stuff. Here is the use of NLinq as the primary query language, and the same one using pure LINQ. Note the differences (there aren't actually).

var context = CreateObjectContext();
context.InitializeRepository();

Person p = new Person() { Name = "Tintin" };
p.Pet = new Pet() { Name = "Milou" };

context.BeginTransaction();
context.Serialize(p);
context.CommitTransaction();

// using nlinq
Assert.AreEqual(1, context.LoadScalar<int>("(from Model.Pet pet select pet).Count()"));
Assert.AreEqual(1, context.LoadScalar<int>("(from Model.Person person select person).Count()"));

// using LINQ
Assert.AreEqual(1, (from Model.Pet pet in context select pet).Count());
Assert.AreEqual(1, (from Model.Person person in context select person).Count());

As usual, we don't care about the repository implementation.

How to enable Listview Databinding in LayoutTemplate

October 13th, 2009

I am a big fan of the ListView control in ASP.NET 3.5. Though I discovered that databinding code can't be used inside the layout template. Recently I had a simple scenario where I wanted to automatically display an arrow on the header of every sortable column.

Even the famous Matt Berseth did not manage to handle this scenario in a simple manner. If you look at the code behind, you'll see he has to handle the OnDataBinding method to check every column header and add an arrow dynamically on the sorted column.

I have found a solution which allows me to had this behavior declaratively, and even more important, simply.

Now in the layout I just have to set this binding expression:

<th class=<%# ContactsLV.SortExpression == "LastName" 
  ? (ContactsLV.SortDirection == SortDirection.Ascending 
    ? "sortedASC" : "sortedDESC") 
  : "notSorted"  %>>

Where ContactLV is my listview, and LastName is the SortExpression.

To be able to handle this data binding code, the ListView has to call DataBind() on elements in the LayoutTemplate. I have created an Adapter for this purpose, and registered it in the Browser file.

The code is also really simple:

public class ListViewAdapter : ControlAdapter
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        ((ListView)Control).DataBound += (sender, args) =>
        {
            if (Control != null && Control.Controls.Count > 0)
            {
                foreach (Control elt in Control.Controls[0].Controls)
                {
                    if (elt is ListViewDataItem)
                    {
                        continue;
                    }

                    elt.DataBind();
                }
            }
        };

    }
}

The declaration in the BrowserFile.browser:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.WebControls.ListView"
               adapterType="Microsoft.Web.Adapters.ListViewAdapter" />
    </controlAdapters>
  </browser>
</browsers>

And the result:

image

As you can see, I have used three states: notSorted, sortedASC and sortedDESC. On the image, every column not sorted has an up/down arrow, and the Title column is sorted ascending. Clicking on any other row will send a Sort command to the underlying data source, and also automatically (and magically) refresh the arrows.

ECMAScript vs. JavaScript

October 11th, 2009

In my long road to the implementation of a .NET JavaScript interpreter, I discovered that I actually knew little about JavaScript. For instance I discovered JavaScript could do for each loops, had the yield statement as in C#, lambda expressions and even XML instructions.

This is just a subset of what JavaScript defines. But the reason why we neither know nor use those feature is that JavaScript is not ECMAScript. The latest is the standardized version of the first, and they don't follow the same timeline. The one we usually know is ECMAScript 3.0.

As a matter of fact ECMAScript 3.0 (also named ES3) is equivalent to JavaScript 1.5. Those versions are used in Internet Explorer, Safari and Opera. Chrome is compatible with version 1.7 and FireFox 3.0 uses JavaScript 1.8 definition. For cross browser scripts, it's obvious that all developers then use the JavaScript 1.5 (ES3) version.

Next big step is to see all browser implement ECMAScript 4.0, which is supposed to be equivalent to JavaScript 2.0, and embeds all concepts I have enumerated above.

Here is a list of very interesting readings:
New in JavaScript 1.6
New in JavaScript 1.7
New in JavaScript 1.8
John Resig's posts (jQuery's father) about ECMAScript

Update
Bertrand corrected me on ES4. Actually this version will never see the light in standard browsers (instead of FF which already implements it). The reason is that it never went to enough acceptance from other editors (Yahoo and Microsoft for instance), and two different paths were followed. Fortunately they joined back to a more simple evolution of ECMAScript, i.e. ES3.1 later renamed ES 5. This should become standard implementation at the end of this year, thus I can't but follow it also ;). Thank you Bertrand for the information (as usual).

Lost feeds

October 6th, 2009

My main way of getting information is by using rss feeds. They can be blogs, sites or specialized opmls. For this I use Internet Explorer exclusively, as it shows everything not yet read, and doesn't need a live connexion for it.

Though there is an issue. Actually some feeds seem to miss activity from time to time. Yesterday I clicked on an unmodified rss feed, and IE displayed it was no more available. The rss url had changed, because the hosting software had been switched. I then checked every single feed in my list and I somehow rediscovered interesting posts. (e.g., Steve, Vincent)

Do you have such an issue from your side ?

The unknown Javascript

Septembre 23rd, 2009

As many of you I suppose, I though I knew JavaScript well. Actually I was totally wrong. Working on Jint lead me to discover some well ignored functionalities. If you want to really understand this language, just take a look at this article or the french version.

Jint - Javascript interpreter for .NET

September 22nd, 2009

I have published a new project on codeplex. It's called Jint.

Jint is a script engine based on the Javascript language. Using Jint, developers can provide fully scriptable applications, execute .NET code without compiling, or create external configuration logic, using the most used script language.
Jint aims at providing every JavaScript functionalities to .NET applications, and bindings to .NET languages can be done in both sides. Jint scripts can use any .NET object from your application, and use every part of the .NET base class library.

Enjoy on http://jint.codeplex.com.

 

ASP.NET Themes

May 13th, 2009

When I was a young developer I did not like Themes in ASP.NET, I prefered pure CSS.

Also, when I was a young boy I did not like girls, I prefered sweets. Did not think loving one did not prevent from loving the other.

Internet Explorer 8 consumes too much memory

April 24th, 2009

Since I have installed IE8, sometimes it starts consuming a lot of memory, about 500Mb, and is very very slow on "postbacks". It sometimes made me switch to Firefox where the sites where very fast. Actually it was my fault.

I very often debug HTML/Javascript code or analyse the techniques to enhance my knowledge. For this I have used the Developer Toolbar, and now with IE8 the integrated one. What I do is minimize it and thus I always have it ready to use. And this is actually the issue, it just loads the whole DOM again into memory with the perforamnce impact you can imagine.

So if you find Internet Explorer to be slow and consume lot of memory, close the development toolbar.

Localized CSV format and Excel

February 18th, 2009

I've just learnt that the CSV format is culture specific. It means that depending on your regional settings Excel for instance will understant or not CSV files it opens.

For instance say I have a French version of Excel, if I open a "comma" separated value like a,b,c,d I would only have one column. But using the line a;b;c;d it will work. On an English version of Excel, it would be exactly the oposite.

This character (coma or semi-colon) is called the List Separator in your regional settings, and in .NET, to get this value we can use the CultureInfo.TextInfo ListSeparator property.