I have a single window app where fresh page content is added to a container div via Ajax. When a new ajax page is loaded, I run $(<page div>).foundation() to initialise Foundation 6 plugins on the new content, which is the method described here:
http://foundation.zurb.com/sites/docs/javascript.html#adding-plugins-after-page-load
However, if I have an Abide form in a Reveal modal, the Abide form is not initialised. I discovered that the reason for this is that the Reveal plugin runs before the Abide plugin and moves the modal content to <body>. When the Abide plugin subsequently runs, it inspects only the <page div> content, as you'd expect, but it no longer finds the form in that content, as it's been moved to <body>.
How can we reproduce this bug?
$(<container div>).foundation()What did you expect to happen?
I expect the form to be validated by Abide.
What happened instead?
The form is submitted without Abide validation.
Hi @silentmiles, can you provide a CodePen example of what you did? You can use this template.
Hi @Owlbertz,
Here you are: http://codepen.io/silentmiles/pen/RGpgpB
Note however, that when I first created this, it worked as expected, and I wasn't seeing the same behaviour I'd described.
But, I'm using a locally hosted copy of Foundation downloaded from Foundation's download page: http://foundation.zurb.com/sites/download.html/. I downloaded the full set of plugins.
I put this version of Foundation on a CDN and and used it in the CodePen, and now the problem occurs as I described.
What I've discovered is that when Foundation is downloaded in this way, the Reveal plugin is loaded (and initialised) first, before Abide. With the copy of Foundation hosted on cdn.jsdelivr.net, the opposite is true. It's this ordering which appears to cause the problem.
Interesting finding... I played around a bit and forked your Pen: http://codepen.io/Owlbertz/pen/xEqpoN.
By using reflow() and initializing the plugins in a specified order you can make it either work or fail. I don't know the root cause as of now, but maybe using the "Example 1.1" can help you for now.
Hi @Owlbertz, yes it's the order of plugin execution which is the factor. If Reveal is run first, then it removes the form from .container, and moves it to the
tag. Then when Abide runs, it does not find any forms within .container.(BTW, the labels in your codePen are reversed -- the first exampel is Reveal first, then Abide, and the second is Abide then reveal.)
What's also curious is why the version of Foundation which is downloaded executes it's plugins in a different order to the version on the CDN. Shouldn't these have resulted form the same build process?
That seems to be the case. I am not sure where the version from the CDN comes from, maybe @kball can step in here.
All in all I would say that this is not an issue with Foundation, it is just the way it works. But maybe it's worth to be stated somewhere on the Reveal documentation page that this might cause some problems.
I would dispute that. If there's no standard way in which the Foundation plugins manipulate the dom, then one can't be be certain that their code will continue to work between versions. And, as the plugins cannot be executed in any order, there's a potential for a circular dependency forming.
What is causing the issues is not the execution order of the plugins in particular here. I think it is pretty clear that if a component removes elements form a certain container, initializing any plugin in said (now empty) container will fail.
I agree with you that having different results for different execution orders might cause some trouble, but as the framework is built in modules the developers will always be able to concat the files as they wish.
But on the other hand (iirc) there are not many plugins that alternate the DOM in the way Reveal does, so maybe stating a note on the docs page might be sufficient to avoid problems here?
Yes, a notice in the documentation is certainly a good idea, at least as long as this possibility exists, as currently, following the documented initialisation procedure with the code downloaded from Foundation will result in an error, in certain cases.
Perhaps a bug should be lodged against the maintainers of the build/download process? If it ordered the plugins as they're ordered in the CDN code, then I presume this wouldn't be an issue.
This is actually a very interesting, and I believe legitimate bug in the framework. I think the highlighted issue as a workaround is valid as that, but we should fix this.
Unfortunately I don't think is a super quick or trivial fix... my first guess at an approach would be that if a plugin is removing stuff from its initial place in the dom, it needs to report that back to the main foundation loop so that it can initialize the subcontent... but this is going to be a rework of the core loop, and so will need extensive testing. Probably we should target this for a non-point release, like 6.3, where we're going to do a bunch of testing already.
Those are my thoughts as well. For now, there are interim workarounds. Foundation.reflow() can be used, as @Owlbertz suggests, to run the plugin initialisers in an order which will not cause this problem (i.e., Abide first then Reveal). Or, as I've implemented, you can run .foundation() on any new Reveal elements that have been added (moved) to
, after running .foundation() on the new container content.Btw, if Foundation.reflow() is a legitimate method of initialisation, it should be added to the documentation. The current documentation at http://foundation.zurb.com/sites/docs/javascript.html seems to indicate that it's a deprecated method.
wicked