I''ve been experiencing some irregularities with Prototype 1.4.0''s Insertion objects and <select> boxes. The same code yields different outcomes with different browsers. Here''s a test case: http://dev.laits.utexas.edu/medievalmap/testa.html There''s a full write-up in the test case - but basically, I''m inserting a new option (<option value="1">apple</option>). - In Firefox 2 (and presumably older versions), it works right. - In Opera 9, the </option> is omitted. - In IE 6, the <option value="1"> is omitted. I haven''t got a copy of IE 7 handy, nor do I have Safari, or I''d have tested those too. Is there some obvious way to fix this that I''ve missed? Any suggestions would be most welcome. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
On Thursday 18 January 2007 03:59, Selanit wrote:> I''ve been experiencing some irregularities with Prototype 1.4.0''s > Insertion objects and <select> boxes. The same code yields different > outcomes with different browsers. Here''s a test case: > > http://dev.laits.utexas.edu/medievalmap/testa.html > > There''s a full write-up in the test case - but basically, I''m inserting > a new option (<option value="1">apple</option>). > > - In Firefox 2 (and presumably older versions), it works right. > - In Opera 9, the </option> is omitted. > - In IE 6, the <option value="1"> is omitted. > > I haven''t got a copy of IE 7 handy, nor do I have Safari, or I''d have > tested those too.It doesn''t work on IE7, and does work on Safari (v.2.0.4) FWIW. No surprises there, then.> > Is there some obvious way to fix this that I''ve missed? Any > suggestions would be most welcome.Select elements in IE are a law unto themselves - they''re implemented as top-level GDI elements or something like that (my grasp of Windows graphics isn''t up to scratch), which can cause them to ''punch through'' DIVs that overlap them, etc. The Prototype Insertion objects are working with generic DOM elements and methods (e.g. insertBefore()) under the hood, which I suspect just don''t work for SELECT elements in IE. I think if you try to add options to a select using plain old innerHTML in IE, it messes up too (but adding an entire new SELECT element using innerHTML is OK). The easiest way to fix it is probably just to use the select elements options property, and the add() method to add a new option object, something like: var sel=$("TestSelect"); sel.add(new Option("apple",1)); This are DOM 1 standard stuff, supported in all browsers AFAIK. HTH Dave ---------------------- Author Ajax in Action http://manning.com/crane Ajax in Practice http://manning.com/crane2 Prototype & Scriptaculous Quickly http://manning.com/crane3 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks, I''ll give that a whirl and report back. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Dave Crane wrote: [...]> The easiest way to fix it is probably just to use the select elements options > property, and the add() method to add a new option object, something like: > > var sel=$("TestSelect"); > sel.add(new Option("apple",1)); > > This are DOM 1 standard stuff, supported in all browsers AFAIK.For the record, new Option is DOM 0 (i.e. not part of the official W3C DOM but implemented by every browser since about Navigator 2 and IE 3). In DOM 1, the add method puts the new option at the head of the list of options, in DOM 2 that was changed to the end of the list. I don''t know how many browsers implement the add method according to DOM 1, but to be sure: sel.options[sel.options.length] = new Option(...); seems to be the commonly accepted method for adding option elements. Also, IE has a few bugs in its implementation of the HTMLSelectElement interface - with the add method, IE expects the optional second argument to be a number (the index of the option to insert before) whereas the W3C DOM HTML specification requires an object (a reference to the option element to insert before). Therefore, if you want to add the option at a particular place in the option list, you can''t use the add method unless you include a bunch more code with try..catch to sort it out. So to put the option in a particular place, use the DOM Core insertBefore method. You can use DOM Core methods to add options in IE, just that you have to add the text property by appending a text node to the option element (which works fine in other browsers too) rather than assign to its text property. var newOption = document.createElement(''option''); newOption.value = ''...''; newOption.appendChild(document.createTextNode(''...'')); // Now add it to the select using whatever method suits Using new Option is somewhat more appealing. :-) -- Rob --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Hmm. I wrote a response, but it hasn''t appeared - RobG posted while I was writing it, and I suspect it didn''t get posted for that reason. Anyway, I basically talked about the same things RobG has said - that add() needs to args, the second being a reference to the option which the new option will be placed right before, and IE needs that argument as an integer rather than an object like everybody else. So a code snippet for inserting a new option into a select element at a specific position across browsers might look something like this: var sel = $("TheSelectBox"); var nextOpt = document.all? (code to create an integer for IE) : (code to get an Option object); sel.add(new Option("apple",1),nextOpt); And if you want it at the end of the list, nextOpt should be null. My problem''s solved, then. I can use this to insert new options while maintaining alphabetical order within the list. Thanks for the help, people. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
Selanit wrote:> Hmm. I wrote a response, but it hasn''t appeared - RobG posted while I > was writing it, and I suspect it didn''t get posted for that reason. > > Anyway, I basically talked about the same things RobG has said - that > add() needs to args, the second being a reference to the option which > the new option will be placed right before, and IE needs that argument > as an integer rather than an object like everybody else. So a code > snippet for inserting a new option into a select element at a specific > position across browsers might look something like this: > > var sel = $("TheSelectBox"); > var nextOpt = document.all? (code to create an integer for IE) : (code > to get an Option object); > sel.add(new Option("apple",1),nextOpt); > > And if you want it at the end of the list, nextOpt should be null.That is probably the worst solution, using document.all to detect IE has been deprecated for years and your solution will likely fail in Opera, which supports document.all but is probably compliant with the W3C''s add method, not IE''s.> > My problem''s solved, then. I can use this to insert new options while > maintaining alphabetical order within the list.If that is your intention, why not just add it then sort the options? Alternatively, if you have a fast method of finding the appropriate index, you can use something like: var idx = indexToInsertOptionAt; if (sel.options[idx]) { sel.insertBefore(newOption, sel.options[idx]); } else { sel.appendChild(newOption); } -- Rob --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---
RobG wrote:> That is probably the worst solution, using document.all to detect IE > has been deprecated for years ...True. Usually, I try to test for the specific functionality I need - eg retrieving the node that an event originated in by testing the typeof event.srcElement: (typeof(event.srcElement) == "object")? callerNode = event.srcElement : callerNode = event.target; But that approach only works with properties; as far as I know, there''s no good way to test what type of argument a browser is expecting for a method. I''d be happy to learn of one, though.> ... and your solution will likely fail in Opera, which supports document.all but > is probably compliant with the W3C''s add method, not IE''s.I did test it in Opera 9 before posting, and it works quite nicely. Opera appears to support both formats for the add method. I don''t test earlier versions of Opera, so I can''t say whether it works in those.> > My problem''s solved, then. I can use this to insert new options while > > maintaining alphabetical order within the list. > > If that is your intention, why not just add it then sort the options?I didn''t think of it. Also, now that I''ve tried it, it''s not as straightforward as it sounds. This code: var sel = $("TestSelect"); sel.options.sort(); ... will throw an error in every browser I''ve tried it in, ''cause the options property isn''t an array, it''s an HTMLOptionsCollection object. So it needs to be converted into an array first: var sel = $("TestSelect2"); var arr = $A(sel.options).sort(); So now we''ve got a sorted array. We can''t just assign the whole array back to options, so we need to truncate the options array and restore each one from the array. sel.options.length = 0; arr.each(function(value, index){ sel.options[index] = value; }); That does in fact rebuild the options in the select box. Unfortunately, it sorts them according to the option *values* rather than the option *labels*. In my case, the value is numerical, and the label is textual, and sort() organizes the list according to the numerical values. For example: <option value="3">Apple</option> <option value="2">Grape</option> <option value="1">Banana</option> <option value="11">Kiwi</option> Given this list, using sort() produces this list: <option value="1">Banana</option> <option value="11">Kiwi</option> <option value="2">Grape</option> <option value="3">Apple</option> The end result is not alphabetical order, and is actually more likely to confuse the user, since one non-alphabetical order has been replaced with a different non-alphabetical order with no visible rhyme or reason to it. In order to fix this, we would need to re-format the array generated by $A($("TestSelect").options) in order to make sort() operate on the labels instead of the values, and then reformat the sorted array AGAIN so that each given entry would be in the right order to get assigned back to the options object as an option element. I didn''t take my experiments far enough to do that, because frankly it sounds like a pain in the butt. The method I''ve been using thus far works like this: var ID = 6; // This is a SQL insert ID retrieved via an AJAX call. var Name = "Joe Schmoe"; // This is supplied in the form. var insert = ''<option value="''+ID+''" id="Account''+ID+''">''+Name+''<\/option>''; var found $A($("SelectUser").getElementsByTagName("option")).find(function(item) { return Name < item.innerHTML; }); if (found != null){ new Insertion.Before(found, insert); } else { new Insertion.Bottom($("SelectUser"), insert); } And, of course, the Insertion commands are the cause of this whole thread - they exhibit the problems I initially mentioned in IE and in Opera. I figure I can rewrite this to use add(). Using a numerical value for the second argument of add() throws a type mismatch error in Firefox, so I figure I can use Try.these() and just run it both ways rather than trying to figure out which the browser wants. But first I''m going to update to Prototype 1.5 and see if that fixes the Insertion errors. That would be even better. For that matter, I don''t even know why I''m worrying about IE and Opera. This particular page is destined to get used by exactly two people: me and my boss. I use Firefox, she uses Safari. Sometimes diligence is a curse. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Spinoffs" group. To post to this group, send email to rubyonrails-spinoffs-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-spinoffs-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-spinoffs?hl=en -~----------~----~----~----~------~----~------~--~---