Sunday, 21 December 2008

Recommended web 2.0 colour schemes

There is a flash colour scheme generator named ColorToy 2.0: http://www.defencemechanism.com/color/



Also there are 14 colour schemes from: http://zcool.com.cn/color/20070623/color_0623J52007.html

073340007334010733402073340307334040733405073340607334070733408073340907334010073340110733401207334013

Tuesday, 16 December 2008

Differences Between XHTML And HTML

First of all, when we are talking about XHTML it is actually XHTML 1.0. When using VS2008 to create HTML/ASP.NET page the default DOCTYPE details are:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
The Most Important Differences between XHTML and HTML are:
  • XHTML elements must be properly nested.
  • XHTML elements must always be closed, for example "</p>". If tag is empty it should be self-closed, like this: "<br />".
  • XHTML elements must be in lowercase, including property names.
  • XHTML property value should always be quoted.
  • Use id instead of name to identify a XHTML element.
  • the script should be embraced by CDATA section.

Sunday, 14 December 2008

The most popular Web 2.0 color palette

Followed are two sets of web 2.0 color palette. Click the image will open the 1:1 size image.



Tuesday, 9 December 2008

C#: The best way to reverse a string

3 lines simple code here:
string ReverseString (string text)
{
    char[] _ch = text.ToCharArray();
    Array.Reverse(_ch);
    return new string(_ch);
}

Monday, 1 December 2008

C#: struct vs class

The differences between struct and class:
1, struct is value type, allocate space from stack. And class is reference type, allocate space from heap.
2, struct cannot inherit from the other struct or class, only can inherit interfaces. And struct can't be inherited because it is implicit sealed. But class can do them all. Also because the struct is sealed then all its members can't be protected.
3, struct can't have parameterless constructor, but class can
4, the default modifier of struct is public but for class it is private.
5, in struct there is no initializer, but class can. See code below.

public struct myStruct
{
    public myStruct(){}; //compile error
    public string s = "abc"; //compile error
}

Monday, 24 November 2008

JavaScript: How to get the actual page size – cross-browser solution

The code below shows you a way to get the page size from even IE5.5. Since IE6, all the popular browsers have been supporting document.documentElement object, so only browser older than IE6 will be using the else code block.

function getPageSize(doc) {
    var re = {};
    if (doc.documentElement && doc.documentElement.clientHeight) {
        var root = doc.documentElement;
        re.width = (root.clientWidth > root.scrollWidth)
                                     ? root.clientWidth : root.scrollWidth;
        re.height = (root.clientHeight > root.scrollHeight)
                                     ? root.clientHeight : root.scrollHeight;
    }
    else {
        var root = doc.body;
        re.width = (window.innerWidth > root.scrollWidth)
                                     ? window.innerWidth : root.scrollWidth;
        re.height = (window.innerHeight > root.scrollHeight)
                                     ? window.innerHeight : root.scrollHeight;
    }
    return re;
}

The return object re is a JSON object and you can directly use re.width and re.height to get the values.

Monday, 3 November 2008

All Regular Expression Characters and Meaning (Chinese)

The original article: http://yirlin.cnblogs.com/archive/2006/04/12/373222.html

