views:

208

answers:

2

I'm implementing the MS NerdDinner app in ASP.NET MVC 2 and I'm using google maps instead of MS maps. I use sample code from the google site for the maps. I have 2 very simple views, Create.aspx and and Edit.aspx in the same directory, which create and edit dinners respectively. They are very simple - they both render a partial view named Dinner.ascx which is also in the same directory.

The Dinner form includes 3 js files and also renders another partial form which displays the google map. I have 2 problems:

  1. The dinner form when rendered from the Edit view isn't finding the Javascript files and is completely falling over, whereas when it's called from the Create view is seeing the Javascript files and is working up to a point. The url for create is http://localhost/NerdDinner/Dinners/Create and Edit is http://localhost/NerdDinner/Dinners/Edit/39. Why are the JS files not being found from the Edit view, even though both views are rendering the same partial view?

  2. In Firefox (ver 3.6.8) the Create page only works sometimes, it's very inconsistent. Usually after refreshing a few times or going away from and coming back to the page it will eventually work, whereas in IE 8 it works all the time. Why is FF inconsistent like this?

The solution directory structure is:

NerdDinner (root)
Controllers
- HomeController.cs
- DinnersController.cs
- etc
Models
Scripts
- CurrentJS.js
- MainJS.js
- jQuery-1.4.1.js
- etc
Views
- Account
- Dinners
- - Create.aspx
- - Edit.aspx
- - DinnerForm.ascx
- - GoogleMap2.ascx
- - etc
- Home
- Shared

I've been beating my head against the wall for 2 days with this, can't see the wood for the trees anymore. Code below (apologies if it's a bit verbose):

Create.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Controllers.DinnerFormViewModel>" %>
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Host a Dinner
</asp:Content>
<asp:Content ID="Create" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Host a Dinner</h2>
    <% Html.RenderPartial("DinnerForm"); %>
</asp:Content>

Edit.aspx:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<NerdDinner.Controllers.DinnerFormViewModel>" %>
<asp:Content ID="Title" ContentPlaceHolderID="TitleContent" runat="server">
    Edit:
    <%=Html.Encode(Model.Dinner.Title) %>
</asp:Content>
<asp:Content ID="Edit" ContentPlaceHolderID="MainContent" runat="server">
    <h2>
        Edit Dinner</h2>
    <% Html.RenderPartial("DinnerForm"); %>   
</asp:Content>

DinnerForm.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<NerdDinner.Controllers.DinnerFormViewModel>" %>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"&gt;&lt;/script&gt;
<script type="text/javascript" src="../Scripts/MainJS.js"></script>
<script type="text/javascript" src="../Scripts/CurrentJS.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $("#Address").blur(function(evt) {
            $("#Latitude").val("");
            $("#Longitude").val("");

            var address = jQuery.trim($("#Address").val());

            alert('address: ' + address);

            if (address.length < 1)
                return;

            codeAddress();
        });
    });
</script>

<%= Html.ValidationSummary("Please correct your errors and try again.") %>
<% using (Html.BeginForm()) { %>
<fieldset>
    <p>
        <label for="Title">
            Dinner Title:</label>
        <%= Html.TextBox("Title", Model.Dinner.Title) %>
        <%=Html.ValidationMessage("Title", "*") %>
    </p>
    <p>
        <label for="EventDate">
            Event Date:</label>
        <%= Html.TextBox("EventDate", Model.Dinner.EventDate) %>
        <%= Html.ValidationMessage("EventDate", "*") %>
    </p>
    <p>
        <label for="Description">
            Description:</label>
        <%= Html.TextArea("Description", Model.Dinner.Description) %>
        <%= Html.ValidationMessage("Description", "*") %>
    </p>
    <p>
        <label for="Address">
            Address:</label>
        <%= Html.TextBox("Address", Model.Dinner.Address) %>
        <%= Html.ValidationMessage("Address", "*") %>
    </p>
    <p>
        <label for="Country">
            Country:</label>
        <%= Html.DropDownList("Country", Model.Countries) %>
        <%= Html.ValidationMessage("Country", "*") %>
    </p>
    <p>
        <label for="ContactPhone">
            Contact Phone #:</label>
        <%= Html.TextBox("ContactPhone", Model.Dinner.ContactPhone) %>
        <%= Html.ValidationMessage("ContactPhone", "*") %>
    </p>
    <p>
        <%= Html.Hidden("Latitude", Model.Dinner.Latitude) %>
    </p>
    <p>
        <%= Html.Hidden("Longitude", Model.Dinner.Longitude) %>
    </p>
    <p>
        <input type="submit" value="Save" />
    </p>
</fieldset>
<div id="mapDiv">
    <%Html.RenderPartial("GoogleMap2", Model.Dinner); %>
</div>
<% } %>

