The foundation of Durandal and Zurb, where should I initialize the foundation?

I use the basic Durandal HTML template, but I replaced Bootstrap with Zurb Foundation. Everything works well, except for the problem when I cannot open any modalities, drop-down lists or anything that requires foundation initialization. Typically, you can do the following in the body of your web page:

<script> $(document).foundation(); </script> 

I tried putting this in Index.html , Shell.html and even randomly in viewmodel and view. In addition, I tried to run it from JS in main.js, and the viewmodel itself in the activation section. None of this worked. (Hopefully a very temporary) workaround I found is to actually create a Foundation by creating my javascript by clicking a button to open the modal:

 $(document).foundation(); $("#myModal").foundation("reveal", "open"); 

Where am I going wrong?

My main.js for reference:

 (function() { requirejs.config({ paths: { text: "../lib/require/text", durandal: "../lib/durandal/js", plugins: "../lib/durandal/js/plugins", transitions: "../lib/durandal/js/transitions", knockout: "../lib/knockout/knockout-2.3.0", jquery: "../lib/jquery/jquery-1.9.1", foundation: "../lib/foundation/js/foundation/foundation", "foundation.abide": "../lib/foundation/js/foundation/foundation.abide", "foundation.accordion": "../lib/foundation/js/foundation/foundation.accordion", "foundation.alert": "../lib/foundation/js/foundation/foundation.alert", "foundation.clearing": "../lib/foundation/js/foundation/foundation.clearing", "foundation.dropdown": "../lib/foundation/js/foundation/foundation.dropdown", "foundation.interchange": "../lib/foundation/js/foundation/foundation.interchange", "foundation.joyride": "../lib/foundation/js/foundation/foundation.joyride", "foundation.magellan": "../lib/foundation/js/foundation/foundation.magellan", "foundation.offcanvas": "../lib/foundation/js/foundation/foundation.offcanvas", "foundation.orbit": "../lib/foundation/js/foundation/foundation.orbit", "foundation.reveal": "../lib/foundation/js/foundation/foundation.reveal", "foundation.tab": "../lib/foundation/js/foundation/foundation.tab", "foundation.tooltip": "../lib/foundation/js/foundation/foundation.tooltip", "foundation.topbar": "../lib/foundation/js/foundation/foundation.topbar" }, shim: { jquery: { exports: "jQuery" }, foundation: { deps: ["jquery"] }, "foundation.abide": { deps: ["foundation"] }, "foundation.accordion": { deps: ["foundation"] }, "foundation.alert": { deps: ["foundation"] }, "foundation.clearing": { deps: ["foundation"] }, "foundation.dropdown": { deps: ["foundation"] }, "foundation.interchange": { deps: ["foundation"] }, "foundation.joyride": { deps: ["foundation"] }, "foundation.magellan": { deps: ["foundation"] }, "foundation.offcanvas": { deps: ["foundation"] }, "foundation.orbit": { deps: ["foundation"] }, "foundation.reveal": { deps: ["foundation"] }, "foundation.tab": { deps: ["foundation"] }, "foundation.tooltip": { deps: ["foundation"] }, "foundation.topbar": { deps: ["foundation"] } } }); define(["durandal/system", "durandal/app", "durandal/viewLocator", "foundation"], function(system, app, viewLocator, foundation) { system.debug(true); app.title = "Durandal Starter Kit"; app.configurePlugins({ router: true, dialog: true, widget: true }); app.start().then(function() { viewLocator.useConvention(); app.setRoot("viewmodels/shell", "entrance"); }); }); }).call(this); 

Shell.html :

 <div> <nav class="top-bar hide-for-small"> <ul class="title-area"> <!-- Title Area --> <li class="name"> <h4 style="color: white">KRS Template</h4> </li> <!-- Remove the class "menu-icon" to get rid of menu icon. Take out "Menu" to just have icon alone --> <li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li> </ul> <div class="top-bar-section"> <!-- Right Nav Section --> <ul class="right" data-bind="foreach: router.navigationModel"> <li data-bind="css: { active: isActive }"> <a data-bind="attr: { href: hash }, html: title"></a> </li> </ul> </div> </nav> <div class="container-fluid page-host" data-bind="router: { transition: 'entrance', cacheViews: true }"></div> </div> 

shell.js :

 (function() { define(["plugins/router", "durandal/app", "foundation"], function(router, app, foundation) { return { router: router, activate: function() { router.map([ { route: "", title: "Welcome", moduleId: "viewmodels/welcome", nav: true }, { route: "List", moduleId: "viewmodels/ListOfItems", nav: true } ]).buildNavigationModel(); return router.activate(); } }; }); }).call(this); 

