3

This is my main.js file:

jQuery(function($) {
  $('LI.tree-item-name').has('ul').click(function() {
    if ($(this).hasClass('opened')) {
      $(this).find('UL').slideUp();
      $(this).removeClass('opened');
    } else {
      $(this).find('UL').slideDown();
      $(this).addClass('opened');
    }
    return false;
  });

  $('LI.tree-item-name li').click(function(e) {
    e.stopPropagation();
  })
});

jQuery(window).load(function(){
    jQuery('#video').removeClass('loading');
    jQuery('#video .box').animate({'opacity' : '1'});
    var $container = jQuery('#video');
    $container.masonry({
        columnWidth: 299,
        itemSelector: '.box'
    });
    jQuery('.popupbox').click(function(){
        jQuery('.popup:visible').fadeOut();
        var id = '#'+jQuery(this).data('popup');
        jQuery('#overlay').fadeIn();
        jQuery(id).css('top', jQuery(window).height()/2 - jQuery(id).height()/2).fadeIn();
        return false;
    });
    jQuery('.profile_popupbox').click(function(){
        jQuery('.popup:visible').fadeOut();
        var id = '#'+jQuery(this).data('popup');
        jQuery('#overlay').fadeIn();
        jQuery(id).css({'top': "20px", 'left': "-200px"}).fadeIn();             
        return false;
    });
    jQuery('#overlay').click(function(){
        jQuery('.popup:visible').fadeOut();
        jQuery(this).fadeOut();
    });
});

I would love for this to be Turbolinks-friendly.

I tried doing:

var ready;
ready = jQuery(window).load(function(){
    jQuery('#video').removeClass('loading');
    jQuery('#video .box').animate({'opacity' : '1'});
    var $container = jQuery('#video');
    $container.masonry({
        columnWidth: 299,
        itemSelector: '.box'
    });
    jQuery('.popupbox').click(function(){
        jQuery('.popup:visible').fadeOut();
        var id = '#'+jQuery(this).data('popup');
        jQuery('#overlay').fadeIn();
        jQuery(id).css('top', jQuery(window).height()/2 - jQuery(id).height()/2).fadeIn();
        return false;
    });
    jQuery('.profile_popupbox').click(function(){
        jQuery('.popup:visible').fadeOut();
        var id = '#'+jQuery(this).data('popup');
        jQuery('#overlay').fadeIn();
        // jQuery(id).css('top', jQuery(window).height() - jQuery(id).height()/2).fadeIn();
        jQuery(id).css({'top': "20px", 'left': "-200px"}).fadeIn();             
        return false;
    });
    jQuery('#overlay').click(function(){
        jQuery('.popup:visible').fadeOut();
        jQuery(this).fadeOut();
    });
});

$(document).ready(ready);
$(document).on('page:load', ready);

That didn't work, and it didn't make both functions Turbolinks-friendly.

So I want to just make the entire file TL-friendly.

Edit 1

I also have an upload.js.erb which has this, that doesn't get executed after initial page load:

$("#myVCModal").html("<%= escape_javascript(render 'videos/upload_video') %>");
$("#myModal").html("<%= escape_javascript(render 'videos/upload_video') %>");

$("#add-video-step-1").html("<%= escape_javascript(render 'videos/upload_video') %>");
$("#video-comment").html("<%= escape_javascript(render 'videos/upload_video') %>");
$('myModalPL').modal(show);

Ladda.bind('button');

I would like for all of these JS bits throughout my app to go back to working.

Edit 2

So now I have the main.js stuff working - Thanks @User089247. But the other modal executing JS is not working at all....i.e. the code under Edit 1.

What is happening is I hit this upload button:

<%= link_to "<i class='fa fa-film fa-lg'></i> Upload".html_safe, "#", class: "upload popupbox", data: { popup: "add-video-step-1"} %>

This is the modal that gets fired:

