PDA

View Full Version : createChild problem on IE



tomlobato
25 Apr 2009, 7:15 AM
Hi all!

I`m testing extcore3 createChild. Trying to add options`s to a select.
On FF it works fine, but on IE6 or 7, it does not populate the select and
shows no error.

html:



<select id='mysel' name='mysel'>
<option value=-1>Select</option>
</select>
js:

Ext.onReady(function() {
Ext.fly('mysel').createChild({tag: 'option', value: 1, html: 'First Option'})
});
Any ideas?


Thank you!

tryanDLS
25 Apr 2009, 7:24 AM
IE does not support adding Options to a SELECT like that. You have do it the old-school way and add new Option(text, value) to the SELECT.

tomlobato
25 Apr 2009, 7:51 AM
Solved! thank you tryanDLS!




Ext.onReady(function() {
var myselect = document.getElementById("mysel")
try{
myselect.add(new Option("New Last Option", "4"), null)
} catch(e){ // IE does not like 'null' as last parameter
myselect.add(new Option("New Last Option", "4"))
}
});

Why Ext can`t handle this IE diff?

syscobra
25 Apr 2009, 10:52 AM
Solved! thank you tryanDLS!




Ext.onReady(function() {
var myselect = document.getElementById("mysel")
try{
myselect.add(new Option("New Last Option", "4"), null)
} catch(e){ // IE does not like 'null' as last parameter
myselect.add(new Option("New Last Option", "4"))
}
});

Why Ext can`t handle this IE diff?
I was watching the debug file of extcore and i found that insertHtml use this function:

frag = range.createContextualFragment(html);
With netbeans it says me that function is not available on all the browsers outthere so maybe thats why. But as we all now that IE sucks its not strange that it doesn't work well with all the options you can use flawless in other browsers.

Anyways.
Here is my aproach

Ext.onReady(function() {
// Create a new method (insertOption) to use in the Ext.Element
Ext.Element.addMethods(function(){
return {
insertOption: function(optionvalue,optionhtml){ // Function to insert an Option to a Select
if (Ext.isIE) { // if its Internet Explorer use this to add the option to the select
var mySelect = document.getElementById(this.dom.id);
mySelect.add(new Option(optionhtml, optionvalue));
} else { //else use the normal action
Ext.fly(this).createChild({tag: 'option', value: optionvalue, html: optionhtml});
}
}
}
}());
// end of method (insertOption)
Ext.fly('mysel').insertOption(1,'First Option'); // Using the newly added method from the Element
});

This aproach helps you if you use it a lot of times in any proyect.
The use is like in the code. You call the element(or CompositeElement) using Ext.get or Ext.fly then use the function insertOption and the parameters are the value and the html (text) of the option.

Tryed on IE7, Firefox and Chrome...The browsers i have installed on my machine

I am starting to learn a lot of the ext core stuff :-?

tryanDLS
25 Apr 2009, 2:37 PM
Ext doesn't handle the difference with IE, because there's no point in adding that little-used case to the generic createChild functionality. It would add code bloat for little benefit. This has been a known issue for the last 3 years (I was the first person to ever come across it here) and since then, it has come up probably less than 5 times.

tomlobato
25 Apr 2009, 2:53 PM
very good, it uses Ext.isIE instead try/catch and creates
a general addOption method.

Thank you!

tomlobato
25 Apr 2009, 2:58 PM
Ext doesn't handle the difference with IE, because there's no point in adding that little-used case to the generic createChild functionality. It would add code bloat for little benefit. This has been a known issue for the last 3 years (I was the first person to ever come across it here) and since then, it has come up probably less than 5 times.

ok, understood.

mystix
30 Apr 2009, 10:30 PM
sorry, saw some incorrect code and i just had to nitpick ;)

@syscobra, you're adding an unnecessary self-invoking function wrapper to your code.
the correct code should be:


// Create a new method (insertOption) to use in the Ext.Element
Ext.Element.addMethods({
insertOption: function(optionvalue,optionhtml){ // Function to insert an Option to a Select
if (Ext.isIE) { // if its Internet Explorer use this to add the option to the select
var mySelect = document.getElementById(this.dom.id);
mySelect.add(new Option(optionhtml, optionvalue));
} else { //else use the normal action
Ext.fly(this).createChild({tag: 'option', value: optionvalue, html: optionhtml});
}
}
});

Condor
30 Apr 2009, 10:38 PM
Shouldn't that be:

Ext.Element.addMethods({
insertOption: function(optionvalue, optionhtml){
if(Ext.isIE){
this.dom.add(new Option(optionhtml, optionvalue));
} else {
this.createChild({tag: 'option', value: optionvalue, html: optionhtml});
}
}
});
ps. Does this really need an Ext.isIE check? Isn't this.dom.add(new Option(optionhtml, optionvalue)); always supported?

mystix
30 Apr 2009, 11:00 PM
Shouldn't that be:

