-
Notifications
You must be signed in to change notification settings - Fork 27.4k
Custom <select> directive: Transclude and replace <option>s not working in IE9 #6926
Comments
Hi, We already fixed this problem for table elements like A workaround would be to define your directive as an attribute on a |
Given the commit linked above, this should be easy to implement. Would you like to try to create a PR for this? |
Definitely! I'll see what I can do. Also, thanks for the workaround, I am doing something similar for the moment. Thanks again |
the compiler will wrap it with a <select> tag. This satisfies IE9. Closes angular#6926
the compiler will wrap it with a <select> tag. This satisfies IE9. Closes angular#6926
So the pull request I just made only partially fixes the root problem. @tbosch, I think you slightly misunderstood me -- I'm talking about transcluding these troubled elements, not putting them in a template. (This pull request is still useful though, as it fixes a directive with a template of From my research, the larger issue might be something that would need to be changed in JQLite. I see that JQLite adds content using Unfortunately, IE9 and before has a major bug with completely ignoring elements such as For example: angular.element('<option>Hello!</option><option>There!</option>'); This ONLY breaks if JQLite is not replaced by jQuery. jQuery has somehow gotten around this issue to get it working in IE9. However, since angular still uses JQLite internally, the problem persists when adding jQuery into the picture. The reason the pull request above fixes this for templates is that the elements are surrounded by their specific parent element to be happy. For example, the following works great: angular.element('<select><option>Hello!</option><option>There!</option></select>'); Overall, I'm not terribly worried, and I do not think this problem is worth everyone's time given the workarounds that exist. I do think it should be documented somewhere (if not here). |
Here's the thing: HTML5 has some super silly rules about "allowed content" for particular nodes. What this means is, there's very little we can actually do about this. One thing that you CAN do, if you want to transclude table content into a directive which uses a select tag for its template, is to make the directive an attribute directive. This way, the browser's HTML parser won't care that you are putting <option> tags as children of the <select> tag, and you'll be able to transclude them just fine. This is a problem with the HTML parser, and sadly, there is very little we can do to circumvent that with custom elements. Theoretically, WebComponents might address this (and may have already addressed this for the <content> tags), but for Angular 1.x, there ain't much we can do. Take it up with hixie maybe? :p |
I'm not sure if we actually need this fix for <option> tags though, does jqLite('<option>') produce an empty collection? |
@caitp I totally agree with you. It's kinda unfortunate that the spec is that strict, and even worse that the browser is so strict while the HTML is being manipulated (before it's actually inserted into the DOM). Also: Yes, it looks like it does on IE9. |
the compiler will wrap it with a <select> tag. This satisfies IE9. Closes angular#6926
Hmm, I see why jqLite('<option>') fails in angular 1.x but not jQuery 2.x Our constructor for elements is extremely simple. I think we could improve this without adding too much code. The question is whether or not it's worth it. I need something to do today though, so I'll hack on improving the jqLite HTML parser for a few minutes, we can look at it. |
Previously, the jqLite constructor was limited and would be unable to circumvent many of the HTML5 spec's "allowed content" policies for various nodes. This led to complicated and gross hacks around this in the HTML compiler. This change refactors these hacks by simplifying them, and placing them in jqLite rather than in $compile, in order to better support these things, and simplify code. While the new jqLite constructor is still not even close to as robust as jQuery, it should be more than suitable enough for the needs of the framework, while adding minimal code. Closes angular#6941 Closes angular#6926
Previously, the jqLite constructor was limited and would be unable to circumvent many of the HTML5 spec's "allowed content" policies for various nodes. This led to complicated and gross hacks around this in the HTML compiler. This change refactors these hacks by simplifying them, and placing them in jqLite rather than in $compile, in order to better support these things, and simplify code. While the new jqLite constructor is still not even close to as robust as jQuery, it should be more than suitable enough for the needs of the framework, while adding minimal code. Closes angular#6941 Closes angular#6926
Previously, the jqLite constructor was limited and would be unable to circumvent many of the HTML5 spec's "allowed content" policies for various nodes. This led to complicated and gross hacks around this in the HTML compiler. This change refactors these hacks by simplifying them, and placing them in jqLite rather than in $compile, in order to better support these things, and simplify code. While the new jqLite constructor is still not even close to as robust as jQuery, it should be more than suitable enough for the needs of the framework, while adding minimal code. Closes angular#6941 Closes angular#6926
Previously, the jqLite constructor was limited and would be unable to circumvent many of the HTML5 spec's "allowed content" policies for various nodes. This led to complicated and gross hacks around this in the HTML compiler. This change refactors these hacks by simplifying them, and placing them in jqLite rather than in $compile, in order to better support these things, and simplify code. While the new jqLite constructor is still not even close to as robust as jQuery, it should be more than suitable enough for the needs of the framework, while adding minimal code. Closes angular#6941 Closes angular#6926
Previously, the jqLite constructor was limited and would be unable to circumvent many of the HTML5 spec's "allowed content" policies for various nodes. This led to complicated and gross hacks around this in the HTML compiler. This change refactors these hacks by simplifying them, and placing them in jqLite rather than in $compile, in order to better support these things, and simplify code. While the new jqLite constructor is still not even close to as robust as jQuery, it should be more than suitable enough for the needs of the framework, while adding minimal code. Closes angular#6941 Closes angular#6926
Previously, the jqLite constructor was limited and would be unable to circumvent many of the HTML5 spec's "allowed content" policies for various nodes. This led to complicated and gross hacks around this in the HTML compiler. This change refactors these hacks by simplifying them, and placing them in jqLite rather than in $compile, in order to better support these things, and simplify code. While the new jqLite constructor is still not even close to as robust as jQuery, it should be more than suitable enough for the needs of the framework, while adding minimal code. Closes angular#6941 Closes angular#6926
Previously, the jqLite constructor was limited and would be unable to circumvent many of the HTML5 spec's "allowed content" policies for various nodes. This led to complicated and gross hacks around this in the HTML compiler. This change refactors these hacks by simplifying them, and placing them in jqLite rather than in $compile, in order to better support these things, and simplify code. While the new jqLite constructor is still not even close to as robust as jQuery, it should be more than suitable enough for the needs of the framework, while adding minimal code. Closes angular#6941 Closes angular#6926
I'm not convinced we'll fix it given age of the ticket. But for anyone interested, JSFiddle no longer works in IE 9 so I ported the test case to JS Bin & updated AngularJS to 1.6.9; it's still broken in IE 9 & works in IE 10+: http://output.jsbin.com/qofuhag. |
Please check out the following JSfiddle (since Plunker doesn't work in IE9):
http://jsfiddle.net/Rpe36/
Basically, I have
myDirective
that is an element. I transclude and replace with the following template:It doesn't work. :(
If I use the ngOptions attribute and nothing transcluded, it works fine! Go figure.
I don't know if this is a larger problem with IE9, or something that could be fixed in Angular.
Thanks!
Alex
The text was updated successfully, but these errors were encountered: