Add map location in customer address

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
6 years ago
Dear All,

I am happy to use the application. but i am facing a requirement now.
We need to add a map location to the address of the customer so we can deliver the order to it.
The customer select a location from the map beside the address and save the order. then while shipping the product the location used to be sure the product arrive to the correct place.
Do we have this functionality? do we have a plugin can do that?
6 years ago
mohamed.so3odi wrote:
Dear All,

I am happy to use the application. but i am facing a requirement now.
We need to add a map location to the address of the customer so we can deliver the order to it.
The customer select a location from the map beside the address and save the order. then while shipping the product the location used to be sure the product arrive to the correct place.
Do we have this functionality? do we have a plugin can do that?



Default nop has this function ===>Go http://admin-demo.nopcommerce.com/Admin/Order/Edit/5

And see the "Shipping info" tab


If it is not perfect for you then you will need customize, You can PM me.
5 years ago
The answer is for the admin area not in customer's order checkout page !!

I was searching for the same request .. but the answer is only for admin area, and it gives google map the address text to search for not a location a user had submitted through google map  


Is there any tutorial on how to add a map in checkout page so that the customer select his address directly on the map without writing it ?
5 years ago
I don't think it would be a useful feature. Let me show a typical shipping address our customers fill in:

John Doe, Financial Department, Monster Corporation, Room 57, 5th Floor, 26 Swanson street, Sampleville, Zip: 54114
Important delivery note: The courier Please text or call me before delivery if it is before noon, but I am out of office in the afternoons, so in case of delivery after 12pm, please leave the package at the concierge attaching a note to call me at 5114 extension the next morning.

An interactive map would help to fill out only 5% of this but in 20x time.
5 years ago
libor wrote:
I don't think it would be a useful feature. Let me show a typical shipping address our customers fill in:

John Doe, Financial Department, Monster Corporation, Room 57, 5th Floor, 26 Swanson street, Sampleville, Zip: 54114
Important delivery note: The courier Please text or call me before delivery if it is before noon, but I am out of office in the afternoons, so in case of delivery after 12pm, please leave the package at the concierge attaching a note to call me at 5114 extension the next morning.

An interactive map would help to fill out only 5% of this but in 20x time.


Thank you for your reply.

Making orders means there are different ways to deliver a product or products. There are many scenarios not only one like you have mentioned.  
A store for food products for example is in need for direct delivery to people who may not knowing there exact address, so why not to use a great and free feature provided by google to let users easily put their location instead of writing it.

Another scenario is when you are at work and want to order some products for your wife or your parent's house and you do not necessarily keeping the exact address in your mind.

The feature is not useful for you but maybe it is very useful for a lot of people. And I think it is not that difficult for those great developers who shared in this great open source project .
5 years ago
You are right, I admit, that as a selectable option this would not harm anybody.

Let me add a thought: I can also imagine a company that would do drone deliveries direct to backyards, (there are already such trials underway in some countries), And having exact GPS coordinates (e.g of a clear landing zone in the backyard) would be such a benefit only a map based shipping location entry could offer.
5 years ago
I was able to add google map in order checkout page "onepagecheckout" by some steps, through which we will change and add code in some views in the theme directory, and adding "Address custom attributes" through the control panel, but these steps do not serve as a general solution for all types of stores. It is suitable only for stores in need of direct delivery process. And also I had one problem that it is not working in "Shipping Address" step, it works only in "Billing" step.

What I have done is the following:

1- Adding "Latitude" & "Longitude" attributes in "/Admin/Setting/CustomerUser" in "Address form fields" tab
2- Setting these attributes type as text boxes and making them not required.
3- Adding map content to the view located in theme folder : "Themes/.../Views/Shared/_AddressAttributes.cshtml", if it is not found in the folder simply copy it from the root project views folder:

