Structure in Web Development (1)

This is study notes of web development involving the relationship and value passing between technologies.

HTML, Hyper Text Markup Language, as its name suggested is a markup language, which does formatting for the document; such as font, border format for cells in table, etc. There are two parts in HTML, head section and body section. Head contains all metadata, controls and the body is the document to be presented in web browser. When URL called by browser, whole HTML file is downloaded in the browser’ computer, which means it is a client side process.

To be easily and programmatically changed or updated, all formats can be centrally managed by a separate file, with extension of .css. This is the file of Cascading Style Sheets, or CSS. The inner link between two files is done through the following declaration to be included in the head of HTML:

‹link rel="stylesheet" type="text/css" href="cssFilename.css"›

In addition, in each division of HTML, “class=”classInCSS”” is needed to point the format class in CSS file. There is no value passing between two files.

Both HTML and CSS do not have programming functionality. To add the programming functionality, JavaScript can be added in HTML. Since programming functions are not of the presentation, it therefore locates in the head of HTML. However, when JavaScript consists too much contents, it can be separated as a file with extension of .js. The inner link between two files is done through the following declaration to be included in the head of HTML:

‹script type='text/javascript' language='Javascript' src='javascriptFileName.js' ›‹/script›

When JavaScript file is called by the HTML in browser’s computer, the whole file is downloaded too. So, JavaScript is also the client side process. Since contents of HTML may need to be changed frequently, separation of HTML and JavaScript may help to improve the refresh speed because programming functions may not change so frequently. This is another reason why JavaScript needs to be an independent file. However, this reason may not sustainable in DHTML scenario, to be mentioned late. At this stage, we deal with the HTML with static contents.

Functions in JavaScript need to be invoked. It can be done through window events, such as mouse move, mouse over, mouse out, mouse click or HTML page on load, etc; or through the calling from another funcation. Since HTML content is static, when value in HTML need to be passed to JavaScript, it is no need to be dealt specifically. Programmer can just use that value when write JavaScript file. In other words, there is no value passed from HTML to JavaScript, apart from invoking action. However, if value passing from JavaScript to HTML is needed, it can be done through “documnt.write()” and “.innerHTML =” methods. “documnt.write()” is located within the body of HTML. Since HTML body is for presentation purpose, to use “documnt.write()” one much first declare it is of JavaScript scripts:

‹script type="text/javascript"›
document.write(' javascriptVariable ');
‹/script›

The major difference between “documnt.write()” and “.innerHTML =” is “documnt.write()” does not need trigger to be active, simply because it is located in the body of HTML. When HTML page loaded, it is invoked. On contrast, “.innerHTML =” is located in JavaScript section/file, it needs to be called either by window events or other functions. Generally, “.innerHTML =” method is recommended. For instance:

document.getElementById('aDivision').innerHTML = javascriptVariable;

By this way, the value javascriptVariable generated from JavaScript functions is delivered to a HTML division called “aDivision”. Since HTML is only the markup language, there will be no variable involved in pure HTML. Variables need to be declared in JavaScript. Indeed, by this way, HTML can have variables. In addition, by this way, the delivered can be not only a value of single variable, but also more complicated contents:

var dynamicTable = ‘‹table›‹tr›‹td›’ + javascriptVariable + ‘‹/td›‹/tr›‹/table›’;
document.getElementById('aDivision').innerHTML = dynamicTable;

Please note, variable dynamicTable now contains some HTML codes, as string. The actual delivered now is no longer the single value but a complete table. This is very much same concept of Dynamic SQL if one is familiar with the database. This indeed is the basic concept of Dynamic HTML, or DHTML, for which the contents together with associated HTML codes are dynamically generated by the running of JavaScript functions.

Each HTML together with its associated CSS and JavaScript files are an independent program. If there are more than one HTML pages in a website, how they are structured? Since HTML and CSS files do not really involve the value passing, Multiple HTML pages can share a single CSS file. One HTML can have more than one JavaScript files by declare both of them in the head:

