Awesome
Meteor "todos" example with drag-n-drop and animation
This is modified todos Meteor example.
Live demo on Meteor hosting: http://todos-dnd-animated.meteor.com.
Following features added:
- sortable from jquery-ui used for drag-n-drop todos and todo lists.
- Sorting animation displayed on other application clients while sorting.
- Remove and add animation added.
- Added url routing for tags filtering (just for fun).
I hope this feature will be added soon in Meteor as Avital Oliver written: Previewing Meteor's new rendering engine: reactive sortable lists
I need it now, so I had to implement something similar. I have not much of Meteor using experience, so any help or criticism will be appriciated.
How to use step-by-step
1. Include animtion.js
Use animation.js file in your project to reuse drag-n-drop animations feature.
2. Create list item template with data-id
This will isolate item template and allows to identify each item.
<template name="list">
<div data-id="{{_id}}">
...
</div>
</template>
3. Create empty container for list items in list template
{{#each ... }}
should not be used because of custom rendering method.
<template name="lists">
<div id="lists">
</div>
</template>
4. Create rendered
event handler in list template
This step including following:
- Prevents multiple useless
rendered
calls. - Stops observer if template switched to another context.
- Defines items container.
- Defines items cursor.
- Defines item template.
- Defines method of updating order.
Example for todos:
Template.lists.rendered = function() {
var items = this.find('.s-items');
if (!items) {
return;
}
var $items = $(items);
// Prevent multiple `rendered` calls on one list.
// `rendered` called each time after `items.append`. Solve this by trigger.
if ($items.attr('rendered')) {
return;
}
$items.attr('rendered', true);
// [animation] Init animation.
var animation = createSortableListAnimation({
el: 'div',
$items: $items,
template: Template.list,
cursor: Template.lists.lists(),
onSortableStop: function(event, ui) {
var info = getItemOrderInfo(ui);
if (info.oldOrder != info.order) {
Lists.update(info._id, {$set: {order: info.order}});
}
}
});
this.handle = animation.observerHandle;
};
Known issues
Full item rerender on change.
Inputs preservations will not work between binded data item changes.
I don't know yet how to rerender template using updated context data. So, for now, every time item data is updated - old item template will be deleted and new one will be created.
Anybody know to fix it?
Prevent list item rerender on mousedown
sortable
will work with element after mousedown. Don't make rerender events on mousedown, becuase sortable
will not like it.
Only first change shown as animation.
Not actually issue but can be odd: if many changes occurs - only first of them will be animated.
Roadmap
Also I want to implement following in next steps:
- Generic mechanism to preserver rerendered templates state.
Contribute
I'll be glad to receive any feedback or help on it. Fill free to make forks or issues.