When updating the SpaceBars @index
native helper after sorting items in an #each
iteration, I believe the correct approach is to sort the cursor used within the #each
.
The cursor is derived from an Items
collection. The array used for sorting belongs to a different collection document (Projects
) containing an ordered list of each published item ID.
After moving an item to a new position, I update each item index within the project document array using the sortable stop
function. This involves removing it first with $pull
, then inserting it back at a specific position with $push
.
stop: function(e, ui) {
var project = Projects.findOne();
// obtain dragged element and its adjacent elements
el = ui.item.get(0)
before = ui.item.prev().get(0)
after = ui.item.next().get(0)
console.log(Blaze.getData(el)._id); // retrieve dropped item's ID
if(!before) {
console.log(after.dataset.index); // get index of next element
Projects.update({_id: project._id},
{$pull:
{
items: Blaze.getData(el)._id
}
})
Projects.update({_id: project._id},
{$push:
{
items:
{
$each:[Blaze.getData(el)._id],
$position:0
}
}
})
} else if(!after) {
Projects.update({_id: project._id},
{$pull:
{
items: Blaze.getData(el)._id
}
})
Projects.update({_id: project._id},
{$push:
{
items: Blaze.getData(el)._id
}
})
} else
Projects.update({_id: project._id},
{$pull:
{
items: Blaze.getData(el)._id
}
})
Projects.update({_id: project._id},
{$push:
{
items:
{
$each:[Blaze.getData(el)._id],
$position:after.dataset.index -1
}
}
})
}
As you can see, the above function uses the index property of the item (e.g., $position:after.dataset.index -1
). This is what needs to be updated by sorting the cursor.
In summary, there is an ordered array of IDs:
items : {
Id2131,
Id4233,
Id2243,
Id2331,
Id2455,
Id2123
}
Additionally, there is a publication with matching IDs but not in the correct order.
To align the cursor Items.find()
with the order of the other document array, how can the sorting be done?