GoogleMap2.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>    
<style type="text/css">
  html { height: 100% }
  body { height: 100%; margin: 0px; padding: 0px }
  #map_canvas { height: 50% }
  #infoPanel {
    float: left;
    margin-left: 10px;
  }
  #infoPanel div {
    margin-bottom: 5px;
  }
</style>
<!-- End add for google map -->

<div id="map_canvas" style="width: 765px; height: 400px;">
</div>

<div id="infoPanel">
    <b>Marker status:</b>
    <div id="markerStatus">
        <i>Click and drag the marker.</i></div>
    <b>Current position:</b>
    <div id="info"></div>
    <b>Closest matching address:</b>
    <div id="address"></div>
</div>

<script type="text/javascript">
    $(document).ready(function() {
        initialize4();
    });
</script>

CurrentJS.js:

//// +++++++++++ Start of attempt to pinpoint location automatically

function initialize4() {
    var myOptions = {
        zoom: 9,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

    // Try W3C Geolocation (Preferred)     
    if (navigator.geolocation) {
        browserSupportFlag = true;
        navigator.geolocation.getCurrentPosition(function(position) {
            initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
            map.setCenter(initialLocation);
        }, function() {
            handleNoGeolocation(browserSupportFlag);
        });
        // Browser doesn't support Geolocation
    } else {
        browserSupportFlag = false;
        handleNoGeolocation(browserSupportFlag);
    }

    if (initialLocation == 'undefined')
        alert('1' + initialLocation);
    else
        alert('2' + initialLocation);

    //Add draggable marker
    var marker = new google.maps.Marker({
        position: initialLocation, //latLng,
        title: 'Point B',
        map: map,
        draggable: true
    });

    // Update current position info.
    updateMarkerPosition(initialLocation);
    geocodePosition(initialLocation);

    // Add dragging event listeners.
    google.maps.event.addListener(marker, 'dragstart', function() {
        updateMarkerAddress('Dragging...');
    });

    google.maps.event.addListener(marker, 'drag', function() {
        updateMarkerStatus('Dragging...');
        updateMarkerPosition(marker.getPosition());
    });

    google.maps.event.addListener(marker, 'dragend', function() {
        updateMarkerStatus('Drag ended');
        geocodePosition(marker.getPosition());
    });

    function handleNoGeolocation(errorFlag) {
        if (errorFlag == true) {
            alert("Geolocation service failed.");
            initialLocation = newyork;
        } else {
            alert("Your browser doesn't support geolocation. We've placed you in newyork.");
            initialLocation = newyork;
        }
        map.setCenter(initialLocation);
    }
}

function geocodePosition(pos) {
    geocoder.geocode({
        latLng: pos
    }, function(responses) {
        if (responses && responses.length > 0) {
            updateMarkerAddress(responses[0].formatted_address);
        } else {
            updateMarkerAddress('Cannot determine address at this location.');
        }
    });
}

function updateMarkerStatus(str) {
    document.getElementById('markerStatus').innerHTML = str;
}

function updateMarkerPosition(latLng) {
    //alert('latLng:' + latLng);
    document.getElementById('info').innerHTML = [
    latLng.lat(),
    latLng.lng()
  ].join(', ');
}

function updateMarkerAddress(str) {
    document.getElementById('address').innerHTML = str;
}

function codeAddress() {
    var address = document.getElementById("address").value;

    alert('In codeAddress');

    geocoder.geocode({ 'address': address }, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            map.setCenter(results[0].geometry.location);
            var marker = new google.maps.Marker({
                map: map,
                position: results[0].geometry.location
            });
        } else {
            alert("Geocode was not successful for the following reason: " + status);
        }
    });
}
//// +++++++++++++ End attempt to pinpoint location automatically    
A: 

Q1: It sounds like its confused about where to find the javascript files.

Rather than

<script type="text/javascript" src="../Scripts/MainJS.js"></script>
<script type="text/javascript" src="../Scripts/CurrentJS.js"></script>

change these to

<script type="text/javascript" src="/Scripts/MainJS.js"></script>
<script type="text/javascript" src="/Scripts/CurrentJS.js"></script>

The relative paths on these lines can be different depending on which view or partial is currently being rendered.

Q2: In Firefox (ver 3.6.8) the Create page only works sometimes - can you explain further - what is displayed when it doesnt work?

Clicktricity
Hi Tim - for Q1 can you rewrite what you had written..seems to be missing some text. For Q2, Firefox frequently won't display the map on the web page, just an empty div area. I make a call to navigator.geolocation.getCurrentPosition whick should return data with latitude and longitude positions. This is undefined any time the map doesn't display. In IE it always returns 2 values.
Ciaran Bruen
A: 

I fixed the js problems by changing from relative paths to use the syntax below:

<script src='<%=ResolveClientUrl("~/Scripts/MainJS.js") %>' type="text/javascript"></script>
Ciaran Bruen