From 043693507c3e7c2c6cef2b9864f56c8c561292d9 Mon Sep 17 00:00:00 2001 From: Vinicius Depizzol Date: Sun, 12 Jun 2011 02:14:19 -0300 Subject: [PATCH] fix drag and drop mode when doing single click, items were wrongly moving. Added timeout to discover when allow drag&drop mode. Also, made facebook style a bit smaller and add initial support for drag&drop visual feedback --- src/jquery.tokeninput.js | 165 +++++++++++++++++++++----------- styles/token-input-facebook.css | 24 +++-- styles/token-input.css | 14 ++- 3 files changed, 138 insertions(+), 65 deletions(-) diff --git a/src/jquery.tokeninput.js b/src/jquery.tokeninput.js index 47c8bc4d..7d5b7527 100644 --- a/src/jquery.tokeninput.js +++ b/src/jquery.tokeninput.js @@ -48,6 +48,7 @@ var DEFAULT_CLASSES = { tokenDelete: "token-input-delete-token", selectedToken: "token-input-selected-token", highlightedToken: "token-input-highlighted-token", + draggedToken: "token-input-dragged-token", dropdown: "token-input-dropdown", dropdownItem: "token-input-dropdown-item", dropdownItem2: "token-input-dropdown-item2", @@ -407,6 +408,8 @@ $.TokenList = function (input, url_or_data_or_function, settings) { // True during dragging process var dragging = false; + var dragTimeout; + // the dragged Token var dragToken; @@ -580,78 +583,126 @@ $.TokenList = function (input, url_or_data_or_function, settings) { // Drag and Drop Functionality // function addDragFunctionality(token) { - token.bind('mousedown',function(){ - var token = $(this) - dragToken = token; - token.addClass(settings.classes.selectedToken); - dragging= true; - $(document).one('mouseup',function(){ - token.removeClass(settings.classes.selectedToken); - dragging=false; - move_token(token, dragDestination); - reindex_results(); + token.bind('mousedown', function() { + var token = $(this); + + dragToken = token; + + dragTimeout = window.setTimeout(function() { + var previous_selected_token = selected_token; + + if(selected_token == token) { + return; + } + + if(selected_token) { + deselect_token($(selected_token), POSITION.END); + } + + select_token(token); + + $(token).clone().appendTo('body').addClass(settings.classes.draggedToken); + + dragging = true; + + }, 200); + + $(document).one('mouseup', function() { + + window.clearTimeout(dragTimeout); + + if(dragging != true) { + return; + } + + $('li.'+settings.classes.draggedToken).remove(); + + if(selected_token) { + deselect_token($(selected_token), POSITION.END); + } + + dragging = false; + + if(dragDestination) { + move_token(token, dragDestination); + reindex_results(); + } + }); + + return false; + }) + .bind('mouseover', function() { + + if(!dragging) return; + + dragDestination = $(this); + + if(is_after(dragToken, dragDestination)) { + dragDestination.addClass(settings.classes.insertAfter); + } else { + dragDestination.addClass(settings.classes.insertBefore); + } + }) + .bind('mouseout', function() { + + if(!dragging) return; + + $(this).removeClass(settings.classes.insertBefore); + $(this).removeClass(settings.classes.insertAfter); + }). + bind('mouseup', function(){ + $(this).removeClass(settings.classes.insertBefore); + $(this).removeClass(settings.classes.insertAfter); + }); + + $('body').mousemove(function(e) { + if(!dragging) return; + + $('li.'+settings.classes.draggedToken).css({'top': e.pageY, 'left': e.pageX}); }); - return false; - }) - .bind('mouseover',function(){ - if(!dragging) return; - dragDestination = $(this); - if(is_after(dragToken, dragDestination)) { - dragDestination.addClass(settings.classes.insertAfter); - } else { - dragDestination.addClass(settings.classes.insertBefore); - }; - }).bind('mouseout', function(){ - if(!dragging) return; - $(this).removeClass(settings.classes.insertBefore); - $(this).removeClass(settings.classes.insertAfter); - }).bind('mouseup', function(){ - $(this).removeClass(settings.classes.insertBefore); - $(this).removeClass(settings.classes.insertAfter); - }); } function move_token(token, destinationToken) { - if(token.get(0) == destinationToken.get(0)) return; - - if(is_after(token, destinationToken)) { - token.insertAfter(destinationToken); - } else { - token.insertBefore(destinationToken); - } - - + if(!destinationToken || token.get(0) == destinationToken.get(0)) return; + + if(is_after(token, destinationToken)) { + token.insertAfter(destinationToken); + } else { + token.insertBefore(destinationToken); + } } function is_after(first, last) { - index_tokens(); - first = $.data(first.get(0), "tokeninput") - last = $.data(last.get(0), "tokeninput") - return last.index > first.index + index_tokens(); + first = $.data(first.get(0), "tokeninput"); + last = $.data(last.get(0), "tokeninput"); + return last.index > first.index } function index_tokens() { - var i = 0; - token_list.find('li').each(function(){ - var data = $.data(this, "tokeninput"); - if(data){ data.index = i; } - i++; - }); + var i = 0; + token_list.find('li').each(function() { + var data = $.data(this, "tokeninput"); + if(data) { + data.index = i; + } + i++; + }); } function reindex_results() { - var ids = [], tokens = []; - token_list.find('li').each(function(){ - var data = $.data(this, "tokeninput"); - if(data){ - ids.push(data.id); - tokens.push(data); - }; - }); - saved_tokens = tokens; - update_hidden_input(); + var ids = [], tokens = []; + token_list.find('li').each(function() { + var data = $.data(this, "tokeninput"); + if(data) { + ids.push(data.id); + tokens.push(data); + }; + }); + saved_tokens = tokens; + update_hidden_input(); } diff --git a/styles/token-input-facebook.css b/styles/token-input-facebook.css index 7fcc826b..da29d283 100644 --- a/styles/token-input-facebook.css +++ b/styles/token-input-facebook.css @@ -12,7 +12,7 @@ ul.token-input-list-facebook { line-height: 15px; z-index: 999; margin: 0; - padding: 2px 0; + padding: 1px 0; background-color: #fff; list-style-type: none; clear: left; @@ -21,9 +21,9 @@ ul.token-input-list-facebook { ul.token-input-list-facebook li input { border: 0; width: 100px; - padding: 2px 3px; + padding: 1px 3px; background-color: white; - margin: 2px 0; + margin: 1px 0; font: inherit; -webkit-appearance: caret; } @@ -32,7 +32,7 @@ li.token-input-token-facebook { overflow: hidden; height: auto !important; height: 15px; - margin: 2px 0 2px 4px; + margin: 1px 0 1px 2px; padding: 1px 1px 1px 3px; background-color: #eff2f7; color: #000; @@ -86,13 +86,25 @@ li.token-input-input-token-facebook { padding: 1px; list-style-type: none; } +li.token-input-dragged-token-facebook { + opacity: 0.7; + position: absolute; + margin: 5px 0 0 5px; + padding: 2px 6px; + list-style: none; + font-size: 11px; + font-family: Verdana; +} +li.token-input-dragged-token-facebook span { + display: none; +} li.token-input-insert-before-facebook { - border-left: 1px solid red; + border-left: 1px solid red; } li.token-input-insert-after-facebook { - border-right: 1px solid red; + border-right: 1px solid red; } div.token-input-dropdown-facebook { diff --git a/styles/token-input.css b/styles/token-input.css index a11f7811..79090613 100644 --- a/styles/token-input.css +++ b/styles/token-input.css @@ -61,13 +61,23 @@ li.token-input-selected-token { li.token-input-selected-token span { color: #bbb; } +li.token-input-dragged-token { + opacity: 0.5; + position: absolute; + margin: 5px 0 0 5px; + font-size: 12px; + font-family: Verdana; +} +li.token-input-dragged-token span { + display: none; +} li.token-input-insert-before { - border-top: 1px solid red; + border-top: 1px solid red; } li.token-input-insert-after { - border-bottom: 1px solid red; + border-bottom: 1px solid red; } div.token-input-dropdown {