‹script type='text/javascript' language='Javascript' src='javascriptFile_1.js' ›‹/script›
‹script type='text/javascript' language='Javascript' src='javascriptFile_2.js' ›‹/script›

When a function is called, the browser will first search if “this” file have this function, if not, it would automatically goes to other JavaScript files declared in same HTML file.

It is not recommended to share JavaScript file between HTML pages. Because invoking any function is through window events, such as on page load etc. Sharing JavaScript file just confuses the computer and yourself, on which page load, for instance. Window events such as “onload” is very much HTML page specified and is not generic. However, for those generic functions with absolutely no window events involved, it can be aggregated into a JavaScript file to be shared by multiple HTML files.

Since each HTML page is an independent program, access to other’s functions or passing value between HTML pages is not recommended, for the sake of programming convention as well as security concern. In special cases like one HTML page (child) was opened by another HTML page (parent), it can be done with limitation. For instance:

In parent JavaScript file:

var windowChild = window.open(url); // “url” is the string variable.
windowChild.close();

In this example, parent JavaScript opens a new HTML window and close it immediately.

In child JavaScript file:

var valueFromParent = window.opener.valuePassToChild;

Child HTML can thus access the value of a variable in parent HTML. In case the child window is opened within the iFrame of parent, it is :

var valueFromParent = parent.valuePassToChild;

Please take special note, this syntax is also true for object reference passing through HTML pages. We know that the reference acts as pointer to point to original variable rather than make a copy, any using of the reference, valueFromParent here, is indeed referencing back to parent HTML ‘s object. It does generate the issue of speed. For details, see http://koncordpartners.blogspot.com/. So, please do apply this to the object other than simple variable, such as array.

Following is the method when parent window calls functions located in iFrame child:

document.getElementById('iFrameID').contentWindow
.functionInIFrame(parameter);

If one include this into another function, that function indeed can be called by same or other iFrame windows:

In parent JavaScript file:

function crossWindow(parameter)
{ document.getElementById('iFrameName').contentWindow
.functionInIFrame(parameter);
};

In iFrame file:

crossWindow(parameter);

Unfortunate, the string iFrameName should not be variable, otherwise dynamic function will be involved. Furthermore, dynamic reference passing does never work properly. It therefore dynamic reference and dynamic function should be avoid. In this example, one can use “if” statement to pick up right inner function:

function crossWindow(option, parameter)
{ if (1==option) document.getElementById('iFrameName_1').contentWindow
.functionInIFrame(parameter)
   else document.getElementById('iFrameName_2').contentWindow
.functionInIFrame(parameter);
};

When “parameter” is reference to variable located parent window, things become little complex. JavaScript indeed regards it is about the variable in iFrame window. One needs to declare parameter locally first:

var parameter = parent.paraInParent;

What about in iFrame child window, calling corssWindow() function is through dynamic insertion? Something like:

window.onload = function()
{ document.getElementById('dynamicContent').innerHTML = '‹a href="#" onclick="parent.crossWindow(‘ + parameter + ‘)"›Click here to run function in parent window‹/a›';
};

No, it would never work properly if parameter is the reference referring back to another variable in parent window.

(To be continued)

Issues of Array in JavaScript

It is noticed the initialization of a variable when declared as an element of array in not allowed. For instance:

var arr = [1, 2, 3];
var num = arr[0];

Assigning value to variable num "num = arr[0]; " needs to be done separately.

Since JavaScript arrays are assigned by reference, when array to be passed across iFrame, an issue of speed was met, especially for Mozilla Firefox.

Scripts in iFrame page:

var newArray = parent.arr;

When calling newArray[0] immediate after above declaration, it often generates error of "newArray is not defined". HTML pages are actual independent programs (stateless), it is no wonder reference across programs facing such kind of problem. It is therefore suggested avoiding passing array across parent page with iFrame page. Alternatively, slice array into single dimensional variable will do.

