Here is a complete working example: http://jsfiddle.net/fasE5/19/
In HTML, I came up with:
<div id="sortable" class="isOnlyTwo"> <div class="destination"> <span class="handle">A</span> <input type="text" name="dest1" value="" /> <a href="#" class="remove_input">×</a> </div> <div class="destination"> <span class="handle">B</span> <input type="text" name="dest2" value="" /> <a href="#" class="remove_input">×</a> </div> </div> <a href="#" id="add_input">Add Destination</a>
And CSS to make it look a little prettier:
#add_input { text-decoration:none; color:#15C; margin-left:35px; } #add_input:hover { text-decoration:underline; } .placeholder { border:2px dashed #bfbfbf; margin:5px; width:240px; } .handle { background-color:#06B500; border:2px solid #3D7311; cursor:n-resize; padding:0 3px; border-radius:99px; font-size:12px; } .destination { margin:5px 15px; } .destination input { border:1px solid #B9B9B9; width:200px; } #sortable.isOnlyTwo .remove_input { display:none; } .remove_input { color:#999; text-decoration:none; font-weight:bold; } .remove_input:hover { color:#666; } .destination.ui-sortable-helper { opacity:0.8; filter:alpha(opacity=80); } .destination.ui-sortable-helper .remove_input { display:none; }
To preserve the correct order of the input name attribute and the order letter (A, B, C ...), we call RecalculateOrder when updating the sort and when deleting the destination.
In order not to delete the last 2 destinations, we add the isOnlyTwo class to the isOnlyTwo div when only 2 destinaitons remain. Thanks to our CSS hides remove_input .
For autocompletion, we need the GoogleMaps API
<script src="//maps.googleapis.com/maps/api/js?sensor=false&libraries=places" type="text/javascript"></script>
Which gives us new google.maps.places.Autocomplete(input) to add Google autocomplete functionality.
$(function(){ $("#sortable").sortable({ containment: "document", placeholder: 'placeholder', handle: ".handle", axis: "y", update: RecalculateOrder, forcePlaceholderSize: true }); $("#add_input").click(function () { var inputIndex = $("#sortable > .destination").length; // Building the new field HTML var html = '<div class="destination">'; html += '<span class="handle">' + String.fromCharCode(inputIndex + 65) + '</span> '; html += '<input type="text" name="dest' + (inputIndex + 1) + '" value="" /> '; html += '<a href="#" class="remove_input">×</a>'; html += '</div>'; var newField = $(html); newField .find(".remove_input").click(RemoveInput); $("#sortable").append(newField ).removeClass("isOnlyTwo"); // Adding autocomplete to the new field BindAutoComplete(newField.find("input")[0]); return false; }); $(".remove_input").click(RemoveInput); // Adding autocomplete to the first two fields $("#sortable input").each(function(){ BindAutoComplete(this); }); function RemoveInput() { $(this).parent().remove(); RecalculateOrder(); var isOnlyTwo = $("#sortable > .destination").length == 2; $("#sortable").toggleClass("isOnlyTwo", isOnlyTwo); return false; } // Recalculating from scratch the fields order function RecalculateOrder() { $("#sortable .handle").text(function(i) { return String.fromCharCode(i + 65); }); $("#sortable input").attr("name", function(i){ return "dest" + (i + 1); }); } function BindAutoComplete(input) { var autocomplete = new google.maps.places.Autocomplete(input); } });
Oleg Grishko
source share