If you form_alter a textarea on to a node form with a weight that puts it before the body of the form, the teaser splitter breaks badly.
This was reported in http://drupal.org/node/192913, but the CCK code is still broken and not a good test of the problem, so I tested it by just form_altering a simple textarea (with no filter form) onto a node form with a weight less than zero.
When you try to use the splitter, it fails to produce the separate teaser box. When you try to re-join the information, the body completely disappears.
If the additional textarea has a weight that puts it below the body, things work correctly.
Comment | File | Size | Author |
---|---|---|---|
#8 | teaser-textarea.patch | 944 bytes | catch |
#5 | teaser-textarea.patch | 945 bytes | kkaefer |
Comments
Comment #1
KarenS CreditAttribution: KarenS commentedRenaming to point out that not fixing this will impair CCK's ability to add textareas to a form. But it is equally true that any other module that wants to add a textarea to a node form will run into this, so it's not just a CCK issue.
Comment #2
cburschkaI wanted to begin with the real basics to get closer to identifying the problem, so I diffed a page with and without the additional textarea. Just to see if adding the field in the Forms API changed anything in obscure parts of the HTML code.
This may be obvious, but I just wanted to confirm that, barring build IDs etc, this is the only part of the HTML code that changes:
Is it possible that jQuery uses a numerical index to access either of the fields, which gets messed up by the addition of a field before that? I find this hard to believe, but hey.
For additional reference, here are the two functions that split and join the teaser field:
Unless this bug is hiding in another obscure location, the two code blocks above should be enough to identify the problem - unfortunately I'm clueless about JS and jQuery, so I can't be of much help.
Comment #3
jp.stacey CreditAttribution: jp.stacey commentedI think this is a lot more complex than the above suggests, because (a) there are things happening in between HTML page load and teaser.js being called and (b) all the .js files monkey with the HTML DOM, so looking at the source doesn't specifically help.
With an extra textarea weighted above the body, I can remove the
.parent()
from$(teaser).parent().slideUp('fast')
and$(teaser).parent().slideDown('fast')
, and it sort of fixes the bug (still no teaser grippie - the drag bar that makes it bigger). However, it breaks the standard behaviour without the extra textarea.teaser.js is a bit comment-free (and it e.g. gets the ID of edit-teaser-include via two different routes: first from
Drupal.settings.teaserCheckbox
, and later fromthis.id.substring(...) + 'include'
). Here's a more annotated version:Depending on the weighting of the extra textarea, the teaser sometimes magically acquires a grippie before teaser.js gets to it, and I think it ends up in a container element too (so teaser[0].parentNode returns a different node). I'm not sure how the Drupal.behaviors work, but my guess is that there's some sort of crawl through the form's DOM, in document order. That means that the presence of the textarea above the body/teaser fields invokes some behaviour that adds a grippie to everything resizable, before teaser.js is able to come in and rearrange things.
When it works, that's when teaser.js gets invoked before this other behaviour. That means that the teaser gets moved, then gets a grippie and a container element, and hence those
.parent()
calls are required to get out of that container element.I haven't much more to add right now unless I can find what's adding the grippies and maybe prevent it from acting on the teaser textarea. I hope this all provides some rather incoherent clues, though.
Comment #4
kkaefer CreditAttribution: kkaefer commentedFor reference, here is a module that adds a textarea:
Comment #5
kkaefer CreditAttribution: kkaefer commentedI found the bug: when adding a textarea before the actual body textarea, the file
textarea.js
gets added beforeteaser.js
. This doesn’t happen when the node body textarea is the first one, becasue intheme_textarea
,teaser.js
is added at first.teaser.js
only works correctly when it is the first file performing changes to the markup.This patch solves this problem by adding a call to the teaser function in the textarea when the currently treated textarea is a teaser textarea.
Comment #6
RobLoachHuge bug, huge patch. Well done, kkaefer. Patch applies cleanly, fixes the problem.
Comment #7
keith.smith CreditAttribution: keith.smith commentedOne minor nitpick:
it's should be its
(There's another patch somewhere in the queue that fixes about twenty similar ones all across core.)
Comment #8
catchit's >> its
don't credit me if this is committed.
Comment #9
Gábor HojtsyUm, hum. This is not exceptionally nice, but as we have no dependency system for behaviors, I cannot think of an elegant solution either. Committed this.
Comment #10
KarenS CreditAttribution: KarenS commentedGreat detective work everyone, especially kkaefer. Thanks!
Comment #11
(not verified) CreditAttribution: commentedAutomatically closed -- issue fixed for two weeks with no activity.