字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
(pattern) 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。
(?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。
(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
x|y 匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
[xyz] 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\cx 匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^0-9]。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。
\xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。.
\num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。
\n 标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
\nm 标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。
\nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。
\un 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。

Tuesday, 28 October 2008

SQL: Basic Transact-SQL commands and syntax

This article is not suppose to make you become a Transact-SQL export, instead it is only suppose to make me don't look like a idiot when reading a SQL Stored Procedure. In that perspective I wrote this article which covered some basic but very often used SQL syntax and command.

1st of all, how to declare variables. The followed code declared a integer, a string and a record-set point:

DECLARE @Counter int
DECLARE @RegionName NVARCHAR(510)
DECLARE @RegionId TABLE (RegionId int)


2nd of al, let’s take a look how to create code block, a classic sample will be like this:

BEGIN TRY 
  BEGIN TRAN
    IF NOT EXIST (SELECT ...) –- make your condition here
    BEGIN
      -- do your stuff here 
    END
  COMMIT
END TRY
BEGIN CATCH
  IF @@Trancount >0
    ROLLBACK

  DECLARE @err VARCHAR(500)
  SET @err = ERROR_MESSAGE()
  RAISERROR (@err, 16, 1)
END CATCH

GO

Above is a complete cycle when you are trying to do some database operation with Transaction cooperation. We begin a TRY block first (if there is error the CATCH block will catch it), and inside the TRY block we can do anything we want, in this case, typically we put a IF BEGIN END block here. In the CATCH block we first try to ROLLBACK all the changes we made first by check the @@Trancount value to see if there is any Transaction started, and then we raise a error message out.

3rd of all, what does the GO sentence do? GO is not a Transact-SQL statement, it just simply signals the end of a batch of Transact-SQL statements. No any Transact-SQL statement can occupy the same line as a GO command but the comments.

In another word, GO marked a end of a T-SQL batch, after the GO any variable will be brand new and unknown. Here is a example from MSDN:

USE pubs
GO

DECLARE @MyMsg VARCHAR(50)
SELECT @MyMsg = 'Hello, World.'
GO
-- @MyMsg is not valid after this GO ends the batch.

-- Yields an error because @MyMsg not declared in this batch.
PRINT @MyMsg
GO


4th of all, a good stuff, SET IDENTITY_INSERT. Allows explicit values to be inserted into the identity column of a table. As you know after you set the table identity field to auto increasing integer you can insert a record with a particular id value any more. But by swtich on/off the IDENTITY_INSERT you can do it.

SET IDENTITY_INSERT MyTable ON
  -- Insert records with any id value you want
SET IDENTITY_INSERT MyTable OFF


5th of all, create and delete a table in T-SQL:

-- Create products table.
CREATE TABLE products (id int IDENTITY PRIMARY KEY, product varchar(40))
GO

-- Drop products table.
DROP TABLE products
GO 


6th of all, some useful methods you can use in your SQL:

* ISNULL ( check_expression , replacement_value ) , Replaces NULL with the specified replacement value.
* COALESCE ( expression [ ,...n ] ) , Returns the first non null expression among its arguments.
* GETDATE, Returns the current system date and time in the SQL Server standard internal format for date-time values.



Then followed is a example to show you how to change current existed table's structure.

If NOT EXISTS ( SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='HighlightBox'
                and COLUMN_NAME='EndPrice' )
BEGIN
  ALTER TABLE HighlightBox ADD EndPrice decimal(10,2) NULL
  ALTER TABLE HighlightBox WITH CHECK ADD CONSTRAINT FK_HighlightBox_TicketAvailabilityID
        FOREIGN KEY(TicketAvailabilityID)
        REFERENCES Ticket_Availability (Ticket_Availability_Id)
END
GO


Finally, there are some rules from MSDN apply to T-SQL batches:

* CREATE DEFAULT, CREATE FUNCTION, CREATE PROCEDURE, CREATE RULE, CREATE TRIGGER, and CREATE VIEW statements cannot be combined with other statements in a batch. The CREATE statement must begin the batch. All other statements that follow in that batch will be interpreted as part of the definition of the first CREATE statement.

* A table cannot be altered and then the new columns referenced in the same batch.

* If an EXECUTE statement is the first statement in a batch, the EXECUTE keyword is not required. The EXECUTE keyword is required if the EXECUTE statement is not the first statement in the batch. Security Note Batch files may contain credentials stored in plain text. Credentials may be echoed to the user's screen during batch execution.

Tuesday, 21 October 2008

C#: Decimal type vs. Float and Double types

Have you ever wondered what is the difference between the .NET "decimal" data type and the similar "float" or "double" data types? Ever wonder when you should use one instead of other? This article is going to help you and myself to work these questions out.

First of all, take a look at the following C# code:

var f = 1.1f;
var dbl = 1.1;
var d = 1.1m;

Response.Write((f + 0.1f).ToString("e20"));
Response.Write("<br />");
Response.Write((dbl + 0.1).ToString("e20"));
Response.Write("<br />"); Response.Write((d + 0.1m).ToString("e20"));

Note: when you declare a float variable like float f = 1.1 you will receive a build error says type 'double' cannot be implicitly converted to type 'float'; use an 'F' suffix to create a literal of this type, which means any decimal without suffix will be created as a double type.

Now here is what the ouptput looks like:

1.20000005000000000000e+000
1.20000000000000020000e+000
1.20000000000000000000e+000

You can see the three results are all slightly different. Why is this? Also, why was 1.20000005 instead of the hard-coded 1.20000000? The reason is simple - we’re working on hardware that uses binary floating point representation as opposed to decimal representation. Binary floating point is really an approximation of the true decimal number because it is base two (binary) instead of base 10 (decimal).

The Decimal Type, instead, is simply a floating point type that is represented internally as base 10 instead of base two. Obviously with base 10 (our real-world numbering system) any decimal number can be constructed to the exact value without approximating. :) The Decimal type is really  really a software implementation of base 10 arithmetic.

