1

I have a Rails 3.2.21 app which I use select2 for my dropdown menus and UI. In this view I'm doing a multi-select to pick different elements/objects in my view/form. When the initial controller view loads it's fine as you can see by the first picture. But when I click to a second page to paginate, the select2 is broken by the Ajax as you can see in the last picture.

Here is what my view looks like:

index.html.erb

<h3 class="offset3">5 most recent pages</h3>
<div class="row">
    <div class="span3"><div class="well" id="form"><%= render 'form' %></div></div>
<div class="span9"><div id="pages"><%= render 'pages' %></div></div>
</div>

index.js.erb

$("#form").html("<%= escape_javascript render("form") %>");
$("#pages").html("<%= escape_javascript render("pages") %>");

_form.html.erb

<%= form_for(@page) do |f| %>
    <div class="control-group">
        <div class="controls">  
      <%= f.label :message %>
      <%= f.text_area(:message, size: "40x2", :maxlength => 254, placeholder: "Enter your message here", required: true) %>

    <%= f.label 'Unit'%>

    <%= f.select :unit_id, options_for_select(Unit.active.order(:unit_name).map{ |unit| [unit.unit_name, unit.id] } + [["All Units", "all"]]), {:include_blank => true}, {:multiple => 'true', class: 'select'} %>

    <%= f.label 'Region' %>
    <%= f.collection_select(:region_id, Region.order("area ASC"), :id, :area, {:include_blank => true}, {:multiple => 'true', :class => 'select' } )%>
      </div>
        </br>
        <%= f.button  'Send Page', class: 'btn btn-info', data: {disable_with: "<i class='icon-spinner'></i>Sending..."} %>
    </div>
<% end %>

_results.html.erb

<table class="table table-striped">
  <thead>
    <tr>
      <th>Incident Number</th>
      <th>Patient Name</th>
      <th>Transfer Date</th>
      <th>Transferred From</th>
      <th>Transferred To</th>
      <th>Determinant</th>
      <th>Unit</th>
      <th>Insurance</th>
      <th>Cancelation Reason</th>
      <th>Billing Reference</th>
      <th>Run Time</th>
      <th></th>
    </tr>
  </thead>

  <tbody>
    <% @calls.each do |c| %>
      <tr>
        <td><%= c.incident_number %></td>
        <td><%= c.patient_name %></td>
        <td><%= c.transfer_date.strftime("%m/%d/%y") %></td>
        <td><%= transferred_from(c) %><br/><%= transferred_from_address(c) %></td>
        <td><%= transferred_to(c) %><br/><%= transferred_to_address(c) %></td>
        <td><%= c.nature.try(:determinant)%></td>
        <td><%= c.units.map(&:unit_name).join(", ") %></td>
        <td><%= c.insurance.try(:insurance_type)%></td>
        <td><%= c.cancel_reason.try(:reason) %></td>
        <td><%= c.imx_num %></td>
        <td><%= TimeFormatter.format_time(c.run_time) if c.in_service_time? %></td>
        <td><%= link_to 'View', c, :class => 'btn btn-info btn-mini'%></td>
      </tr>
    <% end %>
  </tbody>
</table>

<%= will_paginate @calls, :renderer => BootstrapPagination::Rails %>

Here is the jQuery from my application.js file:

$(function (){
  $(".select").select2({
        placeholder: "Select One",
        allowClear: true
  });

    $(function() {
      $("#pages th a, #pages .pagination a").live("click", function() {
        $.getScript(this.href);
        return false;
      });
    });

It looks like when I click a pagination link the dom is not getting reloaded and thus breaking the UI with select2. I can still pick objects in the form but UI-wise it's broken.

I was wondering if anyone could help point me in the right direction with this as I'm not very savvy with jQuery or javascript/ajax.

If my question is not clear or you need further examples, please let me know.

working enter image description here

breaks on ajax pagination enter image description here

nulltek
  • 3,247
  • 9
  • 44
  • 94
  • Unrelated, but, what version of jQuery are you using? – lshettyl Jun 06 '15 at 14:57
  • I'm sorry, I should have included that. I'm using `jquery-rails 2.1.4` It's a legacy app so I'm concerned with upgrading and breaking something else at this point. – nulltek Jun 06 '15 at 15:05
  • 1
    Most likely you aren't reinitializing Select2 after the next page loads, which is why you just see a normal select – Kevin Brown-Silva Jun 06 '15 at 15:22
  • @KevinBrown I think you're right. How could i reinitialize select2 after the ajax pagination page load? Sorry for the newb question. – nulltek Jun 06 '15 at 15:41
  • Where are you currently initializing select2? I'm not familiar with how things are done with rails. – Kevin Brown-Silva Jun 06 '15 at 15:43
  • @KevinBrown In application.js. However a quick Google search found something unrelated but showing how to reinitialize the select2. `$("select").select2("destroy").select2();` I put this in my `index.js.erb` file and it no longer breaks the UI, but the Placeholder that says "select one" doesn't show up on pagination. So I'm making progress :) – nulltek Jun 06 '15 at 15:45
  • If you include the relevant snippet from `application.js` in your question, we might be able to determine the exact call to `.select2` that is needed. – Kevin Brown-Silva Jun 06 '15 at 15:46
  • @KevinBrown Sorry about that. I just updated my question with the relevation snippet where I initialize select2. :) – nulltek Jun 06 '15 at 16:14
  • maybe your problem is with turbolinks... see [this](http://stackoverflow.com/questions/18770517/rails-4-how-to-use-document-ready-with-turbo-links). the problem basically is the javascript `ready` action, when you change page did not trigger the ready action and then you have to use `page:load`. – inye Jun 06 '15 at 19:04
  • @inye I'm using Rails 3.2.21, no turbolinks being used natively or as a gem. :) – nulltek Jun 06 '15 at 19:47
  • Even if you aren't using turbolinks directly, you're emulating it through the use of `getScript`, and the same issues apply. – Kevin Brown-Silva Jun 07 '15 at 01:49
  • @KevinBrown Ah I see what you're saying. Is there anyway around this? – nulltek Jun 07 '15 at 12:16

1 Answers1

0

So far this is the only useful answer I've come up with.

In my index.js.erb file I put the following:

   $("select").select2({
        placeholder: "Select One",
        allowClear: true
  }); init();

This will reinitialize select2 by destroying the call on an Ajax request then calling select2 again. It behaves as expected and keeps the UI properties while overriding the "turbolinks-like" Ajax behavior.

This is working 100% for me, although it feels a bit hackish that I have to do this in UJS, but hey whatever works right?

nulltek
  • 3,247
  • 9
  • 44
  • 94