Ext.Element.addMethods({
insertOption: function(optionvalue, optionhtml){
if(Ext.isIE){
this.dom.add(new Option(optionhtml, optionvalue));
} else {
this.createChild({tag: 'option', value: optionvalue, html: optionhtml});
}
}
});
ps. Does this really need an Ext.isIE check? Isn't this.dom.add(new Option(optionhtml, optionvalue)); always supported?
i should think it is always supported.

tomlobato
1 May 2009, 8:35 AM
I`m testing Ext3 RC1 here...
this.dom.add(new Option(optionhtml, optionvalue)); works only on IE
and
this.createChild({tag: 'option', value: optionvalue, html: optionhtml}); works only on FF

When trying this.dom.add... on FF, firebug shows the error:
uncaught exception: [Exception... "Not enough arguments [nsIDOMHTMLSelectElement.add]" nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)" location: "JS frame :: http://localhost/exttest/addOption.html :: anonymous :: line 12" data: no]

So I need, for while, to check using Ext.isIE. Some idea about why this.dom.add is not working for both?


addOption.html:

<html>
<head>
<script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext/ext-all-debug.js"></script>
<script type="text/javascript" src="addOption.js"></script>
</head>
<body>
<select id=testsel name=testsel>
<option value='-1'>Selecione</option>
</select>
</body>
</html>addOption.js:


Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';

Ext.onReady(function(){

Ext.Element.addMethods({
insertOption: function(optionvalue, optionhtml){
if(Ext.isIE){
this.dom.add(new Option(optionhtml, optionvalue));
} else {
this.createChild({tag: 'option', value: optionvalue, html: optionhtml});
}
}
});

Ext.fly('testsel').insertOption( 1, 'First Option')

})

syscobra
1 May 2009, 8:39 AM
Thanks Mystic.
that was my first addmethod i do so i just get it copying another i saw on the original code. now i understand that. Thanks.

I used the other normal this.createChild because i don't know if that "new Option()" of internet explorer works in every browser outthere. So if the createChild works on every browser but IE i made that so he don't have future (maybe) problems.

syscobra
1 May 2009, 8:42 AM
@ tomlobato:
Hey thanks for testing it. i knew i had to use the old createChild because the "new Option()" structure of IE "maybe" (now confirmed) doesn't work in other browsers.

tryanDLS
1 May 2009, 10:06 AM
It should work cross-browser if you do it the right way

this.dom.options.add(new Option('foo', 'bar'))

syscobra
1 May 2009, 10:20 AM
So this is the way to do that?

Ext.Element.addMethods({
insertOption: function(optionvalue, optionhtml){
this.dom.options.add(new Option(optionhtml, optionvalue));
});
Ext.fly('testsel').insertOption( 1, 'First Option');

syscobra
1 May 2009, 10:57 AM
Just tested in IE, Chrome and FF and added the possibility to insert from an array.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="ext-core.js"></script>
<script>
Ext.onReady(function() {
Ext.Element.addMethods({// Create a new method (insertOption) to use in the Ext.Element
insertOption: function(optionvalue,optionhtml){ // Function to insert an Option to a Select
if (Ext.isArray(optionvalue)) { // If its an array insert each member
for(i=0;i<optionvalue.length;i++) this.insertOption(optionvalue[i][0],optionvalue[i][1]);
} else {
this.dom.options.add(new Option(optionhtml, optionvalue));
}
}// end of method (insertOption)
});// end of addMethods
Ext.fly('mysel').insertOption(1,'First Option'); // Using the newly added method from the Element
options = Array(Array(1,'First Option'),Array(2,'Second Option'),Array(3,'Third Option'));
Ext.fly('myarraysel').insertOption(options); // Using the newly added method from the Element with array
});
</script>
</head>
<body>
<select id='mysel' name='mysel'>
<option value=-1>Select</option>
</select>
<select id='myarraysel' name='myarraysel'>
<option value=-1>Select (from array)</option>
</select>
</body>
</html>

mystix
1 May 2009, 7:58 PM
does that handle optgroups as per @joustin's complaint?
http://extjs.com/forum/showthread.php?p=324080#post324080

syscobra
2 May 2009, 1:38 PM
does that handle optgroups as per @joustin's complaint?
http://extjs.com/forum/showthread.php?p=324080#post324080
Well i don't think so. I was thinking when you add options to a combo in html, maybe you use it to add from an array from a db...

tomlobato
2 May 2009, 4:38 PM
great, very nice result!!



Ext.Element.addMethods({
insertOption: function(optionvalue, optionhtml){
if (Ext.isArray(optionvalue)) { // If its an array insert each member
for(i=0;i<optionvalue.length;i++) this.insertOption(optionvalue[i][0],optionvalue[i][1]);
} else {
this.dom.options.add(new Option(optionhtml, optionvalue));
}
}
});