Ian Steffy Ian Steffy - 2 days ago 4
Javascript Question

Emberjs will not load jquery/javascript, run code when html is inserted in the page

Help!

I'm working on a meaty emberjs/yeoman project that uses multiple hbs templates that can all be routed to from one application.hbs's sidebar.

The problem is when I load the page, sometimes the Jquery to make that sidebar collapse will not work while other jquery in that same file does. Sometimes nothing works at all.

I'm calling my javascript/jquery from one file called magic.js

<body>

<!-- build:js scripts/components.js -->
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/handlebars/handlebars.runtime.js"></script>
<script src="bower_components/ember/ember.js"></script>
<script src="bower_components/ember-data-shim/ember-data.js"></script>
<!-- endbuild -->
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC-c0QvqnFcYbP4r6t7sBiKPu9GPqRLRug&sensor=true">
</script>

<!-- build:js(.tmp) scripts/templates.js -->
<script src="scripts/compiled-templates.js"></script>
<!-- endbuild -->

<!-- build:js(.tmp) scripts/main.js -->
<script src="scripts/combined-scripts.js"></script>
<!-- endbuild -->

<!-- build:js scripts/plugins.js -->
<script src="bower_components/bootstrap-sass/js/affix.js"></script>
<script src="bower_components/bootstrap-sass/js/alert.js"></script>
<script src="bower_components/bootstrap-sass/js/dropdown.js"></script>
<script src="bower_components/bootstrap-sass/js/tooltip.js"></script>
<script src="bower_components/bootstrap-sass/js/modal.js"></script>
<script src="bower_components/bootstrap-sass/js/transition.js"></script>
<script src="bower_components/bootstrap-sass/js/button.js"></script>
<script src="bower_components/bootstrap-sass/js/popover.js"></script>
<script src="bower_components/bootstrap-sass/js/carousel.js"></script>
<script src="bower_components/bootstrap-sass/js/scrollspy.js"></script>
<script src="bower_components/bootstrap-sass/js/collapse.js"></script>
<script src="bower_components/bootstrap-sass/js/tab.js"></script>
<!-- endbuild -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script>
<script src="scripts/models/permit_model.js"></script>
<!-- // <script src="scripts/arcgislink_compiled.js" type="text/javascript"></script> -->
<script src="scripts/magic.js"></script> <!-- Controls UI based javascript. Buttons, pretty effects, animations, etc. -->


magic.js is the last thing called before the body closes.

This is the magic.js file

$( document ).ready(function() {
var close=true


$(".collapsibleHeader").click(function(){
$(this).siblings().slideToggle("fast");
});
// Sidebar START
$(".arrow").click(function() {
if($('.float-left-col').css('width')=='200px') {
$('.float-left-col').removeClass('open');
$('.float-left-col').addClass('closed');
$('.sidebar-button-text').addClass('vanish');
$('.arrow').removeClass('reverse-rotate');
$('.arrow').addClass('rotate');
$('.full-logo').addClass('vanish');
$('.logo-only-container').removeClass('vanish');
$('.content-container').css('margin-left','80px')

}
else {
$('.float-left-col').removeClass('closed');
$('.float-left-col').addClass('open');
$('.arrow').addClass('reverse-rotate');
$('.logo-only-container').addClass('vanish');
$('.full-logo').removeClass('vanish');
var delay = setTimeout(function(){
$('.sidebar-button-text').removeClass('vanish');},250)
$('.arrow').removeClass('rotate');
$('.content-container').css('margin-left','200px');
}
});


The sidebar that isn't working is in the application.hbs file so I'm not sure why it would stop loading.

<div class="super-col">
<div id="sidebar-wrapper" class="float-left-col open">
<ul class="nav nav-pills nav-stacked text-center">
//..stuff inside the sidebar..


Why is my javascript not loading properly? Should I be calling it in a different file/s?

Answer

You're probably trying to attach the jquery before the elements have been created. Document ready isn't necessarily the same time Ember's views are ready.

In your case you insert the sidebar in the application template, so in your application view you could add the jquery in the didInsertElement hook

App.ApplicationView = Em.View.extend({
  doStuff: function(){
    //do your jquery here, the element is in the page now
  }.on('didInsertElement')
});

This pattern can be applied for other views as well throughout your app

App.FooView = Em.View.extend({
  doStuff: function(){
    // do some crazy stuff cause the foo template has been inserted!
  }.on('didInsertElement')
});