Thursday 20 December 2012

Nguyên tắc điểm nhấn trong thiết kế giao diện

Hãy hình dung trang Web của bạn có một "rừng" các nút điều khiển khiến cho người xem lúng túng và khả năng chọn nhầm chức năng là rất lớn do các lỗi "human mistakes". Một trang Web như vậy có thể được xem là có độ tương phản quá mức khiến cho người xem dễ bị rối. Để giảm độ tương phản, cần áp dụng nguyên tắc điểm nhấn. Thí dụ giao diện dưới đây được thiết kế nhằm giảm mức chú ý đối với các phần tử ít được dùng nhất, thí dụ nút Cancel hiếm khi được lựa chọn sẽ được hiển thị "khiêm tốn" ở vị trí cuối cùng. Còn nút "Save" được sử dụng thường xuyên sẽ làm nổi lên. Một thiết kế khá hoàn hảo!






Điểm nhấn trong thiết kế ở trên là nút "Save post", không phải nút  "Cancel".

Dưới đây là các thí dụ khác có thể tìm thấy trong thiết kế của Google Chrome, MS. Word hoặc thiết kế Web.


Các bạn cũng có thể thấy rõ nguyên tắc điểm nhấn được MS. Office tận dụng trong thiết kế mô tả bảng biểu hoặc hình vẽ trong Word ra sao. Trong Word, chọn “Insert Caption”, Word sẽ tự động đổi gam màu nhẹ nhàng hơn cho mô tả Caption nhằm giảm sự tương phản trong văn bản qua đó hướng người dùng vào điểm nhấn là nội dung chính chứ không phải nội dung phụ bên dưới hình vẽ.

Happy Coding!

Wednesday 5 December 2012

Continuous Quality Improvement with Deming PDCA Model



Plan: Goals, Cost-Effective, anticipated Case Studies (đặt ra tình huống)…
Do: Follow-up, Work, Try and Error, R&D, Training…
Check: Measure and compare obtained resutls against expected results, including: Oversee, Review, Audit, Test…
Act: Doing retrospective, fine-tuning process, continnous improving weaknesses…

Note:
1) There are significant differences between Review and Audit.
Audit is a task which goes about verifying that work/project is compliant with regulations and standards. The objective of an audit is to provide a reasonable basis for expressing an opinion regarding the project taken as a whole.

A review does not provide a basis for the expression of such an opinion. A review may bring to the group’s attention significant matters affecting the whole project, but it does not provide assurance that the management team will become aware of all significant matters that would be disclosed in an audit. 

2) When it comes to each step, it might contain its own smaller PDCA circle.



What is Work–family enrichment?

Work–family enrichment or work–family facilitation refers to a process at the work-life interface whereby experience or participation in one role increases the quality or performance in the other role.

Enrichment of facilitation can occur when involvement in one role leads to benefits, resources, and/or personality enrichment which then may improve performance or involvement in the other role. Enrichment can occur bi-directionally such as work-family enrichment or family-work enrichment. Work-family enrichment occurs when involvement in work provides benefits such as skill growth, or changing of mood to be more positive, which has a positive effect on the family. Family-work enrichment occurs when involvement within the family results in the creation of a positive mood, feeling of support, or feeling of success which can help that individual to cope better, more efficient, more confidence, or recharged for one's role at work.

Tuesday 27 November 2012

How to show/hide Grid columns on the fly?

The solution is simple, but quite elaborate to make it work. Here's the complete example using JQuery. You can customize your own way.

