Skip to content

Instantly share code, notes, and snippets.

@nbrew
Created November 29, 2012 20:25
Show Gist options
  • Save nbrew/4171665 to your computer and use it in GitHub Desktop.
Save nbrew/4171665 to your computer and use it in GitHub Desktop.
Reorderable List Javascript Library
// Sample Usage:
// var init_sortable_events = function() {
// var rl, category_id;
// jQuery('#list-info ul').each(function(index, element){
// category_id = element.id.split('_')[1];
// rl = new ReorderableList();
// rl.reorder_action_element = '#event_category_events_reorder_action_' + category_id;
// rl.reorder_action_done_element = '#event_category_events_reorder_action_done_' + category_id;
// rl.sortable_list_id = '#' + element.id;
// rl.update_url = '/admin/events/update_positions';
// rl.tree = false;
// rl.init();
// });
// };
// see http://bitstructures.com/2007/11/javascript-method-callbacks
function bind_instance(toObjectInstance, methodName) {
return function() {toObjectInstance[methodName]();};
};
var ReorderableList = function() {
this.reorder_action_element = '#reorder_action';
this.reorder_action_done_element = '#reorder_action_done';
this.sortable_list_id = '#sortable_list';
this.sortable_list = null;
this.tree = false;
this.update_url = null;
this.init = function() {
this.sortable_list = jQuery(this.sortable_list_id);
jQuery(this.reorder_action_element).bind('click', jQuery.proxy(this.enable_reordering, this));
jQuery(this.reorder_action_done_element).bind('click', jQuery.proxy(this.disable_reordering, this));
};
this.enable_reordering = function(e) {
if(e) { e.preventDefault(); }
this.sortable_list.find('li').each(function(index, li) {
if (jQuery('ul', li).length) { return; }
if (this.tree) {
jQuery("<ul></ul>").appendTo(li);
}
});
jQuery(this.sortable_list_id + ' .publish-toggle').hide();
this.sortable_list.add(this.sortable_list.find('ul')).sortable({
'connectWith': jQuery(this.sortable_list.find('ul'))
, 'tolerance': 'pointer'
, 'placeholder': 'placeholder'
, 'cursor': 'drag'
, 'items': 'li'
, 'axis': 'y'
});
jQuery(this.reorder_action_element).hide();
jQuery(this.reorder_action_done_element).show();
};
this.parse_branch = function(indexes, li) {
branch = "&sortable_list";
jQuery.each(indexes, function(i, index) {
branch += "[" + index + "]";
});
branch += "[id]=" + jQuery(jQuery(li).attr('id').split('_')).last().get(0);
// parse any children branches too.
jQuery(li).find('> li[id], > ul li[id]').each(function(i, child) {
current_indexes = jQuery.merge(jQuery.merge([], indexes), [i]);
branch += this.parse_branch(current_indexes, child);
});
return branch;
};
this.disable_reordering = function(e) {
if(jQuery(this.reorder_action_done_element).hasClass('loading')){
return false;
}
if(e) { e.preventDefault(); }
jQuery(this.reorder_action_done_element).addClass('loading');
if (this.update_url != null) {
serialized = "";
this.sortable_list.find('> li[id]').each(function(index, li) {
if (this.tree) {
serialized += this.parse_branch([index], li);
}
else {
if (serialized.length > 0) { serialized += '&'; }
serialized += "sortable_list[]=" + jQuery(jQuery(li).attr('id').split('_')).last().get(0);
}
});
serialized += "&tree=" + this.tree;
serialized += "&continue_reordering=false";
serialized += "&sortable_id=" + this.sortable_list_id.split('#')[1];
jQuery.post(this.update_url, serialized, bind_instance(this, 'post_success'));
} else {
jQuery(this.sortable_list).removeClass('reordering').sortable('destroy');
jQuery(this.reorder_action_done_element).hide().removeClass('loading');
jQuery(this.reorder_action_element).show();
}
};
this.post_success = function(data) {
jQuery(this.sortable_list.get(0)).html(data);
jQuery(this.sortable_list).removeClass('reordering').sortable('destroy');
jQuery(this.reorder_action_done_element).hide().removeClass('loading');
jQuery(this.sortable_list_id + ' .publish-toggle').show();
jQuery(this.reorder_action_element).show();
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment