app/assets/javascripts/hooch.js in hooch-0.3.0 vs app/assets/javascripts/hooch.js in hooch-0.4.0
- old
+ new
@@ -586,12 +586,399 @@
var fake_option = this
$fake_option.on('click',function(){
$fake_select.select(fake_option)
})
}
+ }),
+ Sorter: Class.extend({
+ init: function($sorter){
+ this.$sorter = $sorter;
+ this.width = $sorter.width();
+ this.getSortElements();
+ var sorter = this
+ $(window).on('mouseup', function(e){
+ sorter.onMouseup();
+ });
+ $(window).on('mousemove', function(e){
+ sorter.onMousemove(e)
+ })
+ },
+ onMousemove: function(e){
+ if(this.dragging_element){
+ hooch.pauseEvent(e)
+ this.redrawDraggingElement(e);
+ this.refreshSequence(e)
+ return false
+ }
+ },
+ getSortElements: function(){
+ this.$sort_elements = this.$sorter.children()
+ this.sort_elements = []
+ var sorter = this;
+ this.$sort_elements.each(function(){
+ var sort_element = new hooch.SortElement($(this),sorter)
+ sorter.sort_elements.push(sort_element)
+ })
+ this.row_height = this.sort_elements[0].height;
+ var elem_widths = this.sort_elements.map(function(sort_element,i,arr){return sort_element.width})
+ this.min_elem_width = Math.min.apply(null,elem_widths);
+ this.refreshGrid();
+ if((this.min_elem_width * 2) <= this.width){
+ this.mode = 'Grid'
+ } else {
+ this.mode = 'Vertical'
+ }
+ },
+ refreshGrid: function(){
+ this.rows = {}
+ var sorter = this
+ $.each(this.sort_elements,function(i,sort_element){
+ if(sort_element != sorter.dragging_element){
+ this_element = sort_element
+ } else {
+ this_element = sort_element.placeholder
+ }
+ var elem_top = this_element.getOffset().top;
+ if(!sorter.rows[elem_top]){
+ sorter.rows[elem_top] = []
+ }
+ sorter.rows[elem_top].push(this_element)
+ })
+ this.row_keys = Object.keys(this.rows).map(function(val,i){return parseInt(val)}).sort(sorter.numberSort)
+ $.each(this.rows, function(row_key,row){row.sort(sorter.elementHorizontalSort)})
+ },
+ redrawDraggingElement: function(e){
+ this.dragging_element.setPosition(e);
+ },
+ refreshSequence: function(){
+ var target_location = this.dragging_element.getCenter()
+ var refresh_method = this['refreshSequence' + this.mode]
+ refresh_method.call(this, target_location)
+ },
+ refreshSequenceGrid: function(target_location){
+ var dragging_element = this.dragging_element
+ if(!this.withinCurrentRow(target_location.y)){
+ this.seekCurrentRow(target_location)
+ }
+ if('end' == this.current_row_key){
+ var last_element = this.getLastElement();
+ if(!last_element.is_placeholder){
+ last_element.$sort_element.after(dragging_element.placeholder.$sort_element)
+ this.refreshGrid()
+ }
+ } else if('begin' == this.current_row_key){
+ var first_element = this.getFirstElement();
+ if(!first_element.is_placeholder){
+ first_element.$sort_element.before(dragging_element.placeholder.$sort_element)
+ this.refreshGrid()
+ }
+ } else {
+ var hovered_element = this.getHoveredElementHorizontal(target_location);
+ if(hovered_element){
+ if('leftmost' == hovered_element){
+ var leftmost_element = this.current_row[0]
+ leftmost_element.$sort_element.before(dragging_element.placeholder.$sort_element)
+ this.refreshGrid()
+ } else {
+ hovered_element.$sort_element.after(dragging_element.placeholder.$sort_element);
+ this.refreshGrid()
+ }
+ }
+ }
+ },
+ refreshSequenceVertical: function(target_location){
+ var dragging_element = this.dragging_element
+ var hovered_element = this.getHoveredElementVertical(target_location)
+
+ if(hovered_element){
+ if('first' == hovered_element){
+ var first_key = this.row_keys[0]
+ var first_element = this.rows[first_key][0]
+ first_element.$sort_element.before(dragging_element.placeholder.$sort_element)
+ this.refreshGrid()
+ } else {
+ hovered_element.$sort_element.after(dragging_element.placeholder.$sort_element)
+ this.refreshGrid()
+ }
+ }
+ },
+ rowAfter: function(row){
+ return this.row_keys[this.row_keys.indexOf[row] + 1]
+ },
+ elemAfter: function(row, elem){
+ return row[row.indexOf(elem) + 1]
+ },
+ seekCurrentRow: function(target_location){
+ var sorter = this
+ var row_key = $.grep(this.row_keys,function(rowY,i){
+ var nextRowY = sorter.rowAfter(rowY)
+ var below_top_edge = target_location.y >= rowY
+ if(nextRowY){
+ var above_bottom_edge = target_location.y < nextRowY
+ } else {
+ var above_bottom_edge = target_location.y < (rowY + sorter.row_height)
+ }
+ return (below_top_edge && above_bottom_edge)
+ })[0]
+ if(row_key){
+ this.current_row_key = row_key;
+ this.current_row = this.rows[row_key];
+ } else if(target_location.y > this.rows[Math.max.apply(null,this.row_keys)][0].getOffset().top) {
+ this.current_row_key = 'end';
+ this.current_row = undefined;
+ } else {
+ this.current_row_key = 'begin';
+ this.current_row = undefined;
+ }
+ },
+ getHoveredElementHorizontal: function(target_location){
+ var current_element = false;
+ var sorter = this
+ current_element = $.grep(this.current_row, function(sort_element,i){
+ if(!sort_element.is_placeholder){
+ var elem_center = sort_element.getCenter();
+ var slot_left = elem_center.x;
+ var past_left_edge = target_location.x >= slot_left
+
+ var next_elem = sorter.elemAfter(sorter.current_row, sort_element)
+ var before_right_edge
+ if(next_elem){
+ if(!next_elem.is_placeholder){
+ var next_elem_center = next_elem.getCenter();
+ before_right_edge = target_location.x < next_elem_center.x
+ }
+ } else {
+ before_right_edge = past_left_edge
+ }
+ return (past_left_edge && before_right_edge)
+ }
+ return false
+ })[0]
+ if(current_element){
+ return current_element
+ } else {
+ var first_elem = this.current_row[0]
+ if(first_elem && !first_elem.is_placeholder && first_elem.getCenter().x > target_location.x){
+ return 'leftmost'
+ }
+ }
+ },
+ getHoveredElementVertical: function(target_location){
+ var sorter = this
+ current_element_key = $.grep(sorter.row_keys, function(row_key,i){
+ var this_elem = sorter.rows[row_key][0]
+ if(!this_elem.is_placeholder){
+ var elem_center = this_elem.getCenter()
+ var slot_top = elem_center.y
+ var below_top_edge = target_location.y >= slot_top
+ var next_row = sorter.rows[sorter.row_keys[i+1]]
+ var above_bottom_edge
+ var next_elem
+ if(next_row){
+ next_elem = next_row[0]
+ if(next_elem && !next_elem.is_placeholder){
+ var next_elem_center = next_elem.getCenter()
+ above_bottom_edge = target_location.y < next_elem_center.y
+ }
+ }
+ if(!next_elem){
+ above_bottom_edge = below_top_edge
+ }
+ return(below_top_edge && above_bottom_edge)
+ }
+ return false
+ })[0]
+ if(current_element_key){
+ return this.rows[current_element_key][0]
+ } else {
+ var first_key = this.row_keys[0]
+ var first_elem = this.rows[first_key][0]
+ if(first_elem && !first_elem.is_placeholder && first_elem.getCenter().y > target_location.y){
+ return 'first'
+ }
+ }
+ },
+ getLastElement: function(){
+ var last_row_key = this.row_keys[this.row_keys.length-1]
+ var last_row = this.rows[last_row_key];
+ return last_row[last_row.length-1]
+ },
+ getFirstElement: function(){
+ var first_row_key = this.row_keys[0]
+ var first_row = this.rows[first_row_key]
+ return first_row[0]
+ },
+ elementHorizontalSort: function(a,b){
+ if(a.getOffset().left < b.getOffset().left){
+ return -1
+ }
+ if(b.getOffset().left < a.getOffset().left){
+ return 1
+ }
+ return 0
+ },
+ numberSort: function(a,b){
+ if(parseInt(a) < parseInt(b)){return -1}
+ if(parseInt(b) < parseInt(a)){return 1}
+ return 0
+ },
+ withinCurrentRow: function(y_value){
+ if(this.current_row_key){
+ var top_edge = this.current_row_key
+ var bottom_edge = top_edge + this.row_height;
+ var in_current_row = (top_edge < y_value) && (y_value < bottom_edge)
+ if(in_current_row){
+ this.current_row = this.rows[this.current_row_key]
+ }
+ return in_current_row
+ }
+ return false
+ },
+ setDraggingElement: function(sort_element){
+ this.dragging_element = sort_element;
+ var current_row = this.rows[this.dragging_element.starting_offset.top]
+ drag_index = current_row.indexOf(sort_element)
+ if(drag_index > -1){
+ current_row.splice(drag_index, 1)
+ }
+ current_row.push(this.dragging_element.placeholder)
+ this.refreshGrid();
+ },
+ clearDraggingElement: function(){
+ if(this.dragging_element){
+ this.removeDraggingElement()
+ }
+ },
+ onMouseup: function(){
+ this.removeDraggingElement()
+ this.sendSort()
+ },
+ removeDraggingElement: function(){
+ if(this.dragging_element){
+ var placeholder_row = this.removePlaceholder()
+ this.rows[placeholder_row].push(this.dragging_element)
+ this.dragging_element.drop()
+ this.dragging_element = undefined;
+ this.refreshGrid();
+ }
+ },
+ sendSort: function(){
+ $.ajax({
+ url: this.$sorter.attr('href'),
+ method: 'PATCH',
+ data: this.getFormData()
+ })
+ },
+ getFormData: function(){
+ var id_array = $.map(this.$sorter.children(),function(e,i){return $(e).attr('id')})
+ var first_id = id_array[0]
+ var last_underscore_location = first_id.lastIndexOf('_')
+ var array_name = first_id.slice(0,last_underscore_location)
+ var form_data = {}
+ form_data[array_name] = id_array.map(function(id){
+ return id.slice((last_underscore_location + 1))
+ })
+ return form_data
+ },
+ removePlaceholder: function(){
+ var sorter = this
+ return $.grep(this.row_keys, function(row_key,i){
+ var placeholder_index = sorter.rows[row_key].indexOf(sorter.dragging_element.placeholder)
+ if(placeholder_index > -1){
+ sorter.rows[row_key].slice(placeholder_index,1)
+ return true
+ }
+ return false
+ })[0]
+ }
+ }),
+ SortElement: Class.extend({
+ init: function($sort_element,sorter){
+ this.sorter = sorter;
+ this.$sort_element = $sort_element;
+ this.old_position = $sort_element.css('position')
+ this.width = this.$sort_element.width()
+ this.height = this.$sort_element.height()
+ var sort_element = this
+ this.$sort_element.on('dragstart', function(e){
+ hooch.pauseEvent(e)
+ return false
+ })
+ this.$sort_element.on('mousedown', $.proxy(sort_element.onMousedown, sort_element))
+ },
+ onMousedown: function(e){
+ if(1 == e.which){
+ this.sorter.clearDraggingElement();
+ hooch.pauseEvent(e)
+ this.starting_offset = this.getOffset();
+ this.mouse_start = {top: e.originalEvent.pageY, left: e.originalEvent.pageX}
+ this.placeholder = new hooch.SortPlaceholder(this.$sort_element.clone().removeAttr('id').css({width: this.width, height: this.height}),this.sorter)
+ this.placeholder.css({'visibility': 'hidden'});
+ this.placeholder.css({background: 'none', 'background-color': 'pink'});
+ $tmp = $('<div style="display: none;"></div>')
+ this.$sort_element.before($tmp)
+ this.$sort_element
+ .css({position: 'absolute', top: this.starting_offset.top, left: this.starting_offset.left})
+ .appendTo('body')
+ $tmp.replaceWith(this.placeholder.$sort_element)
+ this.sorter.setDraggingElement(this,e);
+ return false;
+ }
+ },
+ drop: function(){
+ this.css({position: this.old_position, top: '', left: ''})
+ this.placeholder.replaceWith(this.$sort_element);
+ this.placeholder = undefined
+ },
+ getOffset: function(){
+ return this.$sort_element.offset();
+ },
+ setPosition: function(e){
+ var delta = this.getDelta(e)
+ var new_position = this.getNewPosition(delta);
+ this.$sort_element.css(new_position);
+ },
+ getDelta: function(e){
+ return {
+ top: (e.originalEvent.pageY - this.mouse_start.top),
+ left: (e.originalEvent.pageX - this.mouse_start.left)
+ }
+ },
+ getNewPosition: function(delta){
+ return {top: (this.starting_offset.top + delta.top), left: (this.starting_offset.left + delta.left)}
+ },
+ getCenter: function(){
+ var new_offset = this.getOffset()
+ var newX = new_offset.left
+ var newY = new_offset.top
+ var width = this.width
+ var height = this.height
+ var centerX = newX + (width / 2)
+ var centerY = newY + (height / 2)
+ var center = {x: centerX, y: centerY}
+ return center
+ },
+ clone: function(){
+ return this.$sort_element.clone();
+ },
+ css: function(css_obj){
+ this.$sort_element.css(css_obj);
+ },
+ replaceWith: function($jq_obj){
+ this.$sort_element.replaceWith($jq_obj)
+ }
})
};
+ hooch.SortPlaceholder = hooch.SortElement.extend({
+ init: function($sort_element,sorter){
+ this.sorter = sorter;
+ this.is_placeholder = true;
+ this.$sort_element = $sort_element;
+ this.width = this.$sort_element.width()
+ this.height = this.$sort_element.height()
+ }
+ })
hooch.AjaxExpandable = hooch.Expandable.extend({
expand: function(){
if(!this.ajax_loaded){
this.ajax_loaded = true;
new thin_man.AjaxLinkSubmission(this.$expander);
@@ -701,12 +1088,19 @@
'expand-state' : 'Expandable', 'prevent-double-click' : 'PreventDoubleLinkClick'
},'hooch');
window.any_time_manager.registerList(
['hover_overflow','hidey_button','submit-proxy','click-proxy','field-filler','revealer',
'checkbox-hidden-proxy','prevent-double-submit','prevent-double-link-click', 'tab-group',
- 'hover-reveal', 'emptier', 'remover', 'checkbox-proxy', 'fake-select', 'select-action-changer'],'hooch');
+ 'hover-reveal', 'emptier', 'remover', 'checkbox-proxy', 'fake-select', 'select-action-changer',
+ 'sorter'],'hooch');
window.any_time_manager.load();
};
+ hooch.pauseEvent = function(e){
+ if(e.stopPropagation) e.stopPropagation();
+ if(e.preventDefault) e.preventDefault();
+ e.cancelBubble=true;
+ e.returnValue=false;
+ }
$(document).ready(function(){
if(typeof window.any_time_manager === "undefined" && typeof window.loading_any_time_manager === "undefined"){
window.loading_any_time_manager = true;
$.getScript("https://cdn.rawgit.com/edraut/anytime_manager/9f710d2280e68ea6156551728cb7e2d537a06ee6/anytime_manager.js",function(){
window.loading_any_time_manager = false