Which Type Should I Use?

Since Decimal types are perfectly accurate and float’s are not, why would we still want to use the intrinsic float/double types? Short answer - performance. In my speed tests Decimal types ran over 20 times slower than their float counterparts.

So if you’re writing a financial application for a bank that has to be 100% accurate and performance is not a consideration, use the Decimal type. On the other hand, if you need performance and extremely small floating point variations don’t affect your program, stick with the float and double types.

Other Considerations

Another thing the Decimal type can do that the float and double types cannot is encode trailing zero’s. For example, there is a difference between 7.5 and 7.50 in the decimal type, but there is no way to represent this in a standard float/double. Let’s look at another example:

double dbl = 1.23 + 1.27;
Response.Write(string.Format("double: {0}", dbl));
Response.Write("<br />");
decimal d = 1.23m + 1.27m;
Response.Write(string.Format("decimal: {0}", d));

This output looks like this:

double: 2.5
decimal: 2.50

The first part that uses a double outputs 2.5, but the second one that uses a decimal outputs 2.50 - we didn’t even have to specify a format string in order to get that trailing zero. This could be very useful in applications that deal with dollar amounts.

Thursday, 16 October 2008

ASP.NET Error: The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

There is a chance sometimes you can get this HttpException: The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>). Just like itself mentioned, if you check your aspx page you must can find some <% ... %> exception inside. There are two ways to fix it.

Option 1: move the code into any runat="server" tag, which means move the code into a server side html tag. The tag could be <head runat="server"></head>, or <form runat="server"></form>.

If you can’t put the code into any server side tag (it is wired if this happen :-) ) then there is Option 2:
Step 1: override the OnInit(), like this:

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);
    Page.DataBind(); // Add this new line.
}

Then step 2, in your code replace all the <% … %> or <%= … %> to <%# … %>. Done. I will do more research and probably can tell you what actually happened very soon. -- The End

Tuesday, 14 October 2008

JavaScript: JavaScript Better Practices

There are some tips to make your JavaScript code runing faster.
  • Use "var" whenever a variable is to be declared
  • Reduce scopes (Try avoiding nesting functions or loops)
  • Avoid string concatenation, use Array instead - “push” each pieces of the string into array and then use “join” to get the complete string
  • Use less DOM element concatenation - concatenate everything into string/Array first, then assign to the DOM element
  • Introduce function delegate. This one is worth mentioning. When calling a function in a loop, delegate before the loop because JavaScript interpreter will use the function then as local variable and will not lookup in its scope chain for the function body in each iteration. Code:
    var delegate = myFunc; // myFunc is the function
    delegate(el1);
  • Introduct DOM elements and function caching. Similar to function delegation. Example:
    var divContentAppendChild = document.getElementById("div1").appendChild;

    for (var i = 0; i < count; i++)
        divContentAppendChild(element[i]);
  • Avoid using switch if possible, as JavaScript interpreter can’t optimize switch block.
The End. :)

The .NET Framework type to ADO.NET data type mappings

.NET Framework Type ADO.NET Database Type SQL Data Type
String Varchar Varchar()
String Nvarchar Nvarchar()
String NChar Nchar()
String NText NText
String Text Text
Double BigInt Float
DateTime DateTime Datetime
DateTime SmallDateTime Smalldatetime
Int Int Int
Int64 BigInt Bigint
Int16 SmallInt smallint
Byte[] Binary Binary()
Byte[] Image Image
Byte[] VarBinary Varbinary()
Byte TinyInt Tinyint
Bool Bit Bit
Decimal Decimal Decimal
Decimal Money Money
Decimal SmallMoney SmallMoney
Float Float Float
Guid UniqueIdentifier Uniqueidentifier
Real Real Real

Monday, 13 October 2008

