I call it as const class since the class is used mainly for constants. I learned this this strategy when I used MVP for desktop applications. Concept is very simple, use this class to manage all the constants used in your application so that all the related constants are organized in a better structure.
For example, all the table name field names for a SQL table are defined in a class. Instead of hard-coded strings in your application, you can use this class to manage the table and fields names. I also added some query in the class to get some query SQLs. This makes the maintenance of my application much easier. Whenever I want to change the table or field or query strings, I know where to find them to make changes. No more need to search for the hard-code strings in my application.
Tuesday, December 30, 2008
Const Class
Posted by D Chu at 7:32 PM 0 comments
Labels: C#
Parameterized SQL Query Over Ad Hoc SQL
I have been using Ad Hoc SQL query for very long time in various .Net projects, including ASP.Net. I realized the danger of SQL injection attacks, however, in most cases, I don't provide UI for client or hacker to enter any parks of SQL query. As most people mentioned that the reason of Ad Hoc SQL queries are used in most cases is based on the fact that most of examples codes are using Ad Hoc SQL queries.
Parameterized SQL query is better than Ad Hoc SQL query not only because it could prevent SQL injection attacks. It is better than Ad Hoc one in terms of performance. SQL server has ability to cache parameterized SQL query as stored procedure so that they could be compiled and executed in less time.
Based on the second reason, I have been convert most of SQL queries into parametrized SQL query. The conversion is actually very simple in most cases. I think this should be a rule for any applications with SQL related queies.
Posted by D Chu at 6:49 PM 0 comments
Wednesday, December 17, 2008
WordPress
I have heard WordPress.Com many times and tried to browse its information. I think it is an open source based blogging tool. Anyway, today, I registered an account at WordPress with my new blog account here: chudq.wordpress.com. After I install the software, I may start blogging from the new site. A new experience for me!
Posted by D Chu at 10:01 PM 0 comments
Labels: Blog
Network Drive Mapping in SQL Database Project
Today I tried to add a feature to map to a network drive in a .Net SQL database projjavascript:void(0)ect. The codes is based Windows API functions to map to a network drive. It works fine as a windows application. However, when I tried the same codes in my SQL database project, it fails to map to a network drive. I got an windows exception about something like a log on session failure (I need to use a user and password to make a map drive). The source codes is based on aejw.com's codes.
That's too sad. Maybe there are some other ways to get around this. One way is to run an external process to make a mapping by starting a process from SQL server. Another way may be something like described in this discussion on topic of C# Mapping a network drive, running a process of net.exe directly in C#.
Posted by D Chu at 8:32 PM 0 comments
Remote Twitter Widget From My Blog
I have to remove the widget of Twitter from my blogger since I cannot access to my blog at work. The company I work does not allow me to access most web emails such as yahoo mail, hot mail and gmail. Recently Twitter is banned as well. No choice to do it.
Posted by D Chu at 8:28 PM 0 comments
Labels: Blog
Tuesday, December 02, 2008
More on SproutCore
Just read an article on Cocoa for Windows + Flash Killer = SproutCore. The article provides in depth of SproutCore and its background stories. I really enjoying reading it. It looks like that SproutCore has strong support by Apple and has great potential to rock the web development and application development. Very exiting!
There is also another article on this at AppleInside: Apple's open secret: SproutCore is Cocoa for the Web.
Posted by D Chu at 12:59 PM 0 comments
Labels: SproutCore
Saturday, November 29, 2008
SQL Send Email (3)
This is the continuing part of my previous two posts:
If the file size is too big, more than 10mb in some cases, it will cause mail application (outlook) hanging for a long time when the email is opened. In this case, it is better to send html as an attachment file. In addition to that, I could save the html file to a reporting server site so that a light notifiation email with a link to the html file could be sent.
I have posted several blogs on SQL Server Porjects. It is very easy to create a .Net project to save string to a file. Therefore, I created a SQL procedure .Net project to do the job. The store procedure is very simple:
public partial class StoreProcedures
{
[Microsoft.SqlServer.Server.SqlProdure]
public static void SaveToFile(
string content,
int overwrite0OrAppend1,
string fileName)
{
...
}
...
}
In the same way, I have created another .Net based SP to get file size. With these SPs,
here are some SQLs to save content vars to a file:
EXEC SaveToFile @htmlBefore, 0, @fileName;
EXEC SaveToFile @xml, 1, @fileName;
Finally, I use the following SQLs to send the HTML content by email:
IF @fileSize < @fileSizeLimit
BEGIN
EXEC msdb.dbo.sp_send_dbmail -- SQL SP to send email
@receipients = @p_recipents, -- recipients passed by parameter
@subject = @v_subject,
@body = @v_content,
@body_format = 'HTML'; -- set content as HTML
END
ELSE
BEGIN
EXEC msdb.dbo.sp_send_dbmail -- SQL SP to send email
@receipients = @p_recipents, -- recipients passed by parameter
@subject = @v_subject,
@file_attachments = @fileName, -- set attachment file
@body = @v_msg,
@body_format = 'HTML'; -- set content as HTML
END
Posted by D Chu at 10:42 AM 0 comments
SproutCore Presentation
I just finished watching a show on SproutCore by Charles Jolley. Note: the real show starts after 20 minutes (the first part is on Google App Engine). It is very inspiration and a fresh view. I really like the SproutCore infrastructure.
His view on the current web applications is true. There are too much loads on the server side, data, html presentation, and business logic. Click and wait is a pain process for most web applications, and you rely on server availability to see web application content.
I have started to learn jQuey and Dojo recently. This is my evening part time exploring. All these tools are very good ones to move html presentation part to client side so that data can be retrieved and updated by using Ajax on cient's requests. SproutCore framework jumps one more further step, moving the server side business logic to client side. As a result, the server is very thin!
I think this is a new way to develop web applications and we will see more smooth and desktop like web applications on web. Enjoying the exploration!
Skip 20 minutes to start SproutCore presentation.
Posted by D Chu at 10:13 AM 0 comments
Labels: JavaScript, SproutCore
Wednesday, November 26, 2008
Value2 in Excel VBA
I did a lots of VB programs long time ago. Actually, I started to develop Windows applications by using VB3.0 to VB6.0. Then since the .Net, I switched to .Net C# and VB.Net. However, VB6.0 still has its market. During this year my contract job, I have done a lots VBA applications for Excel, Word and some legacy applications which provides VB6.0 code scripts.
Anyway, I encountered one interesting issue today. I tried to use Value2 in Excel VBA codes to compare two date date types. I know that I put the same date from one worksheet to another worksheet. However, when I tried to search for the same date in another worksheet, the cells with dates are not matched:
v1 = sheet1.Cells(row, col).Value2
v2 = sheet2.Cells(col, row).Value2
If v1 = v2 Then
...
End If
When I changed Value2 to Value, these cells with the same dates are found.
I googled the Value2 and found out that Value2 does not use Currency and Date data types (ref MSDN Office developer center). These values are converted to double type. This conversion caused a very insignificant difference 0.###E-11. This difference makes them different!
By the way, I know that when float values saved in variables, the actual value is very close the "float value" such as 1.2 as 1.199999999, and the value might be dependent on CPUs or OS. That means a float values in one machine may not the exactly same as the value in another machine. For safe gard, when I compare two floating values, I always use absolute the difference to epsilon, same if less then epsilon, not same others.
However, when I looked at C#'s floating data types, I see Equal() operator or == for these data types. Not sure why they are there.
Posted by D Chu at 7:46 PM 0 comments
Sunday, November 23, 2008
Thin Server Archetecture Using Dojo
Just watched a tech show on Youtube.com on Practical Thin Server Architecture Using Dojo:
This well explained the server oriented web development and thin server web development by using client side JavaScript. I have done many ASP.NET web applications. It is true that the server side dominates everything including client side UI's by sending HTML & XML streams from server side. It is very heavy coupled between server and client.
Actually, the most important part between server and client is the data to fill for the client side UI, or passing data with request to server to data source such as DB.
Dojo provides a very good way to provide client side JavaScript codes in Dojo API form so that UI can be easily build and quickly respond by utilizing client side CPU and resources. The Widget I just learned is very clean one, Rating widget. It encapsulates all the UI codes to display icons and events to update icons. The testing HTML page is very clean.
Then web service is another great tool to use: sending request to get and put data between client side and server side. The server could be different web servers. In this way, the web application is very scalable and can be done by components. I can see that many parts are all reusable. Compared to the current way to build web applications, I am getting better picture of those new tools I am interested: REST, Dojo, jQuery, GWT, and YUI.
Posted by D Chu at 10:59 AM 0 comments
Labels: Dojo, JavaScript
Saturday, November 22, 2008
A Dojo Widget: Rating
The title is a tutorial article on how to create a Dojo Widget: Rating by mindtrove' blog. I spent some evenings on this new adventure: Dojo Widget programming. I made some changes and tests to undertand how the Dojo's API working. It is a rewarding process.
Not All Browsers Support Dojo Widget Events
I tried it on Mac and Windows, Firefox, IE and Safari. The widget works fine in Firefox and IE. For Firefox, there was only one minor issue. When I have to Vimperaotr enabled, some keys are not working such as Left, Right, Home and End keys. What I found out is that those key events are trapped by Vimperator and never passed to the widget. After I set pass-through mode(Control-Z), the keys are working fine.
However, Safari is tough. It is a UI mouse driven based browser. It does not let key events to passed to the widget. Only a few HTML DOM controls such as button and text can receive focus but not for others like span. Not sure if there is any way to change Safari's blocking.
Separate Dojo Library from Widget Project
Mindtrove' structure is to put his widget in the folder of Dojo. I don't like this. I prefer to put my customer projects outside of Dojo. Therefore, I tried to put my files like in this structure:
-html (all the test hmtl files)
-images (all the image files)
-scripts
-dojo-release-1.2.0
-[dojo folders]
-mindtrove (customer widget)
The customer widget codes are in a separate folder mindtrove, in the same level of other Dojo API library folders.
Here is the codes to load Dojo library files:
<script type="text/javascript"
src="../scripts/dojo-release-1.2.0/dojo/dojo.js"
</script>
And JavaScripts codes to load the widget:
<script type="text/javascript">
dojo.registerModulePath("info.mindtrove",
"../../../scripts/dojo-release-1.2.0/mindtrove"
);
dojo.require("dojo.parser");
dojo.require("info.mindtrove.Rating");
...
</script>
I tried to move my widget up one level, but the localization files could be not loaded by i18n.js. It looks like that i18n.js does not support cross domain scripts (widget codes outside of Dojo library folder could be treated as cross domain loading).
Add Debug and Double Click Event
When I learn something like this Dojo widget, I always like to add something at the same time. This helps me a lot to better understand structure, logic and codes. As I mentioned above to move my testing html page and Dojo library files not at the root like original codes did.
In addition to that, I have added one more attribute or property called debugKeyCode in the widget. This property is a bool(true or false) data type. I use this property to display keyCode value in the span's Title or tooltip. The keyCode value is saved in the local var preKeyCode when onkeypress event is fired on span object. In this way, I'll be able to see the key codes. Here are some codes I added to Rating.js(under mintrove folder):
dojo.declare('info.mindtrove.Rating', [dijit._Widget, dijit._Templated], {
...
// After currentValue property I added two vars.
// initial value
currentValue: 0,
// Add a property for deug key code, see Rating.html template as well.
debugKeyCode: false,
// this is a related property value to hold previous key code
preKeyCode: "",
...
postCreate: function() {
...
this.connect(span, 'onclick',
dojo.hitch(this, this._onClick, i+1));
// listern for mouse doubleclick on the span with the value it
// represents in the index of star
this.connect(span, 'ondblclick',
dojo.hitch(this, this._onDoublClick, i+1));
...
},
...
/*
* Called when the user doubleclick a star.
*/
_onDoublClick: function(value, event) {
if ( this.currentValue >= value )
this.currentValue -= 1
this.currentValue = Math.max(this.currentValue, this.minimumValue);
this._update();
},
...
_getDescription: function() {
...
var str = dojo.string.substitute(template, [this.currentValue]);
if ( this.debugKeyCode &&
this.preKeyCode )
{
str = str + ' previous key code: ' + this.preKeyCode;
}
return str;
},
...
_onKeyDown: function(event) {
...
this.preKeyCode = event.keyCode;
...
}
});
In above codes I also added codes to handle double click event. Since Safari does allow span object to get focused and to get onkeypress event, I added this feature so that by using mouse, rating can be added and removed.
Using Firebug Addon
Firebug add-on is a great tool for developers. No only it saves you a lots of time and effort to debug JavaScript codes, but it also provides some information normally you cannot get from the browser.
For example, Dojo supports Firebug by using some attributes when Dojo library is loaded. If you enable two attributes in djConfig like in following codes, you will see the Get Dojo library files in Firebug's console tab. That great to see what is downloaded and what are failed if you set them in wrong location:
<script type="text/javascript">
var djConfig={
...
parseOnLoad:true,
isDebug:false
};
</script>
Another great feature of Firefbug is that you can view the dynamically created DOM elements. By using Dojo and jQuery, you can create DOM elements, change style class, do animations on fly. Normally, I would like to see those elements in html but they are not available from browser's View Page Source or View Selection Source. Firebug does reveal the dynamic changes. That's great help.
For example, if you view the HTML tab in Firebug for this Rating widget, you will see the spans dynamically created and hidden text as well. By learning this Widget tutorial, I discovered a lots of new things, both in Dojo and Firebug.
Posted by D Chu at 1:37 PM 0 comments
Labels: Dojo, JavaScript
Wednesday, November 19, 2008
JavaScript and Ajax for Web Applications
Just read an article about Fixing Web, Part 1 referred by Ajaxian blog. It mentioned leading three tools used by developers: jQuery, Dojo and YUI. I know the first two already, actually in the learning progress and very impressed by them, the last one is new.
YUI is Yahoo! User Interface Library with set of utilities and controls based on JavaScript. I went to Yahoo! developer site for YUI and watched the overview vedio. It is another very impressive tool I am going to learn.
As the article says, "We've made major progress on the web since 2005 and the rise of Ajax. JavaScript toolkits like JQuery, Dojo, and YUI have expanded what we can do with web browsers and increased our productivity...", I really like to sharp my skills with these great tools.
Posted by D Chu at 8:14 PM 0 comments
Labels: AJAX, Dojo, JavaScript, jQuery
Monday, November 10, 2008
Dojo Does Raise Exceptions
Dojo does raise exceptions in some cases. As I tried out some example codes from Dojo Quick Start Guide: Events, I got exceptions.
The following codes explains the case:
var mineObj = {
aMethod: function() {
console.log("Running mineObj method A");
},
bMethod: function() {
console.log("Running mineObj method B");
}
};
dojo.addOnLoad(function() {
// run bMethod() whenever aMthod gets run
dojo.connect(mineObj, "aMethod", mineObj, "bMethod");
//dojo.connect(mineObj, "aMethod", mineObj, "bMethod1"); // exception!
//dojo.connect(mineObj, "aMethod1", mineObj, "bMethod"); // OK
// start chain of events
mineObj.aMethod();
//mineObj.aMethod1(); // JavaScript error!
});
The second connect(commented out) will throw an exception in FireBug:
uncaught exception: dojo.hitch: scope["bMethod1"] is null (scope="[object Object]")
The connect fails to invoke method
bMethod1
as it is not defined. However, the third connect call is OK.The last commented out code is a JavaScript error in FireBug:
mineObj.aMethod1 is not a function
Posted by D Chu at 11:00 PM 0 comments
Labels: Dojo, JavaScript
No Exception On Dojo Chain Calls
I spend about 1 or 2 days a week on learning and exploring Dojo. I really like this JavaScript based API framework. I found one very nice feature of Dojo. Not only you can call Dojo methods by using Dojo chain calls, and you don't need to worry about if any middle part of the chain returns undefined or not.
For example, I added the following codes to the head's script section:
dojo.addOnLoad(function() {
console.log("OnLoad ready to add events");
dojo.query("#testHeadingEvent")
.style("cursor", "pointer")
.connect("onclick", function() {
this.innerHTML="I've been clicked";
});
console.log("Onload fires adding event on headEvent");
});
query()
function returns a DOM node by id. If the node is not found, it's still OK. No exception is thrown. I can still see the messages print out on the console(by using FireBug add-on). Isn't that nice?
Posted by D Chu at 10:12 PM 0 comments
Labels: Dojo, JavaScript
Saturday, November 08, 2008
SQL Send Email (2)
Microsoft SQL Sever 2005 supports xml data type. This data type provides a very convenient way to hold data from SQL SELECT statement. Continue from the previous blog, the following codes set xml with data from MyData table(id, name and value three columns):
DECLARE @xml xml;
DECLARE @htmlAfter NVARCHAR(MAX);
..
SET @xml =
-- Checks if count is 0 or not. Avoid NULL value in the result.
CASE
-- @count is a var to get the count from MyData table.
WHEN @count is null OR @count = 0 THEN null
ELSE
-- Get data from MyData table
-- Note: the three columns should match the previous
-- table header column definition (3 cols)
(SELECT
td = CAST(t.ID AS VARCHAR), '',
td = t.NAME, '',
td = t.VALUE, ''
FROM MyData t
FOR XML PATH('tr'), TYPE -- As XML output
)
END;
SET @htmlAfter = N'</table></div>'
The comments should well explain how to set xml in this example case. The reason I use xml data type is that it can hold large amount of data. I tried to use NVARVAR(MAX) before. In one case, the data retrieved by SELECT are millions rows of data and my var was overflowed with some data missing. When this happened, there was not any errors or indications. It took me a day to figure it out. With xml data type, The problem is gone.
The next article will continue to discuss how to use a SQL Database Project to save results to a file and get back text size information before sending out email.
Posted by D Chu at 3:13 PM 0 comments
Labels: JavaScript, SQL
SQL Send Email (1)
I have created a stored procedure to send an email notification of some data. This is quite convenient to get notifications about database status, reports and any related business needs.
Basically, this is done by using Microsoft SQL 2005's build-in msdb.dbo.sp_send_dbmail
. It looks like that some of email related SPs have been faded out since the SQL Reporting Service launched. The reporting services provides much versatile features and allow developers to design more ad-hoc web based reports. However, email notification still has its uniqueness and useful applications.
Since my SP is used for specific notification about data status, therefore, only one parameter is defined, as recipients of emails separated by comma.
The content of the email is HTML text. Depending on the length of text, if it less than the size of email limit(see my previous SQL Server Database Mail setting), then the data are formatted as HTML; otherwise, the file will be saved as a file and it will be attached to the email out.
The following codes set HTML header part:
DECLARE @headerHTML NVARCHAR(MAX);
...
SET @headerHTML =
N'<html>
<head>
<script type=''text/javascript''>
function toggleIt(id) {
var post = document.getElementById(id);
if (post.style.display != ''none'') {
post.style.display = ''none'';
}
else {
post.style.display = '''';
}
}
</script>
</head>';
Here I added some JavaScript to hide and display detail views of data by function
toggleIt(id)
. For example, the following codes define a title node with a link referenced to the function:DECLARE @htmlTitle1 NVARCHAR(MAX);
...
SET @htmlBefore =
N'<a href=''javascript:void(0)''
onclick=''javascript:toggleIt("1")'';
style=''text-decoration:none'' title=''Expand/collapse this item''>
<H2>[+/-]My Data</H2></a>
<div class=''post-body''
id="1" style="display:none">
<table border="1">
<tr>
<th>ID</th>
<th>Name</th>
<th>Value</th>
</tr>';
After the link tag(a), the above codes add a table tag with a row of headers defined for the next data retrieved from SQL.
The next blog will continue on the topic on how to use xml type to hold SQL retrieved data.
Posted by D Chu at 1:36 PM 0 comments
Labels: JavaScript, SQL
Tuesday, November 04, 2008
Enabling PHP for Apache Server in Leopard
While I was doing coding to learn Dojo, I reached one point that I needed PHP module enabled for my Mac Apache server. By default, it is not enabled.
I found information about enabling PHP for Apache Server. The steps are very simple, however, I did not have the right to edit the file httpd.config in /private/etc/apache2. The file is owned by root user. Soon, I found a way to edit the file: logging as root user, see my Mac blog entry.
After all these settings, I made my Dojo page working with php page. Basically, Dojo web page calls the server side php page to pass information back. It is very cool. This is also my first experience with PHP web page development. One lesson I learned is that for a php page, you have to indicate it by <?php and no space between ? and php.
Posted by D Chu at 8:03 PM 0 comments
Monday, November 03, 2008
Doio: JavaScript Tool for Web Page Development
Today, I just started to learn Dojo. It is something very similar to jQuery. However, it provides core and APIs directly for Web Page development. It is very cool!
Just tried the Hello World example to display a button, to run Dojo script, to Get and Post back to server. I used my Mac with PHP to test it. It is very interest! The tool provides universal JavaScript APIs and you don't need to worry about brower syntax for DOM elements. I like it very much. This is another area I would like to invest my energy into it.
One neat thing about Dojo is that you don't need to install Dojo package or core APIs into your server. You can define <script ... src="http//..." /script> to either AOL developer's site or Google's developer's site. You will always have the updated engine for your Dojo scripts.
Posted by D Chu at 9:24 PM 0 comments
Labels: Dojo, JavaScript
Sunday, November 02, 2008
VIM, Initial Configuration and PlugIns
I have been used VIM for about weeks and started to fall in love with it. I am still in learning stage and found many some settings very neat.
The first thing is to configure VIM initial settings. This is done through the configuration file ~/.vimrc for Mac OS and C:\_rimrc for Windows. You can find many sites with good .vimrc file and use it as start. If you don't like some settings, you can change it.
Based on vimrc in the article of VIM Introduction and Tutorial, I made some changes. For example, I prefer the background color as white and tab as 2:
"Tabs are 2 spaces:
set tabstop=2
"We use a white background, don't we?
set bg=white
I found some settings and added them in .vimrc:
"Set characters shown for special cases such as:
"wrap lines, trail spaces, tab key, and end of line.
"(must be turned on whith set list)
set listchars=extends:»,trail:°,tab:>¤,eol:¶
"Set moving around at the end of line back to previous line by
"key and coursor keys, and normal movememt h and l keys
set whichwrap=b,s,<,>,h,l
"Enable C style indention
set cindent
I love special char setting, which displays tab, trial spaces, and end of line as special characters. I have to use command ":set list" to enable the setting. The move around setting enables backspace, arrow keys, and move keys h and l to move back previous lines.
There are many VIM plugins available. This is quite new for me. I found only one is working for me so far: Align. To use it, just type in the command ":Aligh =" when you in visual mode with several lines selected. Then the text will be aligned by = sign to separate left part and right part aligned by = sign.
After aligning, the text are aligned by =:
To install it, find the folder where the file "Align.vba.gz" located in Terminal. Type in the command:
vim Align.vba.gz
The file is opened by VIM. Then typing the command to read scripts and then quit:
:so %
:q
Reopen VIm again. The command
:Align
is available!
Posted by D Chu at 12:38 PM 0 comments
Labels: Editor, Open Source Libraries, VIM
Saturday, November 01, 2008
Scaling SVG Graphics with Javascript (3)
Here I would like to summarize my experience and tips about scaling svg with JavaScript.
Change Only Red Marked Scripts
First, I have shown two ways to scale svg graphics. The first way is to add scripts to both html and svg files. Even the scripts are quite long, actually you need to do is just copy-and-paste scripts. As I explained in demo, the blue area of scripts are ones you do not need to make change. The only scripts are marked as red or marked by '!!!...'.I tried to make the scripts as generic as possible so that you do not need to touch. The only scripts are variables you have to set. As in the first way to call functions from html to svg, you need to set the object tag id in html being consistent with a var in svg. This will enable the svg to attach functions to object element in html.
I would recommend you to set the var in svg first as unique as possible. For example, you can name the var as first 10 char of svg plus a time stamp as the var name like 'ClipArtDog200810281259'. If you do this, it most likely there will be no other svg in your htlm file have the same svg with this name. This may reduce your touch svg file. What you need is to verify svg's top g id name.
The second way to scale svg is done by using JavaScript only in svg file. Normally, you don't need to change the scripts. I have defined some 'constant' vars in the top part of JavaScript for the size of circle and colors for the scale down and up. You may change them at your preference. I'll add one more method to enable and disable in-svg-scaling-scripts. So you will have control from html or in svg to disable the behavior.
SVG Grphics
As you know, svg graphics are defined as in xml files. It offers great control for art designer and programmers to create vector graphics with animation effect and unlimited potentials.I used the InkScape tool to create svg with scripts(actually vim for adding scripts). When you create svg files, you may see the scaling scripts not working well. There are many reasons that may cause the problem. You should examine the svg xml file by a text editor. One issue is the transform function or tag used in the top g tag. This is not necessary because you could place the graphics in the right position by setting other position and size tag attributes. If you find it, you can remove it and use InkScape to make proper adjustment, selection and save.
Another issue is that you should not try to use scripts to create graphics dynamically since some hard-coded size values may not be scaled. As you can see my small circle with size of 5 px as radium is small enough but they are not scaled. These circles are created by script for scaling UI.
Not Working for SVG on Different Sites
As I discussed in the past two blogs, if you place your svg on different sites other than the size where your html file is hosted, the JavaScripts will not work! This is JavaScript security issue. I think there is nothing we can do. Just image if you would refer to another site to execute JavaScript codes, that would open a door for hackers to pull valuable information about the client sites and you have not place to trace down.
JavaScript has is security concern for adding scripts on html file. The browser will not allow you to execute scripts on a mysterious site.
Therefore, in order to make it to work, you have to have the total control of your html file and svg file on one site.
I am so sorry that I could not show you the demo on my blog since I cannot place svg to my blog site.
That's great experience for me to explore svg and JavaScript. I may add some more features like mirror-flip and transform to svg. I'll blog those and update my demo on my blog. Enjoy programming!
Posted by D Chu at 12:25 PM 0 comments
Labels: HTML SVG, JavaScript, Web Tools
Friday, October 31, 2008
Scaling SVG Graphics with Javascript (2)
In the previous posting, I have provided a demo example how to add scripts to scale svg grphics. I was going to add svg graphics in my blog and to show the scaling feature. However, I struggled for two days to make it working but without luck.
I can add script functions to my blog through Blogger's layout settings. In this sense, I have control of my HTML page. Here I mean by having control of HTML page is that you can edit and update the HTML page to web sever. However, I cannot find a way to submit svg graphics to my Blogger server. What I tried was to upload my svg to another site, Open Clip Art Library. I added my scripts to a svg xml graphic.
This brings a problem: my Blogger and my svg are in two different sites. What I found out is that the scripts in my blog does not have access to the scripts in my svg file. JavaScript has security reason to prevent calling scripts on other sites. What have been working in my local computer as shown in the demo would not work any more when I changed the svg reference to a different site!
In order to make this working, you have to put svg in your site.
Anyway, the instructions in my demo still work well if you follow this rule: you have the control of both html and svg files on one site.
The demo shows you a way to attach script functions defined in svg to the object in your html file. In JavaScript world, anything is object. A tag <object> is a DOM element. It also can be obtained by DOM documention object's getElementById() method. The unique feature of JavaScript is that you can attach or detach a function as a method to a object dynamically! That's basic technique I used in the demo. In this way, you can control the scale of svg from your html page.
That is one way to do it. I further investigated an alternative way to scale svg: adding scripts to a svg xml file. This provides some UIs in the svg: two small circles on the top-left corner the svg graphic with some mouse events(mouseover, mouseout and mouseup for click). By clicking on the left circle, it will scale down the svg; while clicking on the right circle, scaling up the svg.
I thought there is no attachment from my html and svg. The scripts in svg should be able to work. Nop! Since the svg is referenced by another site, any function or DOM method calls stop working.
Here is my svg with scripts at Open Clip Art Library. I put it here but the scripts in the svg do not work:
Open the dog graphic in another tab or browser window. Try it out and enjoy it!
NOTE: don't zoom in or scale the svg too big. It will slow down your browser for minutes. I event got crash once! If you scale too small or too big, refresh the page to restore to its original size.
Posted by D Chu at 7:19 PM 0 comments
Labels: HTML SVG, JavaScript
Monday, October 27, 2008
Scaling SVG Graphics with Javascript (1)
This blog, as well as coming ones, contains information about how to scale svg graphics by using JavaScript. It is based on the article of svg scaling with JavaScript. You need to have the control of the source codes of both the html page and svg so that you can add JavaScripts codes.
I discovered svg just recently, and like it very much. Inread of using jpg or png like bitmap graphics, svg is totally based xml. It is a standard way to display graphics at much more control by programmers. However, the first problem I encountered is to scale svg, or change the size of svg graphics. Soon I found the above article. It provides a very simple way to scale svg. It has limitations. The biggest problem is that it can only scale one svg graphic since it linked the graphics set dimension and scale methods to top window object. There is only one top window object.
Then I spent some week's evening time to figure out alternative ways to do it. Finally, I got a better way to scale svg. You can scale as many svg graphics as you like and the scales for each one are different. I am very satisfied with the current solution. Here I put them summarized in this and coming blogs, as well as some examples.
Here is the link to get the demo of HTML and SVG graphics files.
Enjoy it.
Posted by D Chu at 1:28 PM 0 comments
Labels: HTML SVG, JavaScript
Thursday, October 23, 2008
Stack OverFlow: Developers' Q&A Social Site
I found a very good web site: StackOverFlow. It is basically a developers' Q&A social group. You can post any questions there. All the questions are categorized by tags. I added some tags I am interested in and some questions. Actually, I posted some answers first.
I got this web site information while I was walking outside downtown Calgary during my lunch break, listening a podcast by Scott Hanselman. The topic is all about StackOverFlow web site for almost one hour. That's great talk.
Today I google the site, found it, and joined the site. One interesting thing is that you don't need to create a new account. I used my Blogger account(googl's actually) to join the site. That saves me time and brain for another new account. Just for a few hours, I earned 1 point for my reputation. It is an encouragement to spend sometime to share programming experience and learn something as well. I always get valuable knowledge and solutions from web, forums, and discussion groups. This one is the right one for me! I think I'll use it more than other ones. One shop for almost all my skill areas.
Posted by D Chu at 3:19 PM 0 comments
Sunday, October 19, 2008
SVG and DropBox Web Share Space Tool
SVG is a xml file for defining graphics and it is a World Wild Web Consortium (W3c) recommendation. It is very cool graphics. With SVG, it opens a door to create interactive and dynamics graphics with scripts so that web page content is more dynamic.
One interesting about SVG graphics is that you cannot copy the image by right click. The image is defined by xml source codes in a SVG tag. What you can do is to open the source codes and copy the SVG tag section and save it as a SVG file. You can either use a browser or Adobe SVG Viewer. There are many SVG editor tools available as well.
The graphics is defined as SVG tag in an xml file. However, one problem is that you cannot directly place the xml graphics section in a html web page. It has to be placed in the same way as other graphics, ie, referenced by a link. Therefore I could directly place a SVG graphics in my Blogger, when I first learned about SVG. Blogger does allow me to place a graphics like jpg or png files, but does not support SVG. Blogger does not provide any space for me to directly put my files.
Today, I found a web tool called as DropBox. It is a web tool to share your files between you computer and your account there. With DropBox public shared space available. I can place my svg files there so I can reference to it by using embed tag.
Here is one svg file I saved in my public space and make a short name to it:
medium
Or click Feather Pan. I got this SVG graphics from Open Clip Art Library by wsnaccad.
I created a short name by MetaMark for the long name link. The only problem is that both tools are only active if your file and link active at least something like 90 days. I am not sure how long they are available. Anyway, for a blog entry, as long as it is working for the time being, it is OK. I can change the link later on if they are not working. There always some other options available.
Posted by D Chu at 5:26 PM 0 comments
Saturday, October 18, 2008
Add Categories or Labels to My Blog
I have added Blogger's new gadget Labels to my blog. To add a gadget is very simple. Just go to your blogger's Layout tab in Customize link on the top right corner. There should a link as Add a Gadget in the layout page:
To add a label to your posts, just type a label text in Blogger's editor's lower right input box ("Labels for this post"). If you have already defined some labels for your posts, you may see some labels displayed as Label Sense Completion.
To remove a label, you have to remove that label from all your posts.
It is really nice to be able to display Categories in my blog so that I can easily jump to the posts I did before. In addition to that, I'll have a picture what I have posted. For other browsers, I think this provides valuable information about my blogs.
Posted by D Chu at 1:28 PM 0 comments
Labels: Blog
Friday, October 17, 2008
Thursday, October 16, 2008
Blogger Layout and Gadget
I have not touched my layout for a long time. Today I tried to add a twitter to my blog my new twitter account. I realized that I can also add a twitter gadget from Blogger's layout. Actually, there a tons of gadgets available. That's really great! I like some of them.
One of gadgets is Label, something like tags you can define for your blog. While you create a new blog, you can add labels on your blog. This is a very convenient way to group blogs. With Label gadget, you will provide a way for you and other browsers or follows to get interested topics. I'll try to add my own labels to my blog. Hopefully, the Label gadget will be able to provide some visual information about those labels.
Posted by D Chu at 3:37 PM 0 comments
Labels: Blog
Saturday, October 11, 2008
Web Tool: Short URL
I read an article about web tool to make URL short long time ago (last year?). That is ShortURL. However, the site may not free soon as I recall a warning in the article. Now I think that I do need a tool to redirect long urls such as my blog entries to a short one. By gooling web, I found MetaMark.
The short URL generated by this site is not a user friendly one, but it works. According to the information of this site, if the url has not been used for more than two years, it may expire. For short term use, this web tool is great. For example, my previous post is at http://xrl.us/otgzf, comparing to http://davidchuprogramming.blogspot.com/2008/10/web-tools-firebug-and-smushit.html.
Here is the form I copied from the site to do the job:
I did several tests. If you use it to generate one and try the same long URL again, the one first time generated is returned back. Therefore, you just cannot change it. It does not check if the URL exists or not. I gave a none-existing one, and it still generated a new short name, which is not not-found-url. May be this is a way to change it (by making the previous existing one invalid). The web server just generates an alternative short URL, no matter the URL you provide is valid or none-short one. I tried to get a short URL for "http://google.ca". The new one is "http://xrl.us/bemw2" (it may exist or I just generate one for it):).
A related technique about URL is to implement ASP.Net's MVC framework. Its URL is based on controller, action and router. You can construct your own user-friendly URLs. The URLs based on ASP.Net MVC does not contain .aspx or .html suffix and not url parameters like ¶1=value1... You will see more short and user friendly URLs on web. The Metamark page mentioned that it is using MVC pattern. Maybe this server just use the pattern to build a very simple, random and short URL mapped to a long URL.
You can do the same thing for your company's web pages. Most of them are not-user-friendly URLs and hard to remember. By using ASP.Net and MVC framework, you can define a structure of URL and mapping user-friendly URLs to a existing ones without any change to the old ones. It should be very simple project.
Update: One of the great feature of Metamark web tool server is that you can provide a nickname and secret. The nickname must be unique one, not taken by others. Then the generated URL is [server_home]\[nickname]-[secret]. You could create a user-friendly URL! This blog is at http://xrl.us/shortURL1-WebTool. "shortURL" has been taken. I had to add "1" to it.
The generated short URL does not take any suffix like ".aspx" or ".html", which is not needed actually!
Posted by D Chu at 4:32 PM 0 comments
Web Tools: FireBug and Smushit
Two great tools for Web developers: FireBug and Smush.it.
FireBug provides a view panel on the bottom with a lots of options to view such as Console, HTML, CSS, Script, DOM and more. If you click on Inspect to toggle it on, then you can hover your web page to see selections with updates on FireBug panel. I think it will save a lots of time for Web-developers to debug their web-pages. You may find out more about what actually in your client side web page codes when you debug your ASP.Net applications.
Smush.it is a great tool by some Google developers. You simply upload your image and to see how much it can smush. For example, I posted a blog on my Mac log with png image. After smush.it, it reduces 37%. The logic is very simple. It tries to turn off some image bits which will not make much difference in view. I'll use this tool to reduce my images on web. It for-sure will make your web page much faster for your clients!
Posted by D Chu at 1:26 PM 0 comments
Labels: Web Tools
Thursday, October 09, 2008
Apple Programming: User Defaults
Just started to look at some Apple Xcode application examples. That's a whole new huge framework for OS X. One application is about user defaults. In Windows there are many ways to store application defaults or values such as Registry, XML file, Ini file or Active Directory.
In Mac OS X, Apple provides a plist and bundle for user preferences and in Objective-C, there are some classes can be used to get user default values, NSUserDefaults for example:
NSUserDefaults *defaults;
// Get all the defautls for the current app
defaults = [NSUserDefaults standardUserDefaults];
// Register 2 defaults in case they are not available in user defaults
// Note, the registerDefaults does not change defaults.
[defaults registerDefaults:[NSDictionary dictionaryWithObjectsAndKeys:
@"Joe", @"first_name",
@"NO", @"is_married",
nil]];
//...
NSString firstName;
BOOL married;
// the following two calls will return the user's individual preferences,
// if they are available. Otherwise, it will just return the values we
// registered previously. Saves us some hassle!
firstName = [defaults stringForKey:@"first_name"];
married = [defaults boolForKey:@"is_married"];
That's quit difference way to do in Mac. Very interesting! Some good links about User Preference Defaults:
- O'Reily Mac DevCenter.com: Mac OS X's Preferences System (and More!)
- Apple Developer Center: NSUserDefaults Class Reference
- CocoaDev(WikiWikiWeb) article: NSUserDefaults
Posted by D Chu at 9:20 PM 0 comments
Labels: Objective-C
Friday, October 03, 2008
SQL Server Database Mail
I use msdb.dbo.sp_send_dbmail
to send email notification in SQL Server. Recently I migrated our DB to a new server. The problem I encountered is my SQL SP does not working any more.
Finally, I find out this is the SQL server configuration issues. There are some configuration settings to be done on SQL server level.
First, I have to turn the mail feature on by using the command:
sp_configure 'Database Mail XPs', 1
reconfigure
Next, I have to configure the Database Mail. Here is the picture to access the configuration:
where you have to create a Database Mail account and profile. Basically, the configuration contains information about mail server, SMTP Authentication. The profile will be created for you after you add a new account.
One thing you have to do in the Database Mail configuration is that to set the default profile as you will use in
sp_send_dbmail
so that you would not need to specify a profile.For my case, I use this sending mail feature to send file attachment in some cases. My notification report mail contains information from DB in html format. The content may be very big. If the content is very big, it will take time to open the mail. In case of very large size content, I'll send the report as an attachment file.
By default, the file size for Database Mail configuration is 1,000,000 bytes. It is very small in most cases. I have to change it to 10,000,000 or about 10MB. This can be done in Database Mail configuration.
After all these settings, my email notification runs with success.
Posted by D Chu at 9:34 AM 0 comments
Labels: SQL
Thursday, October 02, 2008
ASP.Net MVC
Just watched a training video Creating Task List on ASP.Net MVC. It is very impressive. MVC design pattern has been used for Windows application and now the framework for ASP.Net is available.
I have used this or MVP in several desktop applications before and I have not touched this type of design for several month. I'm very glad to see the new package available.
MVC pattern provides very good design infrastructure with separations of UI, Controller and Model. In addition to this model, I prefer to add a Repository level to separate data base and classes. The Repository model is responsible to provide data as objects and interface for updating objects back to DB.
Any good design pattern does not resolve all the issues. Still you have to keep good practice to use them. I understand that the tutorial video is just an instruction to MVC. My comments on the practice in this video is that there are too many client to server calls. To create a new task you have to make a call to server side to add a new task. However, to mark a task as completed, I don't think that the Complete action call to server for each edit is necessary. It could be done on client side to mark one or more tasks as completed. Add a Save button to save changes. This will avoid frequent calls to server.
In order to do that, I think client side script may be needed to handle these changes. In addition to that, you have to handle redirect change by client to another page. That means a warning message to indicate changes.
New design patterns would provide a gateway to design a better applications. You should remember that that does not resolve all the problems or make your application in a good structure. It'll take time to master skills to develop good applications.
Posted by D Chu at 9:18 PM 0 comments
Add Scripts to Client Side Page 3
In my first post on this topic, I mentioned that there some cases that prompts may not be desired. You can avoid prompt display for a control's click event by calling the base class's method BypassModifiedMethod()
.
This method actually disables the prompt display by setting the client side page level script var on click event:
m_needToConfirm = false;
However, in case of saving failure, such as exception raised from back-end DB, a postback call may be called back to the client side with some error message being displayed. This would cause a problem: if the user redirects to another page, the prompt would not be displayed and the changes may not be lost.
To resolve the problem, I added a method
ResetOnSubmit()
in the base class. You should call this method on Page_Load
event for postback case if you want to reset the flag variable back.protected void Page_Load(object sender, EventArgs e)
{
...
if (!IsPostBack)
{
base.ResetOnSubmit();
...
}
...
}
Another handy method I added to the client side base class is
DebugChanges()
:protected void DebugChanges(
WebControl wc,
string wcEventAttribute,
string clientIDForDisplay)
{
string script = string.Format("javascript: displayChanges('{0}')",
clientIDForDisplay);
wc.Attributes[wcEventAttribute] = script;
}
where
displayChanges()
is a client side javascript function registered on the client side page level. This function will display the current monitored changes and original values on a WebControl specified by control's event. You call this method in Page_Load event to add this debug feature. You can decide when the control is visible. I used a URL request parameter to enable the visibility of a control in one case. See my previous post on Using Query String Parameters in ASP.Net Page.As I promised in my previous post, here is the source codes of ClientSidePage class.
Posted by D Chu at 10:19 AM 0 comments
Labels: ASP.NET, JavaScript
Wednesday, October 01, 2008
SQL Server Project (5)
I have written several blogs on SQL Server Projects. Here is the list of links of previous posts:
Recently we moved our SQL server from one virtual machine to a real PC SQL server. DBAs created the new server and installed a blank SQL server. After that, we had to move our DBs to the new user.
Generally, DBAs don't give us sa password. What they did is to created an appsupport user with almost as same as settings as sa for us. We use this user to back up the existing DBs and copied to the new PC for restoring.
The restoring process went very well. Almost every thing has been set up as same as the existing DBs. However, for SQL database project, as I mentioned in previous articles, some Asymetric Keks for assembly keys and Log Permissions have to be set up in master db. Fortunately, I logged the steps to do that (as I wrote in my previous articles) and restored the keys and permissions in master DB.
One thing I realized that the master DB as created by sa and our other DBs with SQL database projects were restored by appsupport. The owners of these DBs are different. As a result, I could not deploy my project to DBs. The error messages say that the owners are different and they could be changed by ALTER... I used this command to change the DB(MyDB for example) owner:
ALERT AUTHORIZATION DATBASE::MyDB TO sa
I think that if DBs' owners are different, you cannot deploy your project from Visual Studio 2005. You have to make change to keep them in sync.
The second thing I had to do is to set DB TRUSTWORTH on:
ALTER DATABASE MyDB SET TRUSTWORTHY ON
since I referenced System.Web.dll framework assembly in my SQL database project. Otherwise an exception would be thrown out when Ssytem.Web.dll classes are called.
The last thing is to give permissions to Windows' users since I have to use VS to deploy my project remotely to the SQL server with Windows authentication. Instead of give permissions(alter and create assembly) to one user, I created a Role on SQL server DB called as db_developers and adding my user name as a member of the role. Then I set related permissions to the role.
After all these settings, I can deply my project remotely to the SQL server DB and run the deployed assembly based ST with success.
Posted by D Chu at 5:17 PM 0 comments
Labels: SQL
Friday, September 26, 2008
iPone Application: MoveMe (continued)
Finally, I finished my build of MoveMe application from scratch. That's the first demo application for beginner developers. I thought it is better if I build this application by myself. I added one piece by one piece. That's quite good experience. Since Object-C is new for me, it takes some time to gain experience.
Xcode is Microsfot VS like IDE. It is hard to compare two. My first impression is good. IB (Interface Builder) is something like .Net's new Expression Blend. As its name description, it is use for UI design and link UI components, actions(for events) to class codes. At first, I did not have any clue how to use it. I thought these connections or linking must be done through IB's UI such as property, tab or dropdown list. However, when I tried to link MoveMeView class to a component in IB's outlet, I was lost. Finally, by watching some YouTube demos on IB, I figured out the linking is done through drag with Control key and drop. It's quite innovative way. I have to understand IB or Mac's way to do it.
The second lesson I learned is that parameter names in a method has to be matched if it is a delegate method. For example, when I typed in the codes for MoveMeView.m codes, I missed i in the animation delegate method's parameter name "finished":
-(void) animationDidStop:(CAAnimation *) theAnimation finshed:(BOOL) flag
As a result, the animation of MoveMe button only works at the start and then no respond after I moved it. Finally, I found the mis-typing error. It is the signature of method not matched. In Objective-C, you can call a method on object that may not defined. It would not generate an error or cause compiling error. It is OK. That's very nice. However, it may cause some very hard find bug. After I corrected my mistake, the application finds it's matched animation delegate method, and works fine. The bug caused my animation never stopping.
Another good lesson I learned is the Frameworks in Xcode project. It is similar .Net project's References. Since I created a new iPhone project in Xcode from scratch. Xcode did not add animation framework class QuartzCore.framework, which is used in MoveMe example project. I typed in codes in MoveMeView.m file. It includes the QuartzCore's header files like this:
#import <QuartzCore/QuartzCore.h>
and when I typed animation class names and methods, Xcode does show them in intellisense. However, when I compile the application. I got some errors about references not found in xxx.o. I was confused and there was not further indication where in the codes where the error is. Eventually, I realized that it is the library files missing. I have to include animation's library into the build file. In Xcode, all the libraries are under Frameworks folder in the project.
It has been very productive period for me. I got my built MoveMe working. There are some similarities between Objective-C and .Net C#. With my knowledge and experience in .Net C#, it is not so hard to understand Objective-C. However, Objective-C does have its unique features and power. I would like to continue to learn it and to develop applications.
Posted by D Chu at 9:22 PM 0 comments
Labels: iPhone Applications
Sunday, September 21, 2008
iPone Application: MoveMe
I started to learn iPhone application development from Apple's iPhone Dev Center. The first application is MoveMe. The material on this application gives overall description on main items in the application, but it does provide hands-on information about how to build the application by steps.
I tried to create all the classes, resources files, and windows xib files from scratch. It is not so easy. XCode provides good IDE for coding, however, I could not find similar convenient ways as I have done .Net applications by VS.
I am still in the progress to get MoveMe build up and working. One thing I found out that the window xib file has to be specified in the Info.plist file (which is under Groups & Files->Resources):
I did not use MainWindow.xib file. Instead, I created MainMoveMe.xib file. When I first run it, I got crash exception. The problem was caused by this "Main nib file base name" in Info.plist.
After I got this window file, still I could not find a way to link delegate to MoveMeAppDelegate class in Interface Builder. Since I created this window file, I have link windows to classes through Interface Builder. Anyway, it is quite interesting experiences to learn and develop iPhone Application. I'll keep log my experiences.
Posted by D Chu at 9:24 PM 0 comments
Labels: iPhone Applications
Wednesday, September 17, 2008
iPhone, Android and Windows Mobile
It is getting very crowed in mobile phone. iPhone from Apple is mainly for hight-end users. It is very existing mobile phone. However, it has some limitations. For example, you can only run one application at one time and limited openness in iPhone SDK APIs.
Google announced Android early this year, and formed Open Handset Alliance a group of more than 30 technology and mobile companies. It is based on Java framework. It supports multi-processes and is expected to be run over a wide range of handsets from 12 keypads low-end ones to high-end ones. The first mobile phone supporting Android is coming in just a few weeks time.
Microsoft also put a lots of investment and efforts on Windows Mobile and a few mobile companies have already used it.
I think early next year we will see more interesting mobile phones with great applications available on the market!
Posted by D Chu at 2:25 PM 0 comments
Labels: Android, iPhone Applications, Windows Mobile
Tuesday, September 16, 2008
Add Scripts to Client Side Page 2
I have changed the ClientSidePage class. In the following articles, I'll use my updated class as examples. It is very easy to use the class, first use the ClientSidePage class as base class, and then use the base class method MonitorChanges()
to add a web control for monitoring any changes.
For example, here is the code to add a textbox control for monitoring:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
base.MonitorChanges<TextBox>(MonitorChangeControl,
CONTROL_ID_MONITORCHANGECONTROL);
}
}
where
MonitorChanges
is a TextBox control placed on aspx page. It is directly accessible in the server-side code class, and CONTROL_ID_MONITORCHANGECONTROL
is a constant defined in the server-side class. I prefer to define control ID in a region in a class so that can be be easily maintained in once place instead spread all over the places.One change in the method is that it is a method with generic type T, where T is constrained with
WebControl
class. The first parameter is a web control or the parent control where a specified control can be found by control's ID. In some cases, you may place some web controls within a GridView
's templates. Those controls cannot be directly accessible. You have find them by their parent container such as GridViewRow
control. In this case, you can pass in the GridViewRow
control.With the method, I used another class to find a web control. This makes it easy to use. You don't need to add some codes to find the control. See my previous blog on Find a control in ASP.Net Page.
You can monitor as many web controls as you want. However, from my experiences, I found there are too many problems to directly monitor each editable web controls. Some times you don't know how many they. For example, a
GridView
control may be bound to a database with dynamical rows of data. As a result, it is very hard to maintain.The second issue is you have to understand when to initialize these controls on the client side script. As I mentioned in my previous article, the ClientSidePage class registers two groups of scripts on client side page. One is the startup scripts, where the method
assignInitialValuesForMonitorChanges()
is called when the web page is loaded. However, some web controls may not have data values available in the first loading process if the control is bound to an object data source and the object will be created on server side codes. The control may be late postcalled back to set values. In this case, the client side array for initial values would be nulls. What I find out is that I have to call MonitorChanges
at the time the control is bound to data on server side. Then I use another overloaded method to pass initial values to the client side script so that the array could be initialized with correct values.protected void GridView_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
GridViewRow row = e.Row;
base.MonitorChanges<CheckBox>(row,
CONTROL_ID_ISEMPLOYEECONTROL, true);
}
}
What I find out is that I don't need to monitor each web controls. What I need is to monitor only one
TextBox
control. It is initialized as empty. If any other control values are changed, this monitored control's value will be something like "Some data may have been changed. Click on Save button to confirm the changes". In order to achieve this, I added two methods on ClientSidePage class. The first one is
SetScriptOnClientSide()
. This method will register two groups of scripts to client side in the same way as CliendSidePage does: a group script for starup and a group script for script block. These two groups of scripts are customized scripts with a customer provided registry key. This will make sure ClientSidePage registered scripts will not be conflict with customized scripts. You add whatever scripts you want to the client side.SetControlEventScript()
. This method takes three parameters, one for WelControl object, a string for an event attribute, a string for script, and a position to indicate where to add the script to the controls' event attribute if it has some scripts defined already.Here is one example I use these methods in one aspx web page server side codes:
private void SetScriptsForClientSidePage()
{
string script;
/* Monitor one text box control: MonitorChangeControl with its control ID*/
base.MonitorChanges<TextBox>(MonitorChangeControl,
CONTROL_ID_MONITORCHANGECONTROL);
script = @"
<script language=""JavaScript"">
function {0}
{
var v_elem = document.getElementById('{1}');
if ( v_elem )
{
v_elem.value = '{2}';
}
}
</script>
".Replace("{0}", SCRIPT_FUNC_SomeValueChanged) /* constant for function name: "SOmeValueChaned()" */
.Replace("{1}", MonitorChangeControl.ClientID)
.Replace("{2}", SCRIPT_CHANGE_MESSAGE); /* Message like "Some data may have been changed. Click on Save button to confirm changes or click on Cancel to revoke changes." */
base.SetScriptOnClientSide("script", null, script);
/*Add scripts for one text box control: CurrentSales */
script = string.Format("{0};",
SCRIPT_FUNC_SomeValueChanged);
string eventOnChange = "onchange";
ScriptInsertPosition pos =
ScriptInsertPosition.BeforeExistingScrit;
base.SetControlEventScript(CurrentSales,
eventOnChange, script, pos);
}
This private method is called in the Page_Load() event when the page is first time loaded: monitoring one text box control, adding client side script with a script function definition, and adding event script for a web control. After done this, I always to view the client side source to verify my scripts.
The next article will provide the codes of ClientSidePage class.
Posted by D Chu at 2:14 PM 0 comments
Labels: ASP.NET, JavaScript
Monday, September 15, 2008
Add Scripts to Client Side Page 1
I have read an excellent article on how to add client side scripts to monitor changes and prompt user if a redirection call is fired by Scott Mitchell. He later updated the class to disable prompt in case there is no need such as Save and leaving the page.
I have used this class in my project. I found there are some features missing and then further updated the class. In this article and later on articles, I'll discuss how to use this class.
Basically, the class ClientSidePage is used as a base class for an ASP.Net Web Page (server side codes). You can use this class to monitor changes made by client on the page for editable web controls by the method of MonitorChanges().
Here is the way how it works. This method will register two script array variables (page level) on client side, one for monitored control's IDs and another for initial values for those controls.
In order to make this to work, the ClientSidePage class registers two groups of scripts on the client side: startup script and script block. The startup script is a group of scripts that will be called when the client side web page is loaded. This is for initialization purpose, for example, setting the monitored array with initial values by a script function assignInitialValuesForMonitorChanges()
, which is defined in the second script group. This function initializes the array of monitored values as original values, and set a page level variable, m_needToConfirm
, to true. This is a flag for confirming changes.
The second group of script, script block, contains some client side function declarations, page level events, and variables such as variable m_needToConfirm
, and function assignInitialValuesForMonitorChanges()
as mentioned above. Another example is to set page event window.onbeforeunload
is set to a script function confirmClose()
. When a unload page request is made on client side, the window.onbeforeunload
event is called. The function confirmClose()
checks if the flag variable is set and any monitored control' values are changed or not by comparing control's value to the original values. If so, a prompt is displayed with a message to confirm leaving the page with two options: OK for leaving the page, and Cancel for staying.
By the way, in Google's Chrome beta version browser, the OK button is "Leave this page" and "Stay on this page" for Cancel.
Most browsers have view source option. You can view those groups of scripts by this option. I like Chrome's viewing source. It opens a new tab with page's source codes, and it is very nice to search. For example, you can search for the variables, arrays, or functions as mentioned above. The searched strings are highlighted with yellow color and there are marks on scroll bar to indicate their positions. You can easily location them and know if they exist right away. Maybe that's Google's strength: search everywhere and know where they are.
There are some cases that the prompt are not desired. For example, a user makes some changes on a page, and then click on a Save button to save changes. Normally the saving request is a postback call to the server side, where changes are saved and new/refreshed data are sent back to the client side. In this case, the prompt is not needed. Scott updated the class to handle this case. Read his articles for details.
Posted by D Chu at 3:51 PM 0 comments
Labels: ASP.NET, JavaScript
Saturday, September 13, 2008
Mac Software Development
I have have done my software development mainly in Windows Platform, some in Unix long time ago. I have got an iMac in March this year. Since then I spend a lot of my time using it at home. I really enjoy it. Recently I have installed XCode on my Mac and watched training videos about iPhone Application Development API kit.
It is very interesting to learn Objective-C and Cocoa framework even they are very different from .Net languages and framework. iMac computer is very easy to use and very stable. From what I have seen from Apple's training materials, the Objective-C and Cocoa are also very straight forward in syntax. Objective-C for Mac applications uses MVC pattern. That's the one I have seen on Microsoft's P&P team as well. I think there are a lots similarities between both.
I'll spend some time to learn Mac application development. Maybe I'll get more and more involved in Mac software development. Enjoy the new adventure!
Posted by D Chu at 8:01 PM 0 comments
Labels: Mac
Tuesday, September 02, 2008
Google Launches Chrome Web Browser Today
It is getting more crowded in the web browser war. I have IE that is a part of Windows, Firefox, an excellent open source browser with multi-tabs and add-ins, Safari for Mac, and others rarely used. Now Google enters the web browser competition with Chrome!
It is a positive thing for most end users for sure. I think Chrome will have some special offers for us. First, it is built based on IE but it is open source. Soon it will be available for Mac. That means that we could have alternative browser for IE in Mac with IE special features. Secondly, its infrastructure is sandbox so that each process has its own rights which mean more privacy. Another related benefit is that one process crashing would not affect others like tabs and mails.
I think the biggest thing why Google decides to have its own browser is that the current browsers have too many dependencies. Many of Google's products and great features are depending on browser and end user decisions. For example, Google released Google Gears which provides off-line browsing. That's a great feature for most end users. The browsing process would more smooth and faster. The real-time data can be updated by the back-end database store and processes when the Internet connection is available and there is need to fresh the data. However, it is an add-in. It will be up to the end user to install it. Without the installation, it would not work.
jQuery is another great feature for web browsing. It loads additional JavaScript libraries. There are already many jQuery add-ins or plug-ins available and Google shows great interest in it. However, many features will depend on end users to install them.
I guess that Chrome will install Google Gears and many other add-ins as components by default. This will make Chrome very unique and outstanding. Many advanced features will be available right away. That will shine Chrome for sure.
Welcome Chrome to the web browser world!
Posted by D Chu at 11:48 AM 0 comments
Labels: Web Tools
Monday, September 01, 2008
jQuery
Today I read David Hayden's blog on jQuery. It is a quite interesting JavaScript library. I tried some tutorial examples and get some tastes on how to use and its initial power.
I downloaded the library jQuery-1.2.6.js source code. Then I created a test html file. I followed the instruction to save the js file in the same folder as the html file. Then I tried some example codes to hide a reference link <a...>, add a style class to the link, add a click event to the link, and some chained queries. Basically, this library provides API functions to manipulate DOM objects or elements, handle events, perform animation, and add Ajax to your web project. As David recommended, jQuary in Action is a good book for beginners.
I'll spend some time to try out and learn this great tool. Hopefully I can use this in my web projects.
Here is a training video program by a 12 years old child in google engEdu:
Here is very good reference to jQuery API libraries: Visual jQuery 1.1
50+ Amazing jQuery Examples. Unfortunately, some links are not available. However, some are really amazing web pages.
Posted by D Chu at 10:03 PM 0 comments
Labels: JavaScript, jQuery
Sunday, August 31, 2008
Collection Filter Function
Let's continue the topic of my previous blog on .Net Generic and Value Data Type with an example of collection filter function for generic value data types. This function takes two collections, the first one as input collection and another one as filter collection. The returned collection will filter out all the items in the filter collection from the first collection. In this case, in order to filter items, the value data type makes sense when comparing equalities for all the items in a collection to an item. For reference data types, however, it is hard to tell equality or not, by reference or property members? You even can expect multiple-levels if some property members are reference types.
public IEnumerable<T> FilerCollections<T>(
IEnumerable<T> list,
IEnumerable<T> filterList)
where T: struct
{
if ( list != null )
{
foreach (T item in list)
{
bool found = false;
if (filterList != null)
{
foreach (T filterItem in filterList)
{
if (filterItem.Equals(item))
{
found = true;
break;
}
}
}
if (!found)
{
yield return item;
}
}
}
}
Here is the test program:
Test t = new Test();
IEnumerable<int> list;
List<int> list1 = new List<int>(new int [] {1, 2, 3, 4});
List<int> list2 = new List<int>(new int[] {3});
list = t.FilerCollections<int>(list1, list2);
if (list != null)
{
foreach (int item in list)
{
Console.WriteLine("item: {0}", item);
}
}
else
{
Console.WriteLine("List is empty");
}
and the result screen:
Posted by D Chu at 3:45 PM 0 comments
Labels: C#
.Net Generics and Value Data Type
I use .Net Generics a lot. The great benefit is that you can make your codes reusable even you may use it only for one data type. You may extract the generic class or method to a library to a library for reuse. Secondly, it still keeps type safe or strong type integrity. Any attempts to use wrong type will be caught at compile time instead of run time.
The generics can be specified by where clause. In most cases I use generics for reference data types, i.e., classes. If you say a generic as class, that means the generics data type is a reference type. You can use new() to further indicate the class can be instantiated by the default constructor with no parameters. If you specify the class a specified class, that means any class which inherits from the class can be used for the generics class or method.
You cannot use more than one classes in where clause, however, you can use interfaces to specify that the generic class should implement some interfaces. Then in your generic class or method, you can safely call the implemented interfaces or methods.
How about value data types such as int, string or double as examples. You can use struct in the where clause. If you want to use the nullable value data types, you can simply use ? after the generic type, such as T?.
class Test
{
public T GetValueOrDefault<T>(T? item)
where T: struct
{
return item.GetValueOrDefault();
}
public T? GetValue<T>(T? item)
where T: struct
{
if (item.HasValue)
{
return item.Value;
}
else
{
return null;
}
}
}
here are codes to call the methods:
Test t = new Test();
int? a = 2;
a = t.GetValueOrDefault<int>(a);
//t.GetValueOrDefault<Test>(t); //Error: t is not none-nullable data type
Console.WriteLine("GetValueOrDefault<int>(a) = {0}; GetValue<int>(a) = {1}",
t.GetValueOrDefault<int>(a), t.GetValue<int>(a));
a = null;
Console.WriteLine("GetValueOrDefault<int>(a) = {0}; GetValue<int>(a) = {1}",
t.GetValueOrDefault<int>(a), t.GetValue<int>(a));
Console.WriteLine("GetValueOrDefault<int>(a) = {0}; GetValue<int>(a) = {1}",
t.GetValueOrDefault<int>(3), t.GetValue<int>(3));
The result of the above codes in a console is:
Here is an interest posting on .Net Generics and a question about enum data type.
Posted by D Chu at 11:47 AM 0 comments
Labels: C#