First, reference JQuery and create the dynamic list of column names. Then design a checkbox accordingly and hook up onclick event for each:
  
   <script type="text/javascript" src="JS/jquery-1.3.js"></script>  
   <script type="text/javascript" language="javascript">
    $(document).ready(function() {
        $("#tblExample th").each(function() {
            var iIndex = $(this).closest("th").prevAll("th").length;
            var colName = $(this).html();
           
            $("#divColumns")
                .append(
                    $(document.createElement("input")).attr({
                         id:    iIndex
                        ,name:    iIndex
                        ,value:    colName
                        ,type:    'checkbox'
                        ,checked:true
                    })
                    .click( function( event )
                    {
                        var cbox = $(this)[0];
                        ShowHideColumn(cbox.id, !cbox.checked);
                    } )
                )
                .append(
                    $(document.createElement('label')).attr({
                        'for':    iIndex
                    })
                    .text( colName )
                ).
                append("&nbsp;&nbsp;&nbsp;");
        });

        $("#tblExample th").click(function() {
           var iIndex = $(this).closest("th").prevAll("th").length;
           ShowHideColumn(iIndex, true);
        });
       
        function ShowHideColumn(iIndex, isHide)
        {
           try{
               var display = "table-cell";
               if(isHide == true) display = "none";
              
               $("#tblExample").find("tr").each(function() {
                  $(this).find("td:eq(" + iIndex + ")").css("display", display);
                  $(this).find("th:eq(" + iIndex + ")").css("display", display);
               });
           }
           catch(e) { alert(e);}
        }
       
        $("#tblExample th").mouseover(function() {
            $(this).css('cursor','pointer');
        });
    });
    </script>

And here is the implementation of HTML markups in body section:
        <div id="divColumns">
        Put a yes/no check on each column name below to show/hide column correspondingly:<br />
        </div>
        <br />
        Or you can click on header to hide the column at once:<br />
        <table id="tblExample" cellpadding="0" cellspacing="0" border="1" style="border:solid 1px gray;">
            <thead>
                <tr style="background-color:Gray;">
                    <th>ID</th>
                    <th>Name</th>
                    <th>Age</th>
                </tr>
            </thead>
            <tbody>
                <tr><td>0001</td><td>Henry</td><td>35</td></tr>
                <tr><td>0002</td><td>Lucky Luke</td><td>33</td></tr>
                <tr><td>0003</td><td>Winly</td><td>30</td></tr>
            </tbody>
        </table>

RESULTS:

 Try to uncheck the "Age" checkbox and see how it works. Here's the result:









Happy coding,

Wednesday 21 November 2012

6 Key Points for a good IT management job

I've been working with IT management jobs for more than 5 years. I wanna share with you 6 key points which will make your job more fruitful. That is: Job Description, Diversity, Inspiration/Motivation, Rational Schedule, End-to-end Approach and Pecking Order.


1)   Job Description: Clearly-defined Job Description is the key. Develop well-defined standards and clear evaluation criteria in the first place, or as early as possible so employees can gauge their success and we don’t have to remedy the situation at some point in the future.

2)    Diversity: Value diversity in the team. Someone might not smart but work hard, then it has compensations. Think about giving detailed tasks to people who are big-picture oriented or assigned jobs that required toughness to people who are essentially very harmonious in nature. Either way doesn't work. So build on strengths, and to compensate for weaknesses. It’s a trade-off in the team. Remember: “The whole is greater than the sum of its parts”.

3)    Inspiration/Motivation: Inspire team members to grow their skills and develop on the team. Annually, each team member is forced to learn something new and share with others (seminar, forum...). Lack of training kills productivity in the long run.

4)    Rational Schedule: Ensure appropriate schedule for different teams and persons. Tightening schedule kills the creativity and quality in the long run. But loosen schedule causes diminishing focus. Has a balanced development process; are not too gentle or too hasty in software making process. In short, keep in minds 2 important laws:
  • Parkinson's Law: Work expands so as to fill the time available for its completion. (Công việc lúc nào cũng phình ra để lấp đầy thời gian cho phép)
  • Pareto law 80 20 principle.
5)    End-to-end Approach: The work speed, productivity is pretty much same no matter it is just the right begining of project life cycle or going down to the wire (không có giới hạn khoảng cách giữa các điểm khác nhau. Tốc độ làm việc, hiệu quả đều giống nhau cho dù đó là thời điểm bắt đầu hay cuối dự án). The key thing in this approach is "Bring development processes closer to the customers". Have the customer actively participate in the design and offer feedback throughout the development process. This allows both the team and customer to better align their expectations and needs.

6)    Pecking Order: Exercising authority in the team is a indispensable measure to minimize negative conflict and make sure that “running scared” is a good thing to steer the team on the right track.

Wednesday 24 October 2012

What is a Fact table?

A fact table is the central table in a star schema that contains “facts”. A fact table stores quantitative information for analysis and is often denormalized.

A fact table works with dimension tables. Thus, the fact table consists of two types of columns. The foreign keys column allows joins with dimension tables, and the measures columns contain the data that is being analyzed. The primary key of a fact table is usually a composite key that is made up of all of its foreign keys.