<div id="overlay">&nbsp;</div>
<div class="popup" id="add-video-step-1">
  <div class="titles clearfix">
      <h2>Upload a Video</h2>
      <p><i>Step 1 of 2 - TEST</i></p>
  </div>
  <div class="content">
    <% if @family_tree %>
      <%= simple_form_for([@family_tree, @video], :remote => true) do |f| %>
        <div class="column">
              <div class="f-row">
                  <%= f.input :title, label: "Title:" %>
              </div>
              <div class="f-row">
                  <%= f.input :description,label: "Description:" %>
              </div>
              <div class="f-row">
                  <%= f.input :circa, as: :datepicker, start_year: Date.today.year - 5, label: "Circa:" %>
              </div>
              <div class="f-row">
                  <label for="family">Family in this video:</label>
                  <%= f.collection_select :user_ids, @family_tree.members.order(:first_name), :id, :first_name, {}, {multiple: true} %>
              </div>
          </div>
          <%= f.button :submit, "Add Video" %>
        <% end %>
      <% end %>
    </div> <!-- //content -->
</div> <!-- //popup -->

Then when you press "Add Video", it should take you to the 2nd modal which is this:

<div class="bootstrap-styles">
 <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel">Upload your Video</h3>
    <p><i>Step 2 of 2 - TEST</i></p>
  </div>
  <div class="modal-body">
    <div class="form">
      <%= form_tag @upload_info[:url], :multipart => true do %>
        <div>Step 2 of 2</div>
        <%= hidden_field_tag :token, @upload_info[:token] %>
        <%= file_field_tag :file, title: 'Choose video to upload' %>
        <p class="uploader">
          <button class="btn btn-success ladda-button" data-color="green" data-style="expand-left"><span class="ladda-label">Upload Video</span><span class="ladda-spinner"></span></button>
        </p>
      <% end %>

    </div>
  </div>
  <div class="modal-footer">
  </div>
</div>

I guess the issue is I am not seeing how this 2nd modal would be executed, based on my upload.js.erb or am I missing something?

Edit 3

Here are the relevant portions of a server log when this upload video action is done (truncated for brevity):

Started POST "/family_trees/1/videos" for 127.0.0.1 at 2014-10-28 02:16:48 -0500
Processing by VideosController#create as JS
  Parameters: {"utf8"=>"✓", "video"=>{"title"=>"Hello there", "description"=>"Why hello there lady", "circa"=>"", "user_ids"=>[""]}, "commit"=>"Add Video", "family_tree_id"=>"1"}
  User Load (3.1ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
  FamilyTree Load (1.2ms)  SELECT  "family_trees".* FROM "family_trees"  WHERE "family_trees"."user_id" = $1 LIMIT 1  [["user_id", 1]]
  ReadMark Load (1.0ms)  SELECT  "read_marks".* FROM "read_marks"  WHERE "read_marks"."user_id" = $1 AND "read_marks"."readable_type" = 'PublicActivity::ORM::ActiveRecord::Activity' AND "read_marks"."readable_id" IS NULL  ORDER BY "read_marks"."id" ASC LIMIT 1  [["user_id", 1]]
  FamilyTree Load (1.0ms)  SELECT  "family_trees".* FROM "family_trees"  WHERE "family_trees"."id" = $1 LIMIT 1  [["id", 1]]
   (1.2ms)  SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = $1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))  [["user_id", 1]]
  Membership Load (1.7ms)  SELECT "memberships".* FROM "memberships"  WHERE "memberships"."user_id" = 1 AND "memberships"."family_tree_id" = 1
   (3.6ms)  BEGIN
  SQL (3.4ms)  INSERT INTO "videos" ("created_at", "description", "title", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["created_at", "2014-10-28 07:16:48.340452"], ["description", "Why hello there lady"], ["title", "Hello there"], ["updated_at", "2014-10-28 07:16:48.340452"]]
   (4.5ms)  COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 40ms (ActiveRecord: 20.6ms)

