Friday, February 6, 2009
Clone node issue in IE
I am writing after a long time.
If you are wondering why so long?
didnt I had anything worthwhile to type?
Yes, I didnt had anything to write, coz whatever I learnt in last few months its well documented all over internet.
Not to forget an important fact that during my free time last year i Played a lot with my Canon SLR-Like Camera.
You can check my photography @ Sinless Photography
But this Time again our big time sucker IE(Internet Explorer) showed his ugly face and delayed our work and entangled us in DOM herarchies.
IE Sucks it AGAIN.
cloneNode doesnt work for all elements in IE.
yes
cloneNode doesnt work for all elements in IE.
My Problem.
I wanted to upload an image form without submitting the original form (in page1).
What I wanted to do:
1. Created a hidden form outside original form.
2. Copy / Clone input (type = file) element from original form to hidden Form.
3. Submit hidden form via JavaScript and view output in a frame (in page1).
What I did:
1. var clonedFileObject = document.forms['originalForm'].fileElement.cloneNode(true);
( where fileElement is input type = file element)
2. document.hiddenForm.appendChild(clonedFileObject);
3. hiddenForm.submit();
And What Happened.
var clonedFileObject = document.forms['originalForm'].fileElement.cloneNode(true);
Above statement worked perfectly fine in Firefox but in IE nothing happened.
No cloning was done and on form submission / image upload button All I could see was empty $_FILES array with error code = 4.
What all I tried:
1. hiddenForm.fileElement.value = originalForm.fileElement.value // didnt in FF either
2. Created a outer div and copied innerHTML of first div to hiddenforms div // didnt worked for input type file (didnt wasted much time either...should have worked)
3. Finally I did a shabby Patch work in my code which i really hated but in the given time limit and set conditions this was only I could think of.
var OriginalFileObj = document.getElementById('fileElement');
//this will remove fileElement from Original Form
var clonedFileObj = OriginalFileObj;
document.hiddenForm.appendChild(OriginalFileObj);
document.hiddenForm.submit();
divObj.appendChild(OriginalFileObj); //restoring of original file object in original form
//if you dont do this there wont be any file object in original form
I am sure there would be other better ways to do the same.
If you are aware of it please add in comments so as others can benefit from you including me.
Friday, March 21, 2008
Problems with JS for...in Loop
Similar thing happen to me recently.
My webpage was full of JS errors on one fine morning.
I just could understand why..... but again google came to my rescue.
I found this article.... about dangers of using for...in loop
The Problem
Try the following code on an empty page, one without any JavaScript libraries added:
var associative_array = new Array();
associative_array["one"] = "Lorem";
associative_array["two"] = "Ipsum";
associative_array["three"] = "dolor";
for (i in associative_array) { alert(i) }; You’ll get three sequential alert boxes: “one”; “two”; “three.” This code has a predictable output and looks logically sound: you’re declaring a new array, giving it three string keys, then iterating over them.
Now do this: replace “Array” with “RegExp” and run the code again. As if by magic, this also works! It’s not the only one. Try Boolean, or Date, or String, and you’ll find they all work as well. It works because all you’re doing is setting properties on an object (in JS, foo["bar"] is the same as foo.bar), and a for..in loop simply iterates over an object’s properties. All data types in JS are objects (or have object representations), so all of them can have arbitrary properties set.
In JavaScript, one really ought to use Object for a set of key/value pairs. But because Array works as demonstrated above, JavaScript arrays (which are meant to be numeric) are often used to hold key/value pairs. This is bad practice. Object should be used instead.
I’m not trying to ridicule or scold. This misconception is too common to attribute it to stupidity, and there are many legitimate reasons for the confusion. But this is something that needs to be cleared up if JavaScript is ever to be used on a grand scale.
If you need further evidence that Array is not meant to be used this way, consider:
- There is no way to specify string keys in an array constructor.
- There is no way to specify string keys in an array literal.
- Array.length does not count them as items. In the above example,
associative_array.lengthwill return0. - The page on Arrays in the Mozilla JavaScript reference makes no mention of this usage. (Nor does the ECMAScript specification, by the way, but you’ll have to do your own legwork to verify that, because I’m not linking to page 88 of a kajillion-page PDF.)
The History
This confusion has several other contributing factors:
- In PHP, a language that many JavaScript users are also familiar with, numeric arrays and associative arrays are treated more or less identically. And since a set of key/value pairs goes by about eleven different names, depending on the language, this usage is quite often a result of unclear definitions of terms.
- JavaScript is interpreted, not compiled, and many people have learned it by example. Thus a third-party script that uses
Arrayimproperly might rub off on its users. - JavaScript started with no specification, then received a poor specification, and I know few people who spend their free time reading specifications. Especially bad ones.
- Because there is no formal construct for key/value pairs, JavaScript cannot distinguish between creating a hash and setting properties on an object. As we’ve demonstrated, any object can have arbitrary properties, and a
for..inloop simply iterates over each of these properties, so the code above is not explicitly incorrect. - The harmful side effects of using
Arrayfor key/value pairs are not experienced unlessArray.prototypeis extended. Since this is an underutilized feature of JavaScript, it hasn’t been done on a large scale until rather recently.
Why Prototype “breaks” this usage
Concurrent with Prototype’s rise in popularity have been various blog posts complaining that the JavaScript framework “breaks” associative arrays — i.e. Arrays with string keys. It “breaks” them because it adds a handful of useful methods for working with arrays to Array.prototype, and these methods are also iterated over in a for..in loop. This means that when Prototype is included on a page the code above will loop 35 times instead of the original three.
Prototype also extends String with some methods for dealing with strings. If you try to use String as an associative array, your code will loop 20 times instead of three.
I am aware of the mitigating factors — hell, I just enumerated them — but complaining that Prototype “breaks” your ability to use Array as a hash is like complaining that Prototype “breaks” your ability to use String as a hash. It is not Prototype’s fault that JavaScript does not deter this improper use, and it certainly does not mean that Prototype does not “play well with others.” You are free to reject Prototype and keep using Array improperly, but then you give up your right to bitch and moan.
Actually, we’ve been here before: before version 1.4, Prototype added a couple methods onto Object.prototype, meaning that Object couldn’t even be used in the manner I describe, and a bunch of people rightly took Sam Stephenson to task for it. Object.prototype is verboten. Since version 1.4, however, this is no longer an issue, and therefore there is no longer an excuse.
So I will say it again: Array is not meant to be used for key/value pairs. Luckily, there is a dead-simple way to fix this. In the above example, you need only change Array to Object. (Or, if you’re using literal syntax, change [] to {}.) There. Your wrong code is no longer wrong, and it took only a little more work than a simple find-and-replace.
There are plenty of JavaScript frameworks to choose from, and many of them are excellent. I use Prototype because it works for me, and I do not take it personally when other people decide they don’t like it. But I believe Prototype deserves to be hated on its merits, dammit, not because it makes wrong code stop working — especially when the wrong code can be made right in ten seconds.
Saturday, June 2, 2007
IE DOM Issue
While doing so my code worked perfectly fine in FireFox, but in IE the new elements created did not behaved in desired manner.
After a bit research I found that setAttribute() function doesnt work always in IE (actually it is suppose to not work at all ;)..).
Substitue for using setAttribute() is to use innerHTML
eg.TR1.innerHTML = "
In my case innerHTML didnt worked as i had too many parameters to pass wherein I was out of combinations for using single and double quotes.
Below were the different ways I tried.
Not one of the following examples worked in IE:
TD1.setAttribute('onclick', 'doThis(' + param + ');');
TD1.onclick = 'doThis(' + param + ');';
TD1.onclick = new Function('doThis(' + param + ');');
TD1.onclick = function() { doThis(param); };
TD1['onclick'] = 'doThis(' + param + ');';
TD1['onclick'] = new Function('doThis(' + param + ');');
TD1['onclick'] = function() { doThis(param); };
The hack for making onClick work for you in IE via DOM
TD1.onclick = function() {
var temp = new Function("dostuff('"+myvar+"')");
temp();
}
The above code works well with both IE and Mozilla.
The same technique is to be used for calling any function for any HTML Events(onMouseOver).
NOTE: The above code can be simplified only when the function you are calling (dostuff) does not have any parameters to pass.
E.g.
TD1.onclick = function() { dostuff(); }
Some more interesting hacks for making your DOM work in IE are
blah.setAttribute('class','myCSS');
blah.className = 'myCSS'; <-- This line needs to be added
blah.setAttribute('valign', 'top'); This wont work as IE is case-sensitive
blah.setAttribute('vAlign', 'top');
Reference: Why IE Sucks
Wednesday, May 30, 2007
JavaScript Conditional Compilation.
| Variable | Description |
|---|---|
| @_win32 | Returns true if running on a Win32 system, otherwise NaN. |
| @_win16 | Returns true if running on a Win16 system, otherwise NaN. |
| @_mac | Returns true if running on an Apple Macintosh system, otherwise NaN. |
| @_alpha | Returns true if running on a DEC Alpha processor, otherwise NaN. |
| @_x86 | Returns true if running on an Intel Processor, otherwise NaN. |
| @_mc680x0 | Returns true if running on a Motorola 680x0 processor, otherwise NaN. |
| @_PowerPC | Returns true if running on a Motorola PowerPC processor, otherwise NaN. |
| @_jscript | Always returns true. |
| @_jscript_build | The build number of the JScript scripting engine. |
| @_jscript_version | A number representing the JScript version number in major.minor format. IE4 supports JScript 3.x The version number reported for JScript .NET is 7.x. |
| @_debug | Returns true if compiled in debug mode, otherwise false. |
| @_fast | Returns true if compiled in fast mode, otherwise false. |
In most cases, you probably will be limited to just using @_win and @jscript_build:
/*@cc_on
@if (@_win32)
document.write("OS is 32-bit. Browser is IE.");
@else
document.write("OS is NOT 32-bit. Browser is IE.");
@end
@*/User defined Variables
You can also define your own variables to use within the conditional compilation block, with the syntax being:
@set @varname = termNumeric and Boolean variables are supported for conditional compilation, though strings are not. For example:
@set @myvar1 = 35
@set @myvar3 = @_jscript_versionThe standard set of operators are supported in conditional compilation logic:
- ! ~
- * / %
- + -
- << >> >>>
- < <= > >=
- == != === !==
- & ^ |
- &amp;& |
You can test if a user defined variable has been defined by testing for NaN:
@if (@newVar != @newVar)
//this variable isn't defined.This works since NaN is the only value not equal to itself.
References:
Friday, May 25, 2007
JavaScript No click links
While Googling for Eazy no click links, I found a Javascript code which enables us to navigate without clicking.
The example is given here
http://labs.mininova.org/noclick/
Other than no Clicks, there quite good number of other examples also like
- mulitselect without control button use,
- Visual Passwords,
- Instant Form Validation,
- etc. ;)
Wednesday, May 23, 2007
Navigation Without Mouse Clicks
Still thinking what I mean.
Let me make it straight then.
lets Say there exist a "Link". Now inorder to view this page, people would normally click it.
Navigating without mouse clicks is that -all we need to do is just do mouseover on it and the link will be clicked and we will be taken to the desired page.
This is very much possible and many research projects are made online based on No-Click Idea.
If this idea is accepted by Internet Users then there would be no sound of mouse clicking while surfing internet,it would be a Quite expedition and number of people complaining of finger pains due to mouse clicks will also gradually decrease ;).
One such research project is here .
Its www.dontclick.it
I would strongly recommed you all to visit it so as to get that weird-nice experience while navigating this site.
I thoroughly enjoyed my experience and even played few games there.
Thursday, April 19, 2007
JS 3d arrays
eg:
abc['test1'] = new Array();
abc['test1'][test2'] = new Array();
abc['test1'][test2']['test3'] = new Array();
foreach() substitute in JavaScript JS
The for...in statement is used to loop (iterate) through the elements of an array or through the properties of an object.
The code in the body of the for ... in loop is executed once for each element/property.
Syntax
for (variable in object)
{
code to be executed
}
The variable argument can be a named variable, an array element, or a property of an object.
Example
Using for...in to loop through an array:
var x
var mycars = new Array()
mycars[0] = "Saab"
mycars[1] = "Volvo"
mycars[2] = "BMW"
for (x in mycars)
{
document.write(mycars[x] + "
")
}
appendchild issue in IE
The below code worked fine with Mozilla, however nothing happened in IE also no errors were shown
var theTable = document.getElementById(tableId);
var rowIdAttribute = i+1;
var newRow = document.createElement('tr');
newRow.setAttribute("id", rowIdAttribute); theTable.appendChild(newRow );
I found that IE does not support appendChild to add new rows in the table
So I added a container element to place the new row and append that container element.
Correct code is as shown below which works fine both in IE and Mozilla
var theTable = document.getElementById(tableId);
var newtbody = document.createElement('TBODY');
var rowIdAttribute = i+1;
var newRow = document.createElement('tr');
newRow.setAttribute("id", rowIdAttribute);
newtbody.appendChild(newRow);
theTable.appendChild(newtbody);