ASP.NET MVC: First shoot, the ActionResult type

When I created my first MVC project I noticed this method named Index which is created automatically by MVC framework.

public ActionResult Index()
{
    // Add action logic here
    return View();
}

When you move mouse over the View() method you will see it returns a instance of ViewResult type but not a ActionResult type. The ViewResult type is actually inherited indirectly from ActionResult type. The complete inheritance structure is:

ActionResult
|
|--PartialViewResult
|
|----ViewResult

The whole story here is we created a Index action for current Controller which means when you just go to this website and don’t specify any page name you will go into this Index action. What this action does is initialize the page view and return a ViewResult object for MVC viewer to use.

Tuesday, 29 July 2008

AJAX: How to user Yahoo! Stock Quote CVS service

If you are trying to use AJAX skills to build your stock quote tool and are looking for some stock price feeds, then this article could help you a lot. :) The sample Yahoo! Stock Quote HTTP string looks like this: If you type in the HTTP address above to your browser address bar, it will return you a string like

20.745,-0.385,2590659
If you want the full information about the symbol, you can use **f=sl1d1t1c1ohgvj1pp2wern** instead. Don’t sweat, here comes the explanation for each letter (or letter-digit pair)

* s: the symbol name
* l: last value (or current price). If you use l alone, you will get back a string similar to Mar 22 - 31.26
* l1: (letter l and the number 1) to just get the last value of the symbol
* d: d alone will give you 0, while d1 will return the current date (e.g. 3/22/2007)
* t: t by itself will request the yahoo-generated chart. However, you will get back the chart image with a whole bunch of other HTML garbage, e.g. src=http://chart.yahoo.com/c//y/yhoo.gif" alt="Chart">
* t1: the time of last update, for example 4:00pm.
* c: the change amount. Can either be used as c or c1.
* o: opening value
* h: high value
* g: low value
* v: volume
* j: 52-week low.
* j1: the market cap. This is string like "42.405B" for $42 billion. Man… that can buy **a lot** of hamburger
* p: after hour price (?)
* p1: (?)
* p2: change percentage e.g. "-0.10%"
* w: 52-week range
* e: EPS (Earning per share)
* r: P/E (Prince/Earning) ratio
* n: Company name

Wednesday, 23 July 2008

How to build a popular 3 column HTML laytou

There is a very famous and very popular 2 or 3 columns html framework layout which used by IBM, Sony etc etc, and which is very easy to build and maintain. Below is the screen shot of the layout. The key skills are used in this structure are CSS float style and clear styles. The float style sets or retrieves on which side of the object the text will flow. The clear style sets or retrieves whether the object allows floating objects on its left side, right side, or both, so that the next text displays past the floating objects.

From the screen shot you can see to build the 3 columns we usually set the first two div columns' float style to left and the last one to right. By the way the 3 div areas will be listed horizontally and properly. Then we have to set the followed/next div (in the screen shot, DIV D) clear style to left or both.

The reason to use clear style
As you all know, the div element is a block element. But by set the float to left or right will change the div element to a inline object. In this case the DIV A, DIV B and DIV C are actually inline objects and DIV D is a block object. If don't set the DIV D's clear style to left or both the DIV D will be located at very top/left area inside the DIV MAIN and will be overlapped with DIV A, B and C.

If you don't like the clear style at all, there is a alternative way to set up this html layout, which is put the DIV A, B and C in a table element and you can get the same effect because the table will always auto reset its size to suit for all the element inside it and it is a block element too.

layout

Tuesday, 8 July 2008

Stupid syntax difference between IE and Firefox

When you are doing javascript/AJAX development you probably will add a very useful function trim() into build-in String object to return a copy of a string without both leading and trailing spaces. To do so you just need simply add one sentence in front of your js file. Below is the coding I used in my js framework.

function String.prototype.trim() {return this.replace(/(^\s*)|(\s*$)/g,"");};

Unfortunately this sentence only works on IE browser. It caused an error on Firefox which cost me one hour this afternoon to figure it out. after I changed the sentence to the syntax shown below a peaceful world came back again.

String.prototype.trim = function() {return this.replace(/(^\s*)|(\s*$)/g,"");};