A fact table might contain either detail level facts or facts that have been aggregated (fact tables that contain aggregated facts are often instead called summary tables). A fact table usually contains facts with the same level of aggregation



Types of fact tables:
There are basically three fundamental measurement events, which characterizes all fact tables.[2]
  1. TransactionalA transactional table is the most basic and fundamental. The grain associated with a transactional fact table is usually specified as "one row per line in a transaction", e.g., every line on a receipt. Typically a transactional fact table holds data of the most detailed level, causing it to have a great number of dimensions associated with it.
  2. Periodic snapshots
    The periodic snapshot, as the name implies, takes a "picture of the moment", where the moment could be any defined period of time, e.g. a performance summary of a salesman over the previous month. A periodic snapshot table is dependent on the transactional table, as it needs the detailed data held in the transactional fact table in order to deliver the chosen performance output. 
  3. Accumulating snapshots
    This type of fact table is used to show the activity of a process that has a well-defined beginning and end, e.g., the processing of an order. An order moves through specific steps until it is fully processed. As steps towards fulfilling the order are completed, the associated row in the fact table is updated. An accumulating snapshot table often has multiple date columns, each representing a milestone in the process. Therefore, it's important to have an entry in the associated date dimension that represents an unknown date, as many of the milestone dates are unknown at the time of the creation of the row.

The following diagrams provide an overview of the fact tables in the Team System data warehouse and the dimensions tables they have in common:


Tuesday 23 October 2012

Phân biệt Callback và Postback

Callback là 1 dạng đặc biệt của Postback, nhưng hoàn toàn không giống với cách Postback thực hiện. Postback giúp Client liên lạc với Server để thực hiện một tác vụ nào đó và refresh/redraw lại trang HTML. Postback thông thường sẽ gây hiện tượng co giật toàn màn hình (full postback) do phải vẽ lại toàn bộ trang. Đối với postback một phần (partial postback hay async postback), thì hiện tượng co giật không xảy ra do có một đối tượng JavaScript (ScriptManager) đứng đằng sau để vẽ lại một phần màn hình theo yêu cầu. Tuy nhiên khi trang HTML quá phức tạp với số lượng lớn các thẻ HTML được sinh ra, thì Partial Postback vẫn gây ra hiện tượng co giật nhưng với mức độ nhỏ hơn so với Full-Postback.

Trong khi đó Callback chỉ là một cách triệu gọi (thí dụ gọi hàm) đơn thuần lên server để lấy dữ liệu và đổ vào một thẻ nào đó được đặt trước (Place holder) chứ không refresh lại toàn bộ trang, và do đó cũng không gây ra hiện tượng co giật. Như vậy sẽ không thể dùng Callback để vẽ lại bất cứ một vùng nào của trang HTML. Trên server (code-behind), việc cố gắng update giao diện các Control thì sẽ trở nên vô tác dụng, điều này cũng giống như khi cố gắng update một cái gì đó trên UI tại thời điểm “unload” xảy ra (xem ASP.NET Page LifeCycle) nhưng lúc đó việc Rendering đã hoàn tất và không thực thi bất cứ một yêu cầu cập nhật UI nào. Một nhược điểm của ASP.NET là việc cố gắng cập nhật UI tại thời điểm Unload hoặc Callback đểu không gây ra Exception khiến cho những người mới bắt đầu học ASP.NET mất rất nhiều thời gian để tìm hiểu vì sao việc cập nhật UI lại thất bại!

Chúng ta có thể so sánh vòng đời của Postback và Callback như ở dưới đây. Có thể thấy là chúng giống nhau ở hầu hết các giai đoạn, trừ các giai đoạn Rendering vì Callback không tham gia thực hiện việc update UI. Một lưu ý quan trọng là khi Callback xảy ra, giá trị của ViewState không bao giờ thay đổi, tức là khi cố gắng thay đổi giá trị của ViewState trên server khi Callback xảy ra, thì giá trị ViewState vẫn giữ nguyên.