Started GET "/" for 127.0.0.1 at 2014-10-28 02:16:48 -0500
  User Load (4.0ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 1  ORDER BY "users"."id" ASC LIMIT 1
Processing by DashboardController#index as JS

For what it's worth, even after it successfully finishes processing this GET "/" request, it doesn't actually reload/redirect the browser. It just stays at the modal.

Error in the JS console says:

Failed to load resource: net::ERR_CACHE_MISS 

Here is the VideoController#Create

  def create
    authorize! :read, @family_tree
    @video = Video.new(video_params)

    respond_to do |format|
      if @video.save
        format.html { redirect_to root_path }
        format.json { render action: 'show', status: :created, location: @video }
      else
        format.html { render action: 'new' }
        format.json { render json: @video.errors, status: :unprocessable_entity }
      end
    end
marcamillion
  • 32,933
  • 55
  • 189
  • 380
  • Have you tried using https://rubygems.org/gems/jquery-turbolinks ? It brings the default events back. – Ilya Bodrov-Krukowski Oct 20 '14 at 08:47
  • Yep..I am using it. Yet I still have a problem with this block of code. Specifically when I click many pages and go back to my main page, this line doesn't get executed when it should: `jQuery('#video .box').animate({'opacity' : '1'});` - so I imagine that whole function is not being executed. – marcamillion Oct 20 '14 at 08:51
  • So what's exactly happening? is second modal popping up or not? Do you see any JavaScript/jQuery error or any error in rails server log? – Surya Oct 27 '14 at 12:33
  • @User089247 You are correct, the 2nd modal is not popping up. No JS or jQuery errors and no errors in the server log. All that is happening is that it is saving the record in the DB, and redirecting to the root_path. I am going to update the question with the server logs. – marcamillion Oct 28 '14 at 07:15
  • @User089247 So I was wrong. It seems there is a JS error. I updated the question with the server logs and the JS error. – marcamillion Oct 28 '14 at 07:22
  • Well, your JS error looks like not a code bug: https://stackoverflow.com/questions/26494153/stupid-error-failed-to-load-resource-neterr-cache-miss and http://stackoverflow.com/a/26480396/645886 You probably need to see why second modal isn't working in the code. Sorry, but I can't really replicate the code to help you with this. – Surya Oct 28 '14 at 07:37
  • Want to see a live demo? – marcamillion Oct 28 '14 at 08:43
  • You can check it out here - http://kordli2.herokuapp.com/ - ( rory2@example.com/password). Click on "upload" in the navbar at the top, and try to go through that process. Once you press "Add Video", it seems like it freezes. What actually happens is the video record is created in the bg, but it just doesn't transition to the second modal. Thoughts? – marcamillion Oct 28 '14 at 09:31
  • @User089247 any more ideas? – marcamillion Oct 29 '14 at 06:35
  • @marcamillion : It's not like that I don't want to help but I am sorry that I really didn't understand a valid reason why your second modal is not popping up, even the errors you have posted does not lead to any bug in code. – Surya Oct 29 '14 at 06:48
  • @User089247 That's why I posted the login credentials, just in case you can find something that I have overlooked. Any luck with that? – marcamillion Oct 29 '14 at 07:50
  • @marcamillion looks like your form is not being submitted or not returning any value at all. – Surya Oct 29 '14 at 07:55
  • @User089247 but it successfully creates a record for the `Video` in my DB. So it definitely does submit the first form. I believe that JS I highlighted should take the pressing of that submit button and fire the 2nd modal but that is not happening, despite the form being submitted properly. Notice the logs that show that the `video` is inserted into the db - `SQL (3.4ms) INSERT INTO "videos" ("created_at", "description", "title", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["description", "Why hello there lady"], ["title", "Hello there"], (4.5ms) COMMIT` – marcamillion Oct 29 '14 at 08:26
  • @User089247 Also the next request shows that it has been completed, because it does the redirect to the main page - as you can see by the logs. – marcamillion Oct 29 '14 at 08:27

1 Answers1

3

Change your main.js to this(I prefer this way as it is very easy to debug the issues in jQuery without getting lost in the web of methods, and it works really well with turbolinks without adding jquery-turbolinks gem for it):

$(document).on("page:change", function(){
  MainJS.init();
});

MainJS = {
  init: function() {
    MainJS.initializePage();
    $('.popupbox').on('click', MainJS.popupBox);
    $('.profile_popupbox').on('click', MainJS.profilePopupbox);
    $('#overlay').on('click', MainJS.overLay);
    $('LI.tree-item-name').has('ul').on('click', MainJS.treeItemName);

    $('LI.tree-item-name li').on('click', function(ev) {
      ev.stopPropagation();
    });
  },

  initializePage: function(){
    $('#video').removeClass('loading');
    $('#video .box').animate({'opacity' : '1'});
    var $container = $('#video');
    $container.masonry({
      columnWidth: 299,
      itemSelector: '.box'
    });
  },

  popupBox: function(){
    $('.popup:visible').fadeOut();
    var id = '#'+$(this).data('popup');
    $('#overlay').fadeIn();
    $(id).css('top', $(window).height()/2 - $(id).height()/2).fadeIn();
    return false;
  },

  profilePopupbox: function(){
    $('.popup:visible').fadeOut();
    var id = '#'+$(this).data('popup');
    $('#overlay').fadeIn();
    // $(id).css('top', $(window).height() - $(id).height()/2).fadeIn();
    $(id).css({'top': "20px", 'left': "-200px"}).fadeIn();             
    return false;
  },

  overLay: function(){
    $('.popup:visible').fadeOut();
    $(this).fadeOut();
  },

  treeItemName: function(){
    if ($(this).hasClass('opened')) {
      $(this).find('UL').slideUp();
      $(this).removeClass('opened');
    } else {
      $(this).find('UL').slideDown();
      $(this).addClass('opened');
    }
    return false;
  }
}

Now, in case you can easily debug the above code to see which part is working/not-working, for example:

$(document).on("page:change", function(){
  MainJS.init();
  console.log('MainJS.init() was called successfully);
});

or:

MainJS = {
  init: function() {
    MainJS.initializePage();
    $('.popupbox').on('click', MainJS.popupBox);
    $('.profile_popupbox').on('click', MainJS.profilePopupbox);
    $('#overlay').on('click', MainJS.overLay);
    console.log('MainJS initialization was successful.');
  },

and so on. You get the idea, right?

Regarding your upload.js.erb issue, I am not sure what's wrong in there as it should work(as same thing works for me), however, you can wrap your code around: $(document).on("page:change", function(){ to see if it works, but I suspect that it is not the issue though.

Surya
  • 15,703
  • 3
  • 51
  • 74
  • Thanks for this. Given your answer, does this mean I don't need the `jQuery.turbolinks` gem? Just asking because I am using it. – marcamillion Oct 27 '14 at 10:15
  • I honestly never used jquery-turbolinks gem in my Rails 4 applications. I use the same approach I presented in answer, I am not sure what purpose you have it, but just to be on a safer side, you can keep it in your app and remove it later and see if there's any dependency on it when everything works and committed on your remote git repo. – Surya Oct 27 '14 at 10:20
  • Ahh ok. That makes sense. You left off one piece of the JS code, which was the top part with this: `$('LI.tree-item-name').has('ul').click(function() {`. How would I convert that section to this new structure? Sorry...JS noob :| – marcamillion Oct 27 '14 at 10:21
  • 1
    Ok great...this update did work. Just the `upload.js.erb` issue. I wrapped it in the `document.on page:change` and that didn't work. What should I have in my `application.js`? – marcamillion Oct 27 '14 at 10:47
  • I am not sure what's wrong with upload.js.erb. I do see this code: `$('myModalPL').modal(show);` are you sure it is correct? shouldn't is have `#` or `.`? something like: `$('#myModalPL').modal(show);`? – Surya Oct 27 '14 at 10:49
  • Then I have no idea on your js.erb file, buddy, I guess you'll have to see what are the error being thrown in your server log, as it works for me without any issue. – Surya Oct 27 '14 at 11:40
  • Ok I added some more code for this step, hopefully that helps us troubleshoot it some more. – marcamillion Oct 27 '14 at 12:18