@model IList<Nop.Web.Models.Common.AddressAttributemodel>
    @using Nop.Core.Domain.Catalog;
    @*changes1*@
    @{
        string GoogleMapsApiKey = "YourAPIKeyhere";
        string latStr = "";
        string lngStr = "";
    }
    <style>.pickup-points-map {min-width: 500px;height: 500px;margin: 20px;padding: 10px;border: 1px solid #d0d0d0;}</style>
    @*end changes1*@

    @foreach (var attribute in Model)
    {
        string controlId = string.Format("address_attribute_{0}", attribute.Id);
        string textPrompt = attribute.Name;

        @*changes2*@
        if (textPrompt.ToLower() == "latitude")
        {
            latStr = attribute.DefaultValue;
        }
        if (textPrompt.ToLower() == "longitude")
        {
            lngStr = attribute.DefaultValue;
        }
        @*end changes2*@

        <div class="inputs custom-attributes">
            <label>@textPrompt:</label>

            @switch (attribute.AttributeControlType)
            {
                case AttributeControlType.DropdownList:
                    {
                        <select name="@(controlId)" id="@(controlId)">
                            @if (!attribute.IsRequired)
                            {
                                <option value="0">---</option>
                            }
                            @foreach (var attributeValue in attribute.Values)
                            {
                                <option selected="@attributeValue.IsPreSelected" value="@attributeValue.Id">@attributeValue.Name</option>
                            }
                        </select>
                    }
                    break;
                case AttributeControlType.RadioList:
                    {
                        <ul class="option-list">
                            @foreach (var attributeValue in attribute.Values)
                            {
                                <li>
                                    <input id="@(controlId)_@(attributeValue.Id)" type="radio" name="@(controlId)" value="@attributeValue.Id" checked="@attributeValue.IsPreSelected" />
                                    <label for="@(controlId)_@(attributeValue.Id)">@attributeValue.Name</label>
                                </li>
                            }
                        </ul>
                    }
                    break;
                case AttributeControlType.Checkboxes:
                case AttributeControlType.ReadonlyCheckboxes:
                    {
                        <ul class="option-list">
                            @foreach (var attributeValue in attribute.Values)
                            {
                                <li>
                                    <input id="@(controlId)_@(attributeValue.Id)" type="checkbox" name="@(controlId)" value="@attributeValue.Id" checked="@attributeValue.IsPreSelected" @(attribute.AttributeControlType == AttributeControlType.ReadonlyCheckboxes ? Html.Raw(" disabled=\"disabled\"") : null) />
                                    <label for="@(controlId)_@(attributeValue.Id)">@attributeValue.Name</label>
                                </li>
                            }
                        </ul>
                    }
                    break;
                case AttributeControlType.TextBox:
                    {
                        <input name="@(controlId)" type="text" class="textbox" id="@(controlId)" value="@attribute.DefaultValue" />
                    }
                    break;
                case AttributeControlType.MultilineTextbox:
                    {
                        <textarea id="@(controlId)" name="@(controlId)">@attribute.DefaultValue</textarea>
                    }
                    break;
                case AttributeControlType.Datepicker:
                case AttributeControlType.FileUpload:
                case AttributeControlType.ColorSquares:
                case AttributeControlType.ImageSquares:
                    {
                        //not support attribute type
                    }
                    break;
            }
            @if (attribute.IsRequired)
            {
                @Html.RequiredHint()
            }
        </div>
    }
    @*changes3*@
    @{
        double InitLat = 48.864716;
        double InitLng = 2.349014;

        double lat = 0;
        double lng = 0;

        double.TryParse(latStr, out lat);
        double.TryParse(lngStr, out lng);

        if (lat == 0 || lng == 0)
        {
            lat = InitLat; lng = InitLng;
        }


        var src = string.Format("https://maps.googleapis.com/maps/api/js{0}", string.IsNullOrEmpty(GoogleMapsApiKey) ? string.Empty : string.Format("?key={0}", GoogleMapsApiKey));
        <div class="pickup-points-map" id="map">
            <script type="text/javascript">
                $(document).ready(function () {
                    if (typeof google === 'object' && typeof google.maps === 'object') {
                        gmapInit();
                    } else {
                        $.getScript("@src", function (data, textStatus, jqxhr){
                            gmapInit();
                        });
                    }
                });
                function gmapInit(){

                    var markersA = new Map();
                    var googleMap = null;
                  
                        google.maps.visualRefresh = true;
                        googleMap = new google.maps.Map(document.getElementById("map"), {
                            zoom: 15,
                            mapTypeId: google.maps.MapTypeId.ROADMAP
                        });
                        var geocoder = new google.maps.Geocoder();
                        //var infowindow = new google.maps.InfoWindow();
                        @if(lat>0 && lng>0)
                                {
                            <text>
                        (function() {

                            var marker = new google.maps.Marker({
                                map: googleMap,
                                title: "Address",
                                draggable: true,
                                position: new google.maps.LatLng(@lat, @lng),
                                icon: "http://maps.google.com/mapfiles/ms/icons/blue-dot.png"
                            });
                            markersA.set("asdasdas", marker);

                            google.maps.event.addListener(marker, 'dragend', function () {
                                $("#address_attribute_1").val(this.getPosition().lat());
                                $("#address_attribute_2").val(this.getPosition().lng());
                            });

                            google.maps.event.addListener(googleMap, 'click', function (event) {
                                placeMarker(event.latLng);
                            });

                            function placeMarker(location) {
                                marker.setPosition(location);
// if we could rename the two text boxes attributes we added in admin area
// as address_attribute_lat & address_attribute it would be better
                                $("#address_attribute_1").val(marker.getPosition().lat());
                                $("#address_attribute_2").val(marker.getPosition().lng());
                            }
                            googleMap.setCenter(marker.getPosition())

                        }());
                        </text>
                       }
                }
            </script>
        </div>
    }
    @*end changes3*@

4- By this we can read the latitude and longitude that the customer selected through the map and can see it in the order details in admin area. You can use the data and create map link like in the shipping info in the order details page in admin area

This is my solution to add the map to the client's address, but I'm sure there are better solutions that can be provided by more experienced developers. I would be grateful if there was a solution to the problem I mentioned above or giving us a better solution than this solution.

P.S.: I used the map code from shipping view provided by nopcommerce team.
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.