Jump to content

Archived

This topic is now archived and is closed to further replies.

redbullmarky

problem with javascript/ajax/populating list menus - Opera

Recommended Posts

Hi all
I'm having a bit of an issue with Opera. I have a function which populates a drop down menu (SELECT tag) with a list of countries. I also have a table of items, each of which has an 'edit' link and its own (initially hidden) form with a country dropdown/Save button. These forms are named/id'd as 'editform1', 'editform2', 'editform3', etc, etc. When you click on the edit link, the hidden form appears underneath the item and my function populates the dropdown list (the list could be very very long, and there are hundreds of countries, etc, so hence why I've chosen to populate the drop down as required, rather than all at the beginning). This is where the problem starts.
When you click on 'Save Changes', I'm using AJAX to update the info on the server and redraw the table of items, again with all the forms hidden. But on Opera, when I click on Edit again, the dropdown menu does not populate with the countries, but it works on FF/IE/Safari, etc on the Mac and PC.

This is my function which is called directly after clicking the edit link and displaying the FORM:

[code]
function listcountries(theelement, thedefault)
{
  var theel = document.forms['editform'+theelement].elements['country'];
  var cnt = 0;

  for (var country in countries)
  {
      if (countries[country] != '')
      {
        theel.options[cnt] = new Option(countries[country], country);
      }
      cnt++;
  }
}
[/code]

i did a bit of digging, by putting a few 'prompt' calls in certain places, to find out why this is not working, and the thing with Opera is the type of 'country' seems to change from HTMLSelectElement (when it works) to HTMLCollection (when it doesnt - ie, after an AJAX reload). This does not change on other browsers I've tested on.

Can anyone tell me why this happens, and how I can get it working on Opera?

Cheers
Mark

Share this post


Link to post
Share on other sites
Instead of looping through everytime you need to fill the menu, you don't you make a pre-filled select menu, and then clone it when you need. Should run a bit faster.

Share this post


Link to post
Share on other sites
what's the best way to clone an entire <select> with all its options? and do you know why opera has a problem with the current way?

cheers
Mark

Share this post


Link to post
Share on other sites
you just use cloneNode(true) and that should clone all the childern of the elements

Here is an example
[code]
<script language="javascript">
function add_sel(){
var new_sel = document.getElementById('sel_menu').cloneNode(true);

document.getElementById('holder').appendChild(new_sel);
}
</script>

<select id="sel_menu">
<option value="1">a</option>
<option value="2">b</option>
</select>

<div id="holder">

</div>

<button onClick="add_sel();">Clone</button>
[/code]

I am not sure why Opera change it though!!

Share this post


Link to post
Share on other sites
one more quick question - is it possible to actually clone just the dropdown's options and values instead of the whole thing? each of my dropdowns also has a load of 'onchange' properties which are unique. i tried cloning the whole thing and yes it was faster - but getting all the 'onchange's to act correctly was a different story.
cheers
Mark

Share this post


Link to post
Share on other sites
You can set your original select without any events, and attach the events to the new select menus. I am posting a sample to show how you can attach a simple function on onchange event (Also, changing the name and id of the select object) and a more advance attach for the onclick event to show how to get the object (using "this" refrence) and the event object as well.

[code]
<script language="javascript">
// checking if the browser is Opera
var is_Opera = (window.navigator.userAgent.search("Opera") != -1);
// checking if the browser is IE
var is_IE = ((window.navigator.userAgent.search("MSIE") != -1) && !is_Opera);

function add_sel(){
var new_sel = document.getElementById('sel_menu').cloneNode(true);

new_sel.name = "New_select";
new_sel.id = "new_select_id";

new_sel.onchange = function (){ alert('I am here'); }
new_sel.onclick = show_me;

document.getElementById('holder').appendChild(new_sel);
}

function show_me(evt){
if (is_IE) evt = event;

alert(this.tagName);
alert(evt);

alert(this.name + " " + this.id);
}
</script>

<select id="sel_menu">
<option value="1">a</option>
<option value="2">b</option>
</select>

<div id="holder">

</div>

<button onClick="add_sel();">Clone</button>
[/code]

if that doesn't work, you can always get the inner HTML of the holder div, replace the "<select" with "<select event event evetn" and then replacing the inner HTML of the holder div with the new HTML code.

Share this post


Link to post
Share on other sites

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.