Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting and adding inputs like Google - Get directions

I'm trying to do dynamic sortable list with link "Add Destination" such as Google - Get directions screenshot below. Big problem is that in sorted inputs sequence IDs should be maintained and the contents changed after draging. Input is able to drag before "A" and last, remove by "x" right field. Adding additional waypoints, judging by this: directions-waypoints tutorial should be get as array in JavaScript, waypoints is always middle "A" and last fields, input point "A" always name eg. "from", last "goal". I would like to do latter fields filling by autosuggestion from Google places. I was looking everywhere for some solution but its is too different.

EDIT: I collected everything from different sources end I got in result not quite good code: jsfiddle.net/fasE5/5/

http://maps.google.com/maps?hl=en&tab=wl

like image 480
leon Avatar asked Nov 09 '11 21:11

leon


1 Answers

Here is a complete working example: http://jsfiddle.net/fasE5/19/

The 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">&times;</a>
     </div>
    <div class="destination">
        <span class="handle">B</span>
        <input type="text" name="dest2" value="" />
        <a href="#" class="remove_input">&times;</a>
     </div>
</div>
<a href="#" id="add_input">Add Destination</a>

And the CSS, to make it look a little more pretty:

#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 keep the right order of the input's name attribute and the order letters (A, B, C...), we call to RecalculateOrder on sort update and when removing an destination.

To prevent from removing the last 2 destinations, we add an isOnlyTwo class to the #sortable div when there is only 2 destinaitons left. Which thanks to our CSS hides the remove_input.

For the autocomplete we need GoogleMaps API

<script src="//maps.googleapis.com/maps/api/js?sensor=false&libraries=places" type="text/javascript"></script>

Which provides us an new google.maps.places.Autocomplete(input) to add google's 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's 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">&times;</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);
    }
});
like image 137
Oleg Grishko Avatar answered Oct 08 '22 07:10

Oleg Grishko