Let's say that I have:
a 'Survey' with many 'Questions' which has many 'Answers'
If I had a 'Survey' that had 2 instances of a 'Question', let's call them: 'Good Question' and 'Bad Question'
'Good Question' has 5 'Answers' and 'Bad Question' has 3 'Answers'
If 'Good Question' and 'Bad Question' were connected sortable lists with this jQuery-UI interaction. http://jqueryui.com/sortable/#connect-lists
I know how to display them as 2 sortable lists using the jQuery-UI and I can also drop an 'Answer' from a 'Bad Question' to a 'Good Question'. But how would I save their new sorted positions and their newly sorted association to another 'Question' back to a Rails database?
Railscasts has how to save position for a single sortable lists but not for lists that belong to different associated models.
http://railscasts.com/episodes/147-sortable-lists-revised
I really appreciate the help here!
EDIT
I realized that I just need to POST to the Rails controller, an element id of the list that I dropped the 'Answer' into (i.e <ol class = "connectableSortable" id = "Good_Question"</ol>
)
This is the syntax for how the Railscast does a POST to the Rails Controller to pass an array of object_id's in the sortable order.
jQuery ->
$('#faqs').sortable(
axis: 'y'
update: ->
$.post($(this).data('update-url'), $(this).sortable('serialize'))
)
How would I update this POST to pass the list ID to it, so I can just update the 'Question' foreign key for the 'Answer' to the list 'ID' that it fell into?
This SO answer has a way to retrieve the list ID. Get the item/object where the element is dropped
So now, I really just need to know how to pass an extra parameter back to the rails controller. Any help?
I was able to figure out what I wanted after a couple of days of struggling through this.
The model here is a Day has many Activities (as opposed to the original question of a Question has many Answers).
This is my jQuery code (in Coffeescript):
Using jQuery selectors to get the ID of each list item and the column ID of each list item. Pushing it as a Parameter that looks like this Activity:[{"id":"1", "column":"1"}, {"id":"2", "column":"1"}...etc]
jQuery ->
$('[id*="day"]').sortable(
connectWith: ".day"
placeholder: "ui-state-highlight"
update: (event, ui) ->
neworder = new Array()
$(this).children().each ->
column = $(this).parent().attr("id").match(/\d+/)[0]
id = $(this).attr("id").match(/\d+/)[0]
neworder.push(
id: id
column: column
)
alert neworder
$.ajax
url: "sort"
type: "POST"
data: { Activity: JSON.stringify(neworder) }
).disableSelection()
How I parse the AJAX call back to the Rails Controller:
I'm looping through each {"id":"1", "column":"1"}
object in the array and also getting it's index position.
def sort
JSON.parse(params[:Activity]).each_with_index do |x, index|
idx = x["id"]
positionx = index+1
column = x["column"]
activity = Activity.find(idx)
activity.update_attributes(:position => positionx, :day_id => column)
end
render nothing: true
end
Back in my Model, I order "Activities" association by it's Position so when I list it in the view, it shows up in the correct position.
class Day < ActiveRecord::Base
has_many :activities, :order => 'position'
accepts_nested_attributes_for :activities, allow_destroy: true
end
More details for how I arrived to this in these 2 answers:
Formatting Parameters for Ajax POST request to Rails Controller - for jQuery-UI sortable list
jQuery AJAX POST to Rails Controller. Error when doing each_with_index (TypeError can't convert Symbol into Integer)