It is painful to find out these tiny differences and it always lets me down. :(  But from the positive side, it makes you always use the standard syntax rule to build your project.

Wednesday, 2 July 2008

My AJAX framework v1.0

Nothing special. Create a new object wjAjax inside there is a XMLHttpRequest object named xmlhttp. And then you can call the function getData (method, url, params, async, func) which attached in wjAjax class. If you call the getData function by asynchronized way, the function will return true or false. But if you call the getData function by synchronized way it will directly return the XMLHttpRequest object for further using.

function wjAjax ()
{
  try
  {
    if (window.XMLHttpRequest)
    {
      this.xmlhttp = new window.XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
      this.xmlhttp = new window.ActiveXObject("MSXML2.XMLHTTP.3.0");
      if (!this.xmlhttp)
        this.xmlhttp = new new window.ActiveXObject("MICROSOFT.XMLHTTP");
    }
  }
  catch (e) {return null;}
  this.isRunning = false;
  return this;
}

wjAjax.prototype.getData = getData;

function getData(method, url, params, async, func)
{
  if (this.isRunning) {return false;}
  if (!url) {return false;}
  if (async && !func) {return false;}
  var me = this; //alias of wjAjax object, for reference using in onreadystatechange method.
  method = method || "get";
  params = params || "";
  try
  {
    if (method.toLowerCase() == "get")
    {
      this.xmlhttp.open("get", url+"?"+params, async);
      params = null;
    }
    else if (method.toLowerCase() == "post")
    {
      this.xmlhttp.open("post", url, async);
      this.xmlhttp.setRequestHeader("Method", "POST "+url+" HTTP/1.1");
      this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    }
    if (async)
    {
      this.xmlhttp.onreadystatechange = function()
      {
        if (this.readyState == 4)
        {
          me.isRunning = false;
          if (this.status == 200) {func(this);}
          else {alert ("HTTP server error. The HTTP server response status code is " + this.status);}
        }
      }
    }
    this.isRunning = true;
    this.xmlhttp.send(params);
    if (!async)
      this.isRunning = false;
  }
  catch (e) {alert("Run time error: "+e.message); return false;}
  if (async)
    return true;
  else
    return this.xmlhttp;
}

Monday, 30 June 2008

Dynamically insert new function to current html page - NEW SCENARIO

I have introduced two different way to insert new function in current html page dynamically. But there is a very tricky situation here which I think I should explain more. Let us say there are three html pages: main.htm, p1.htm and p2.htm. main.htm is actually the container of p1.htm and p2.htm and there is a nav control switch can help user jump between p1.htm and p2.htm pages. Now I want to add a new js function into the onunload event of main.htm page, which make sure a particular function will be invoke when user close the main.htm page no matter he/she is viewing p1.htm or p2.htm. To do so add the js code below to p1.htm (we suggest the p1.htm will be the first page shown in main.htm).
window.top.eval("window.onunload=function(){alert('new func...')};");
If you use window.eval instead of window.top.eval to create the new function, then when you jump to p2.htm and close the window the main.htm can't find the proper onunload function to call. I reckon the reason is the function point is only relying on the window object which you called the eval function from.

Wednesday, 2 April 2008

Javascript: How to preload audio by Windows Media Player with code sample

In my last article I explained how to preload images by HTML IMG element and javascript. Now I am going to show you the way to preload the audio.

This skill is used for one of our client. In the SCORM course we created for this client there are lots of background audio clips. Our client want the audio could be playing automatically without any delay when user go into the particular page, which means we have to preload all the audio clips at the very beginning for further using. In this case, I am using Windows Media Player to preload all the audios.

To do so, obviously we have to create a WMP object, hide it, set its autostart parameter to ture and set its mute to true. And then in the HTML page onload event, we transfer all the audio clip files one by one to the media player, and monitor the downloaded percentage and current status values of media player to refresh the progress bar. If the media player downloaded 100% I will send another audio to it.

There are two things I have to say. One is the media player downloading and buffering only happened after the HTML page onload event, because before that there is no WMP object at all. This thing is different with image preload rule because the IMG element is a internal HTML object but WMP is not. Another thing is there are two confusing events in WMP, buffering and downloading. In sample way, buffering could be fired more than once but downloading only be fired once and it will stop when WMP downloaded 100% of current file. So downloading is exactly the event we should take care of.

The link followed is a full function sample to preload images and a audio clip (singing in the rain) to your local machine by javascript and WMP, which is my personal album. Please click my album to try it. It is fully tested on IE7 and Firefox2.

The coding below is the key function to monitor media player running status.

var _currPrecent = 0;
function mediaDetector()

  var oWMP = document.getElementById("WMP"); 
  if (oWMP.playState == 10) {// state Ready means current URL is unavailable 
    window.clearInterval(_tId); 
    _tId = 0; 
    if (_currMedia >= _totalMedia) { 
      document.getElementById("icontext").innerHTML = _sProgress+"Media Loading... 100%"; 
      window.setTimeout("reLocateHTML()",1000); 
      return; 
    } 
    else { 
      reloadMedia(); 
    } 
  } 
  if (_mediaBuffering && oWMP.network.downloadProgress == 100) { 
    window.clearInterval(_tId); 
    _tId = 0; 
    _mediaBuffering = 0; 
    if (_currMedia >= _totalMedia) { 
      document.getElementById("icontext").innerHTML = _sProgress+"Media Loading... 100%"; 
      window.setTimeout("reLocateHTML()",1000); 
      return; 
    } 
    else { 
      reloadMedia(); 
    } 
  } 
  if (_currPrecent <= oWMP.network.downloadProgress || _currPrecent == 100) { 
    _currPrecent = oWMP.network.downloadProgress; 
    document.getElementById("icontext").innerHTML = _sProgress+"Media Loading... " 
      +Math.round(((_currMedia-1)/_totalMedia)*100)+"%<br/>" 
      +"--Media file "+_currMedia
      +"(total "+_totalMedia+")... "+oWMP.network.downloadProgress+"%";    
  }
}