The reason behind this issue is this syntax of passing value is also true for object reference passing through HTML pages. We know that the reference acts as pointer to point to original variable rather than make a copy, any using of the reference is indeed reference back to parent HTML's object. It does cause a complex process behind the scent.

For same reason, if one wants to turn array in JavaScript, the best approach is to turn it into a string first, then pass the string to php, then use explode() to turn it back to array in php.


http://www.webdeveloper.com/forum/archive/index.php/t-93920.html

iFrame Height Issue

Changing height of iFrame from JavaScript function becomes painful task in new versions of both IE and Firefox. However, if one uses iFrame, adjusting its height to fit its contents is essential. The problem is the height of content is unknown when dramatic feeding required. The “orthodox” method to accomplish this task is to open iFrame with any height first, then adjust it on onLoad event. Width is less painful because for those iFrame to fit complete screen width, width=“100%” can be defined when iFrame is defined.

Basic idea of this “orthodox” approach includes two steps, detect the correct height and resize to it.

Detecting methods include:
- document.documentElement.clientHeight
- contentWindow.document.body.scrollHeight

Resize method is:
- document.getElementById('myIframe').style.height = newHeight

Basically, this approach does not work. There are several problems around it, such as assignment to .style.height does not work in Firefox. More serious problem is contentWindow.document.body.scrollHeight will return permission denial error message if host page and iFrame content page are not in the same domain; more precisely, the scheme, hostname and port match.

Another approach is to find the correct height before opening the iFrame. It is hard to detect the height of page to be inside of iFrame. However, since iFrame can have its own scroll bar, it may not be necessary to detect content’s height. The best approach might be to find available screen height of user after your title head. Following methods have been tested in Firefox and IE:


It appears Internet Explorer does not response to any of detections.

Following is the codes to apply this approach:

Codes in head:

‹script type="text/javascript"›
var url = "http://www.google.com/" // URL for your iFrame.
var titleHeight = 240;
var frameHeight = Math.max((screen.availHeight ? (screen.availHeight-titleHeight) : (window.innerHeight ? (window.innerHeight-titleHeight) : document.body.clientHeight)), 768);
window.document.onload = function {document.getElementById('linkIframe').style.height = frameHeight};

‹/script›

Codes in body:

‹script type="text/javascript"›
document.write('‹iframe id="linkIframe" width="100%" height="' + frameHeight + '" src="' + url + '" name="content"›‹/iframe›');
‹/script›

Clearing Obstacles for MS Excel Application Upgrading to 2007

,Recently an Excel application wrote in 2003 version needs to be converted into 2007 following the network infrastructure upgrade. It is noticed there are three parts needed to be attended.

In VBA micro of old application, value of attribute FileFormat for ActiveWorkbook.SaveAs was xlNormal. It is no longer allowed in Excel 2007. The FileFormat now needs to be explicitly expressed. Common values are:

51 = xlOpenXMLWorkbook (without macro's in 2007, xlsx)
52 = xlOpenXMLWorkbookMacroEnabled (with or without macro's in 2007, xlsm)
50 = xlExcel12 (Excel Binary Workbook in 2007 with or without macro's, xlsb)
56 = xlExcel8 (97-2003 format in Excel 2007, xls)

In this case, value of 52 is used. For more information, please refer to http://www.rondebruin.nl/saveas.htm.

File name is also an issue. This application automatically archives data everyday into a file, of which there is a space in file’s name. Now VBA in Excel 2007 converted the space to ‘%’ sign. Accordingly, the archiving file’s name needs to be changed, as well as the file type changed from .xls to .xlsm.

Originally archiving function involved large chunk of cells being copied from one worksheet to another. After conversion to Excel 2007, it is noticed the file’s size increase drastically without apparent reason. The educated guessing is somehow the application accumulated its clipboard during the automatic archiving process which involved copy-paste and save-as. However, nothing was found either in worksheets or clipboard. Web search shows no such error had been reported to Microsoft. After rewrote codes in this part to remove format as part of clipboard, the problem is resolved, although the reason is still not be found.

Labels