Where is the real problem: ListOfItems.html :

 <section> <div> <h2 data-bind="text: displayName" style="text-align: center"></h2> <div class="row"> <div class="small-12 column"> <div data-bind="foreach: items"> <div class="panel"> <div class="row"> <div class="small-6 column"> <b>Number: <span data-bind="text: NumberA"></span></b> <br /> <b>Number B: <span data-bind="text: NumberB"></span></b> <br /> </div> <div class="small-6 column"> <b>Text A: <span data-bind="text: StringA"></span></b> <br /> <b>Text B: <span data-bind="text: StringB"></span></b> <br /> <b>Text C: <span data-bind="text: StringC"></span></b> <br /> </div> <div class="row"> <div class="small-12 column"> <a class="button" data-bind="click: function () { $parent.openModal(this); }">Open Modal</a> </div> </div> </div> </div> </div> </div> </div> <div id="myModal" class="reveal-modal" data-reveal> <h2>Edit Item</h2> <p class="lead">Please alter the item</p> <input id="Stepper" type="number" data-bind="value: ModalNumberA" /> <input id="Number1" type="number" data-bind="value: ModalNumberB" /> <input type="text" placeholder="Scope name" data-bind="value: ModalStringA" /> <input type="text" placeholder="Scope name" data-bind="value: ModalStringB" /> <input type="text" placeholder="Scope name" data-bind="value: ModalStringC" /> <a class="small button" data-bind="click: saveModalChanges">Save</a> <a class="small button" data-bind="click: closeModal">Close</a> <a class="close-reveal-modal">&#215;</a> </div> </div> </section> 

ListOfItems.js (generated from CoffeeScript):

 (function() { var _this = this; define(["durandal/app", "knockout", "krs", "jquery", "foundation.reveal", "foundation.dropdown"], function(app, ko, krs, $, reveal, dropdown) { return { displayName: "List of Items", items: ko.observableArray([]), result: ko.observable(), ModalNumberA: ko.observable(), ModalNumberB: ko.observable(), ModalStringA: ko.observable(), ModalStringB: ko.observable(), ModalStringC: ko.observable(), ItemBeingEdited: ko.observable(), activate: function() { var _this = this; return callTheWebApi("http://localhost:54129/api/mocked/GetMockedViewModelList", "GET", "", function(result) { console.log(result); _this.items(result); }); }, openModal: function(item) { this.ItemBeingEdited(item); this.ModalNumberA(item.NumberA); this.ModalNumberB(item.NumberB); this.ModalStringA(item.StringA); this.ModalStringB(item.StringB); this.ModalStringC(item.StringC); $(document).foundation(); return $("#myModal").foundation("reveal", "open"); }, saveModalChanges: function() { var itemBeingEdited, _this = this; itemBeingEdited = new Object(); itemBeingEdited.NumberA = this.ModalNumberA(); itemBeingEdited.NumberB = this.ModalNumberB(); itemBeingEdited.StringA = this.ModalStringA(); itemBeingEdited.StringB = this.ModalStringB(); itemBeingEdited.StringC = this.ModalStringC(); return callTheWebApi("http://localhost:54129/api/mocked/SaveMockedViewModel", "GET", "{'model':" + JSON.stringify(itemBeingEdited) + "}", function(success) { var templist; if (success) { _this.items()[_this.items().indexOf(_this.ItemBeingEdited())] = itemBeingEdited; templist = _this.items(); _this.items(null); _this.items(templist); return $("#myModal").foundation("reveal", "close"); } }); }, closeModal: function() { return $("#myModal").foundation("reveal", "close"); } }; }); }).call(this); 

If anyone can indicate where I'm going, I would really appreciate it.

+7
zurb-foundation requirejs durandal
source share
3 answers

When Foundation initialized in the block below, it requires that all objects that it binds to methods, such as modals , dropdowns , etc., must be inside the DOM. This means that you can do the following to provide most of the functionality of the basics.

Code initialization

 $(document).foundation(); 

By providing multiple KISS and keeping it simple, you can add this to each "viewModel" in the attached or compositionComplete callback, as indicated here . This ensures that all elements are in the DOM when Foundation initialized.

Example

 define(function(require){ var backend = require('backend'); return { customers:ko.observableArray([]), activate:function(){ // This runs as soon as the viewModel is loaded } attached:function(){ // This runs as soon as the view is full rendered $(document).foundation(); } }; }); 

In addition, I use micro-templating for modal ones (which often do not go into the DOM during Foundation initialization), and one trick I found is to initialize the base against the object itself.

Example

 $('#dynamicElement').foundation(); 

This works for things that use data attributes , such as modals, and allows you to run Foundation methods against these objects.


Regarding the Foundation, with KnockOut.js is mentioned in other answers. I looked at it because I love Foundation and KnockOut - it's my bread and butter, but these two just don't work well together. In the end, you rewrite the entire Fund for working with KO, and I personally do not have time for this, but I would like it to happen.

If you really need a responsive design and all the Foundation bells included in Durandal , you really need to use Bootstrap as it offers these features in a compatible way.

+2
source share

You might want to create custom Knockout bindings for Foundation. Otherwise, you will finish working with DOM links on all viewmodels, which in most cases is an anti-template for Durandal.

If you are not familiar with Knockout custom bindings, you can read about them at http://knockoutjs.com/documentation/custom-bindings.html . If you need help with custom bindings, come back here and I will be happy to help.

If I remember, foundation () is an initialization call in heavy weight. You only need to do this once. A simple custom binding placed on your shell.html trivializes initialization - the Durandal / Knockout path.

+1
source share

I believe script tags are coming out of durandal views, so this is probably why this is not working.

Not sure about the structure or nature of your project, but if your durendal application is delivered via a web page, you can initialize the foundation on the web page.

Alternatively, you can initialize it in composComplete methods or attached methods of your shell view model.

0
source share

All Articles