Thursday, 6 March 2008

Javascript: How to preload images

The first thing you should know is, the body onload event will fire immediately after the browser loads all the html object, or we say html element. This is the key point we use to create the image preload widget.

So first of all, we declare a image array which included all the paths of the images we want to preload. And then we user javascript to create image elements (<img />) for every single image path in the array, and in the image onload event, we insert a function to refresh loading counter. Finally, we insert auto jump function to body onload event to jump to the actually page we want, in this case, it is google.com.

* Please remember the image path has to be an available path, or the image onload event will not fire and the counter will not show the correct percentage. 

The simple code below create a loader page, which will preload 4 images first and then auto jump to google.com. The code was tested on IE7 and FIrefox2.

<html>
<head>
<script type="text/javascript">

var _currImg = 0;
var _totalImg = 0;
var _sURL = "htt"+"p://www.google.com";

var _arrImg = new Array(
  "img_1.jpg",
  "img_2.jpg",
  "img_3.jpg",
  "img_4.jpg"
)

function createHTMLEl()
{
  _totalImg = _arrImg.length;

  h = "<div id='icon' style='position:absolute;left:0px;top:0px;"
    +"width:220px;height:120px;'>"
    +"<div style='width:100%;height:90px;'>"
    +"<span id='icontext' style='font-family:tahoma,arial;font-size:8pt;"
    +"font-weight:bold;'>Graphic Loading... 0%</span>"
    +"<span>&nbsp;&nbsp;&nbsp;</span>"
    +"<img src='load.gif' align='absmiddle'/>"
    +"</div>"
    +"<div style='text-align:center;'>"
    +"<input type='button' value='Skip' onclick='NextPage();'/>"
    +"</div>"
    +"</div>";

  for (var i = 0; i < _arrImg.length; i++)
  {
    h += "<img src='"+_arrImg[i]+"'"
      +"style='visibility:hidden;width:0px;height:0px;'"
      +"onload='refreshProgressBar();'/>";
  }
  document.body.innerHTML += h;
}

function refreshProgressBar()
{
  _currImg += 1;
  if (_currImg < _totalImg) {
    document.getElementById("icontext").innerHTML = "Graphic Loading... "
      +Math.round((_currImg/_totalImg)*100)+"%";
  }
  else {
    document.getElementById("icontext").innerHTML = "Graphic Loading... 99.9%";
  }
}

function resetIconPos()
{
  var o = document.getElementById("icon");
  o.style.left = Math.round((document.body.clientWidth - o.offsetWidth)/2)+"px";
  o.style.top = Math.round((document.body.clientHeight - o.offsetHeight)/2)+"px";
}

