Question

For the sake of simplicity, I have a form that updates a partial. Nothing special there. Within the partial, I have a jQuery sortable list. Before updating the form, I can drag things around in the list without problem.

However, after I update the list, it's like js isn't reloaded and I have to refresh the whole page to get things rolling again.

I've tried everything, even borrowed the demo jQuery application from Ryan Bates Esq. over here. That doesn't work either after I put some js shizzle in the partial.

I'm sure it's simple but I'm an ajax / jQuery newbie and am really struggling.

View:

#test_one
  = render "test_one"

partial "test_one"

= form_for @location, :remote => true do |f|
  %table
    %tr= collection_select(:location, :type_ids, Type.all, :id, :name, {:prompt => true}, :multiple => true, :class=>"chzn-select")
     %tr
       %td
         %ul#types.unstyled{"data-update-url" => sort_types_locations_url}
           - @types.each do |type|
             = content_tag_for :li, type do
               %span.handle
                 [Drag]
               = type.name

update.js.erb

$("#test_one").html('<%= escape_javascript render("test_two") %>');

And in my controller:

  def update
    @location = Location.find(params[:id])
    @types = @location.types.order('location_types.position').limit(2)
    respond_to do |format|
      if @location.update_attributes!(params[:location])
        flash[:notice] = 'Settings updated successfully'
        format.html { redirect_to edit_location_path }
        format.js
      else
        format.html { render action: "edit_access" }
        format.js { render action: "update_access_errors" }
      end
    end
  end

And finally in locations.js.coffee

jQuery ->
  $('#types').sortable(
      axis: 'y'
      update: ->
        $.post($(this).data('update-url'), $(this).sortable('serialize'))
      )

The update works, I get no errors and I have nothing in my console. Am a lot lost with this now - how can I get the js to reload after I update the record?

Was it helpful?

Solution

The reason is, your custom js(about sortable) is loaded on document ready, and won't be fired again once partial updated.

The solution is: wrap your custom js into a function. Call this function when document ready and update happens.

# locations.js.coffee
$ ->
  $(document).custom_js()

$.fn.custom_js ->
  $('#types').sortable(
    axis: 'y'
    update: ->
      $.post($(this).data('update-url'), $(this).sortable('serialize'))
    )

# update.js.erb
$("#test_one").html('<%= escape_javascript render("test_two") %>');
$(document).custom_js();

Side note about custom js function: No need to wrap all custom codes here, just the part relating to what are going to added/updated by Ajax.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top