Có thể cập nhật một vùng của trang Web với Callback?
Hoàn toàn được. Nhưng chúng ta sẽ phải tự mình viết rất nhiều code, đặc biệt là JavaScript để render các thẻ HTML và điền nội dung theo yêu cầu.
Chúng ta sẽ không thể cập nhật các Server Control với Callback. Thí dụ chúng ta không thể fill data vào đối tượng GridView và render nó sau khi Callback. Để làm được điều giống như Postback, chúng ta sẽ viết JavaScript để sinh ra các thẻ <table><th><tr>… và fill dữ liệu sau khi Callback vào các vị trí tương ứng. Đây có thể nói là một công việc hết sức khổ ải vì chúng ta không tận dụng được lợi thế của các Web Control có sẵn có thể giúp render ra HTML Markup dễ dàng hơn rất nhiều.

Thiết kế định hướng Callback giúp trang Web nạp nhanh hơn so với Postback?
Không chính xác. Callback và Postback không xảy ra tại thời điểm ban đầu nạp trang. Postback và Callback xảy ra tại thời điểm khi có một yêu cầu gửi đến server tại thời gian thực (sau khi trang đã được nạp và sẵn sàng). Tại thời điểm gửi yêu cầu và phản hồi lại phía Client, Postback sẽ refresh lại toàn bộ trang (hoặc một vùng nào đó) do đó performance sẽ thấp hơn so với Callback (không vẽ lại bất cứ vùng nào trên trang). Như vậy nếu người dùng gửi yêu cầu không liên quan đến cập nhật UI từ server, thì có thể dùng Callback sẽ cho hiệu quả cao hơn so với Postback. Có thể nói về mức độ an toàn thì Callback có mức an toàn cao hơn vì yêu cầu gửi đi được thực hiện vòng (async) mà không thay đổi lại toàn bộ cấu trúc cây điều khiển của trang (Page Control Tree).

Chúng ta có thể sử dụng Callback khi thiết kế tính năng Download, kiểm tra sự tồn tại của một dữ liệu (thí dụ username), bình chọn (rate/vote), hoặc tự động nạp dữ liệu vào một số trường nào đó. Trong trường hợp này thì Callback có hiệu quả hơn hẳn so với Postback.



Callback  và Partial Postback trong Ajax khác nhau như thế nào?
AJAX là viết tắt của Asynchronous JavaScript and XML. Ajax có thể hiểu là công nghệ được hình thành bởi một tập hợp các các kỹ thuật phát triển Web, trong đó có Callback, để tạo nên các trang Web sinh động. Ajax là sự kết hợp cả JavaScript và XML, JSon.. để làm tối đa hóa công việc viết mã của các nhà lập trình Ajax.

Partial Postback là một kỹ thuật nằm giữa Callback (kỹ thuật thô sơ nhất) và Postback. Partial Postback trong Ajax sử dụng cơ chế Callback để phát động cuộc gọi lên server và cũng thực hiện các ASP.NET LifeCycle như một postback thông thường. Tuy nhiên Ạjax chỉ điều khiển quá trình rendering trên các control thay vì rendering lại toàn bộ trang Web. Ajax đóng gói các dữ liệu đã được render và gửi ngược trở lại Client. Về phía trình duyệt, Ajax cập nhật DOM cho trang Web với các thay đổi cần thiết.

Partial Postback không được hỗ trợ trong ASP.NET 2.0 (trong khi Callback đã có trong phiên bản này). Tuy nhiên AJAX đã giúp các nhà phát triển Microsoft làm điều này bằng cách bổ sung các thư viện hỗ trợ cho Partial Postback.

Như vậy Callback chỉ là một kỹ thuật nhỏ lẻ, cấp thấp và có lợi thế hơn Ajax trong việc khai thác các tính năng nhỏ để tăng mức User Experience cho trang Web.

Khi nào thì quyết định sử dụng Callback hoặc Postback?
Như đã nói ở trên, Callback đem lại sự thuận tiện cho người dùng khi phải vẽ lại toàn màn hình. Các developer thường hay mắc một nhược điểm là lạm dụng kỹ thuật Callback hoặc đối tượng UpdateManager quá nhiều sẽ khiến cho trang Web load chậm và hiệu quả cũng trở nên phản tác dụng khi hiện tượng co giật vẫn xảy ra do quá nhiều xung đột phát sinh. Do vậy tác giả đề nghị các developer cần hết sức lưu ý 2 nguyên tắc sau:
-  Chỉ sử dụng Callback đối với các action đơn giản, thí dụ rate một bài báo hoặc like một cái gì đó.
-  Đối với các action phức tạp như lưu dữ liệu, nên thiết kế full postback nhằm mục đích an toàn và hạn chế lỗi. Các developer cũng cần estimate xem một action xảy ra sẽ khiến trang Web thay đổi nhiều hay ít, nếu là thay đổi nhiều thì việc khai thác Ajax không đem lại hiệu quả nhiều, thay vào đó full postback là giải pháp tốt nhất.
 