function reLocateHTML()
{
  document.getElementById("icontext").innerHTML = "Graphic Loading... 100%";
  window.location.href = _sURL;
}
</script>
</head>
<body onload="reLocateHTML();">
<script type="text/javascript">
createHTMLEl();
resetIconPos();
</script>
</body>
</html>

Saturday, 1 March 2008

Enjoy: Independence Day

Good morning. !@#$% - Good morning.
In less than an hour, aircraft from here will join others from around the world. And you will be launching the largest aerial battle in the history of mankind. Mankind - that ~ word should have new meaning for all of us today. We can't be consumed by our petty differences anymore. We will be united in our common interests. Perhaps its fate that today is the 4th of July, and you will once again be fighting for our freedom, not from tyranny, oppression, or persecution - but from annihilation. We're fighting for our right to live, to exist. And should we win the day, the 4th of July will no longer be known as an American holiday, but as the day when the world declared in one voice: "We will not go quietly into the night! We will not vanish without a fight! We're going to live on! We're going to survive!" Today, we celebrate our Independence Day!

Thursday, 28 February 2008

Enjoy: 2008 Beijing Olympic Games (8th~24th, Aug, 2008)

2008 Beijing Olympic Games start at 8th Aug 2008, there are total 35 sports in the Olympic Games. By the flash shows below, you can see all of these 35 sports icons. If you click any one of these icons, it will link you to the related sport page in 2008 Beijing Olympic Games official website. Enjoy it. :)

Wednesday, 27 February 2008

Javascript: 2 ways to insert new function dynamically

The coding below help you to create and insert new javascript function into a loaded html page. Which is very useful for dynamic external js libs binding. I personally recommend the first way:
function addFunc()
{
var sFunc = ""
+"function myOnUnLoad()"
+"{"
+"alert('unload...');"
+"};"
+"window.document.body.onunload = myOnUnLoad;";

window.eval(sFunc);
}
Second way, by this way you have to write down all your code in a external js file, in this case, let us say myjs.js file:
function addFunc()
{
var o = window.document.createElement("script");
o.type="text/javascript";
o.src="myjs.js";

//if you use o.innerHTML="..." or o.innerText="..." here, you will get a
//runtime error. That is why you have to use a external js file, and use
//o.scr="myjs.js" to insert function code


window.document.getElementsByTagName("head")[0].appendChild(o);
}

//-- code in myjs.js file
window.document.body.onunload = function ()
{
alert("unload...");
}

Javascript: tricky window.open() on IE6

If you write javascript regularly, you must be very familiar with function window.open(), which open an external browser window with particular features (size, position, scroll bars, status bar etc.) This function is supported by almost all the popular browsers (IE6/7, Firefox, Opera and Safari), but I found in one particular case it doesn't work properly on IE6, which is when you try to show a menu bar on the browser window. Followed is the code.
//page1.htm source code <html>
<head>
<title></title>
<script type="text/javascript">
function popup()
{
var style = "width=300,height=300,left=0,top=0,"
+"toolbar=yes,scrollbars=no,resizable=no,menubar=yes,status=yes,location=yes";
var o = window.open("page2.htm","page2",style);
}
</script>
</head>
<body>
click <a href="javascript:void(0);" onclick="popup();">here</a>.
</body>
</html>
////page2.htm source code
<html>
<head>
<title>page two</title>
</head>
<body>
<div style="position:absolute;left:0px;top:0px;
width:300px;height:300px;background-color:yellow;"></div>
</body>
</html>
When I launch page1.htm by all the other browser except IE6, and click the link in the page, it will open page2.htm in a pop-up window with correct clientHeight and clientWidth value, in this case they are 300 and 300. But when I do the same thing by IE6, I got a pop-up window with 19px more height space in the window. And if I switch off the menubar from the javascript code, it works ok. Below is the screenshot of this bug?

Javascript: basic XML object searching

In this case, let's suggest we have already declared a xml node object oXml, the most popular search xPaths are:
//search by attribute
oXml.selectNodes("//tag1/tag2[@id='1' and type='1']");
//search by tag text value
oXml.selectNodes("//tag1/tag2[text='text']");

Javascript: the first dodgy, execute javascript function in browser address bar

In Browser addess bar, type in javascript: and then followed by the javascript function you wanna execute, press enter key. Below is a example.
javascript:alert(document.getElementById("id").outerHTML);