Trong ASP.NET 2.0, các control như TreeView sử dụng rất nhiều script callbacks để thiết kế các tính năng expand/collapse. Trong khi đó GridView sử dụng callback để phân trang và sort dữ liệu mà không gây ra Postback.

    <asp:GridView ID="GridView1"
        DataSourceID="TitlesSource"
        EnableSortingAndPagingCallbacks="true"
        AllowPaging="true"
        AllowSorting="true"
        Runat="Server" />

Hi vọng bài viết này sẽ đem lại lợi ích cho những ai còn đang băn khoăn sẽ thiết kế trang Web theo hướng nào: Postback, Callback hay Ajax.

Happy Coding

Monday 5 March 2012

What is the difference between decodeURIComponent and decodeURI?

Sometimes, we post the request (search for instance) with the value of parameter ("keyword" for instance) passing on the URI, like below:

var uri="http://www.myweb.com/search.asp?keyword=lập trình C++&includecomment=true";
If keyword parameter contains the special characters like , / ? : @ & = + $ #..., the URI will be parsed incorrectly. So we have to encode the parameter.

Examples:
alert(encodeURI('lập trình C++')); ==> Return: l%E1%BA%ADp%20tr%C3%ACnh%20C++

alert(encodeURIComponent('lập trình C++')); ==> Return:l%E1%BA%ADp%20tr%C3%ACnh%20C%2B%2B

alert(encodeURI('http://www.myweb.com/search.asp?keyword=lập trình C++&includecomment=true')); ==> Return: http://www.myweb.com/search.asp?keyword=l%E1%BA%ADp%20tr%C3%ACnh%20C++&includecomment=true

alert(encodeURIComponent('http://www.myweb.com/search.asp?keyword=lập trình C++&includecomment=true')); ==> Return: http%3A%2F%2Fwww.myweb.com%2Fsearch.asp%3Fkeyword%3Dl%E1%BA%ADp%20tr%C3%ACnh%20C%2B%2B%26includecomment%3Dtrue

From MSDN JScript Reference:
The encodeURI method returns an encoded URI. If you pass the result to decodeURI, the original string is returned. The encodeURI method does not encode the following characters: ":", "/", ";", and "?". Use encodeURIComponent to encode these characters.

EncodeURI
, sometimes called fixBrokenURI or produces a "safe" URI by encoding invalid characters such as spaces and some other (e.g. nonprintable), and turns it into a real URI. It has a valid use in fixing up invalid URIs from user input, and it can also be used to turn an IRI (URI with bare Unicode characters in) into a plain URI (using %-escaped UTF-8 to encode the non-ASCII).

EncodeURIComponent
encodes the colon and slash and plus characters, and is meant to be used in query strings. The encoding of + and ? and & is of particular importance here, as these are special chars in query strings.

Now you know the real difference between EncodeURI() and EncodeURIComponent().
Converserly, DecodeURI() and DecodeURIComponent() is provided to be an inverse of EncodeURI and EncodeURIComponent.

And here the real Web example:

<input type="text" name="keyword" id="keyword" value="<%=Server.HtmlEncode(Request.QueryString["keyword"]) %>" onkeypress="if(event.keyCode==13) SearchPage()" />
document.write(encodeURIComponent(uri));
   <script type="text/javascript">    
    //<![CDATA[
     
      function SearchPage()
      {      
        var searchTerm = encodeURIComponent(document.getElementById('keyword').value); //Return "l%E1%BA%ADp%20tr%C3%ACnh%20C%2B%2B"
        var includecomment = '&comment=true';

        location.href = 'search.aspx?q=' + searchTerm + comment; //Now the query string is safe, isn't it?   Encoded URL = http://www.myweb.com/search.asp?keyword=l%E1%BA%ADp%20tr%C3%ACnh%20C%2B%2B&includecomment=true
      }
      //]]>
    </script>

Happy Coding,