Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
BOOK: Professional ASP.NET MVC 2
This is the forum to discuss the Wrox book Professional ASP.NET MVC 2 by Jon Galloway, Scott Hanselman, Phil Haack, Scott Guthrie, Rob Conery; ISBN: Professional ASP.NET MVC 2
Welcome to the p2p.wrox.com Forums.

You are currently viewing the BOOK: Professional ASP.NET MVC 2 section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developers’ questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
 
 
Thread Tools Display Modes
  #11 (permalink)  
Old October 12th, 2010, 01:07 PM
Friend of Wrox
Points: 539, Level: 8
Points: 539, Level: 8 Points: 539, Level: 8 Points: 539, Level: 8
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2010
Location: Seattle
Posts: 106
Thanks: 1
Thanked 17 Times in 17 Posts
Default

Also on Page 142, Index.aspx needs to have reference to:

Code:
<script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" type="text/javascript"></script> 
<script src="/Scripts/Map.js" type="text/javascript"></script>
Hint: if you don't already know, you can drag-n-drop the Map.js file into Index.aspx instead of typing.

Since I used a modified Map.js file (from codeplex), I had to prefix the function calls in Index.aspx with "NerdDinner"
Code:
<script type="text/javascript">

    $(document).ready(function () {
        NerdDinner.LoadMap();
    });

    $("#search").click(function (evt) {
        var where = jQuery.trim($("#Location").val());
        if (where.length < 1)
            return;

        NerdDinner.FindDinnersGivenLocation(where);
    });

</script>
  #12 (permalink)  
Old October 12th, 2010, 04:35 PM
Registered User
 
Join Date: Oct 2010
Location: Zürich
Posts: 8
Thanks: 0
Thanked 1 Time in 1 Post
Default

Aha! That's it.

flyinhawaiian - thanks for your efforts in looking though the completed solution and working back. I can now (literally) turn the page and move onwards.

(That comment was related to your previous post regarding the CSS additions.)

Last edited by ajameson; October 12th, 2010 at 04:38 PM.
  #13 (permalink)  
Old November 9th, 2010, 06:33 PM
Authorized User
 
Join Date: Sep 2010
Posts: 13
Thanks: 1
Thanked 1 Time in 1 Post
Default Decimal point versus decimal comma

For those of you who live in a country where the decial point is replaced by a decimal comma (like in Denmark) you will need to make a couple of changes to make the map work.

Note: this is just for this demo... If you where going to use this "live", you should definately make sure to make a better test than the one I have made

In the file Map.js replace:

Code:
//If we've found exactly one place, that's our address.
    if (points.length === 1) {
        $("#Dinner_Latitude").val(points[0].Latitude);
        $("#Dinner_Longitude").val(points[0].Longitude);
    }
with

Code:
//If we've found exactly one place, that's our address.
    if (points.length === 1) {
        $("#Dinner_Latitude").val(points[0].Latitude.toString().replace(".", ","));
        $("#Dinner_Longitude").val(points[0].Longitude.toString().replace(".", ","));
    }
and in Map.ascs replace

Code:
var latitude = <%:Model.Latitude %>;
var longitude = <%:Model.Longitude %>;
with

Code:
var latitude = <%:Model.Latitude.ToString().Replace(',', '.') %>;
var longitude = <%:Model.Longitude.ToString().Replace(',', '.') %>;
I know that this is not a good solution:
1: In Map.js I could have used toLocaleString() instead, if I just knew how to get more than two decimals...
2: In Map.ascs: tsk tsk... it is not nice to replace raw data like this...

But it works for me in this tutorial!
  #14 (permalink)  
Old November 9th, 2010, 06:47 PM
Authorized User
 
Join Date: Sep 2010
Posts: 13
Thanks: 1
Thanked 1 Time in 1 Post
Default Page 133

When updating the Latitude/Longitude Textboxes to hidden boxes it should not be done as in page 133:

Code:
<%: Html.Hidden("Latitude", Model.Dinner.Latitude)%>
<%: Html.Hidden("Longitude", Model.Dinner.Longitude)%>
but as this instead:

Code:
<%: Html.Hidden("Dinner.Latitude", Model.Dinner.Latitude)%>
<%: Html.Hidden("Dinner.Longitude", Model.Dinner.Longitude)%>
  #15 (permalink)  
Old November 10th, 2010, 10:15 AM
Friend of Wrox
Points: 539, Level: 8
Points: 539, Level: 8 Points: 539, Level: 8 Points: 539, Level: 8
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2010
Location: Seattle
Posts: 106
Thanks: 1
Thanked 17 Times in 17 Posts
Default

Ah, this is further evidence that one part of the book is totally missing. You'll notice the book mentions something about a customed shaped viewmodel, but never shows an example. Using this as a clue, I figured that in your view model, you can expose specific properties of your model (Dinner). Then, you can use "Latitude" instead of "Dinner.Latitude" You can do it like this in DinnerFormViewModel:

Code:
public double Latitude
{
    get { return Dinner.Latitude; }
    set { Dinner.Latitude = value; }
}

public double Longitude
{
    get { return Dinner.Longitude; }
    set { Dinner.Longitude = value; }
}
  #16 (permalink)   Spam!  
Old November 24th, 2010, 11:17 AM
ellyka112
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by ajameson View Post
No, there's no CSS for #mapDiv anywhere in my solution.

In retrospect, this seems a little silly. However, while following the book, at no point have I been told to create a style for the mapDiv.

Also, even if there was a CSS selector for #mapDiv, this wouldn't explain why the map is 'blowing up' all over the page, i.e. the map in the top-left, "bing" in the bottom-left, and the map legend in the bottom-right of the webpage, entirely outside the div that's supposed to be containing it.

And why is the containing element (the visible grey box) below the controls rather than to the right of them? Yes, your CSS fix would probably resolve this, but shouldn't that be in the book?

I know you didn't write the book, flyinhawaiian, and I do appreciate your reply, but there's something other than positioning on the mapDiv going wrong here.

UPDATE: I've now added that styling, and the grey box (in which the map should be contained, has moved to the bottom-right. So it looks like there's supposed to be some styling attached to #dinnerDiv which hasn't been included in the book.

http://screencast.com/t/8VfQiedzO

flyinhawaiian - would I be right in thinking that you found that #mapDiv styling on a downloaded version of the project?
Yes, I probably got #mapDiv from another thread or the downloaded complete version. The completed version causes even more confusion because it's constantly changing...they put the map on the left instead of the right, things have been renamed.

Last edited by jminatel; March 26th, 2013 at 10:29 AM. Reason: Deleted spam links
Received Infraction
  #17 (permalink)  
Old December 31st, 2010, 04:30 PM
Registered User
 
Join Date: Dec 2010
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Question wiring up the Search

It appears that my search button doesn't get wired up. I have to be honest, there are so many flaws in the code in the book that I'm at a loss.

I can't tell if I've missed something in my code or if this just isn't working.

Posting my map.js & index.aspx files because I'm hoping someone can point out where I screwed up. Help...

Code:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" type="text/javascript"></script>
    <script src="/Scripts/Map.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            LoadMap();
        });
        $("#search").click(function (evt) {
            var where = jQuery.trim($("#Location").val());
            if (where.length < 1)
                return;
            FindDinnersGivenLocation(where);
        });
    </script>
    <h2>Find a Dinner</h2>
    <div id="mapDivLeft">
        <div id="searchBox">
            Enter your location: <%: Html.TextBox("Location") %>
            <input id="search" type="submit" value="Search" />
        </div>
        <div id="theMap">
        </div>
    </div>

    <div id="mapDivRight">
        <div id="dinnerList"></div>
    </div>
</asp:Content>
Code:
var map = null;
var points = [];
var shapes = [];
var center = null;

function LoadMap(latitude, longitude, onMapLoaded) {
    map = new VEMap('theMap');
    options = new VEMapOptions();
    options.EnableBirdseye = false;

    // Makes the control bar less obtrusive.
    map.SetDashboardSize(VEDashboardSize.Small);
    if (onMapLoaded != null)
        map.onLoadMap = onMapLoaded;
    if (latitude != null && longitude != null) {
        center = new VELatLong(latitude, longitude);
    }
    map.LoadMap(center, null, null, null, null, null, null, options);
}

function LoadPin(LL, name, description) {
    var shape = new VEShape(VEShapeType.Pushpin, LL);

    // Make a nice Pushpin shape with a title and description
    shape.SetTitle("<span class=\"pinTitle\"> " + escape(name) + "</span>");
    if (description !== undefined) {
        shape.SetDescription("<p class=\"pinDetails\">" + escape(description) + "</p>");
    }
    map.AddShape(shape);
    points.push(LL);
    shapes.push(shape);
}

function FindAddressOnMap(where) {
    var numberOfResults = 20;
    var setBestMapView = true;
    var showResults = true;
    map.Find("", where, null, null, null, numberOfResults, showResults, true, true, setBestMapView, callbackForLocation);
}

function callbackForLocation(layer, resultsArray, places, hasMore, VEErrorMessage) {
    clearMap();
    if (places == null)
        return;

    // Make a pushpin for each place we find
    $.each(places, function(i, item) {
        var description = "";
        if (item.Description !== undefined) {
            description = item.Description;
        }
        var LL = new VELatLong(item.LatLong.Latitude, item.LatLong.Longitude);
        LoadPin(LL, item.Name, description);
    });

    // Make sure all pushpins are visible
    if (points.length > 1) {
        map.SetMapView(points);
    }

    // If we've found exactly one place, that's our address.
    if (points.length === 1) {
        $("#Latitude").val(points[0].Latitude);
        $("#Longitude").val(points[0].Longitude);
    }
}

function clearMap() {
    map.Clear();
    points = [];
    shapes = [];
}

function FindDinnersGivenLocation(where) {
    map.Find("", where, null, null, null, null, null, false, null, null, callbackUpdateMapDinners);
}

function callbackUpdateMapDinners(layer, resultsArray, places, hasMore, VEErrorMessage) {
    $("#dinnerList").empty();
    clearMap();
    var center = map.GetCenter();
    $.post("/Search/SearchByLocation", { latitude: center.Latitude, longitude: center.Longitude },
        function (dinners) {
            $.each(dinners, function (i, dinner) {
                var LL = new VELatLong(dinner.Latitude, dinner.Longitude, 0, null);
                var RsvpMessage = "";
                if (dinner.RSVPCount == 1)
                    RsvpMessage = "" + dinner.RSVPCount + " RSVP";
                else
                    RsvpMessage = "" + dinner.RSVPCount + " RSVPs";
                // Add Pin to Map
                LoadPin(LL, '<a href="/Dinners/Details/' + dinner.DinnerID + '">' + dinner.Title + '</a>', "<p>" + dinner.Description + "</p>" + RsvpMessage);
                // Add a dinner to the <ul> dinnerList on the right
                $('#dinnerList').append($('<li/>').attr("class", "dinnerItem").append($('<a>').attr("href", "/Dinners/Details/" + dinner.DinnerID).html(dinner.Title)).append(" (" + RsvpMessage + ")"));
            });

            // Adjust zoom to display all the pins we just added.
            if (points.length > 1) {
                map.SetMapView(points);
            }
            // Display the event's pin-bubble on hover.
            $(".dinnerItem").each(function (i, dinner) {
                $(dinner).hover(
                    function () { map.ShowInfoBox(shapes[i]); },
                    function () { map.HidInfoBox(shapes[i]); });
            });
        }, "json");
}
  #18 (permalink)  
Old January 3rd, 2011, 11:01 AM
Friend of Wrox
Points: 539, Level: 8
Points: 539, Level: 8 Points: 539, Level: 8 Points: 539, Level: 8
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2010
Location: Seattle
Posts: 106
Thanks: 1
Thanked 17 Times in 17 Posts
Default

Yes, lots of major errors in Chapter 1. Did not notice anything obvious in your code. Here's what my code looks like. I ended up copying from codeplex version (which is slightly different).

Index.aspx
Code:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>


<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Find a Dinner</h2>

<div id="mapDivLeft">

    <div id="searchBox">
        Enter your location: <%: Html.TextBox("Location") %>
        <input id="search" type="submit" value="Search" />
    </div>

    <div id="theMap">
    </div>

</div>

<div id="mapDivRight">
    <div id="dinnerList"></div>
</div>

<script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" type="text/javascript"></script> 
<script src="/Scripts/Map.js" type="text/javascript"></script> 


<script type="text/javascript">

    $(document).ready(function () {
        NerdDinner.LoadMap();
    });

    $("#search").click(function (evt) {
        var where = jQuery.trim($("#Location").val());
        if (where.length < 1)
            return;

        NerdDinner.FindDinnersGivenLocation(where);
    });

</script>




</asp:Content>
-----------------------------------------------------------------
map.js
Code:
function NerdDinner() { }

NerdDinner.MapDivId = 'theMap';
NerdDinner._map = null;
NerdDinner._points = [];
NerdDinner._shapes = [];

NerdDinner.LoadMap = function (latitude, longitude, onMapLoaded) {
    NerdDinner._map = new VEMap(NerdDinner.MapDivId);

    var options = new VEMapOptions();

    options.EnableBirdseye = false

    // Makes the control bar less obtrusize.
    this._map.SetDashboardSize(VEDashboardSize.Small);

    if (onMapLoaded != null)
        NerdDinner._map.onLoadMap = onMapLoaded;

    if (latitude != null && longitude != null) {
        var center = new VELatLong(latitude, longitude);
    }

    NerdDinner._map.LoadMap(center, null, null, null, null, null, null, options);
}

NerdDinner.ClearMap = function () {
    NerdDinner._map.Clear();
    NerdDinner._points = [];
    NerdDinner._shapes = [];
}

NerdDinner.LoadPin = function (LL, name, description) {
    var shape = new VEShape(VEShapeType.Pushpin, LL);

    //Make a nice Pushpin shape with a title and description
    shape.SetTitle("<span class=\"pinTitle\"> " + escape(name) + "</span>");

    if (description !== undefined) {
        shape.SetDescription("<p class=\"pinDetails\">" + escape(description) + "</p>");
    }

    NerdDinner._map.AddShape(shape);
    NerdDinner._points.push(LL);
    NerdDinner._shapes.push(shape);
}

NerdDinner.FindAddressOnMap = function (where) {
    var numberOfResults = 1;
    var setBestMapView = true;
    var showResults = true;
    var defaultDisambiguation = true;

    NerdDinner._map.Find("", where, null, null, null,
                         numberOfResults, showResults, true, defaultDisambiguation,
                         setBestMapView, NerdDinner._callbackForLocation);
}

NerdDinner._callbackForLocation = function (layer, resultsArray, places, hasMore, VEErrorMessage) {
    NerdDinner.ClearMap();

    if (places == null) {
        NerdDinner._map.ShowMessage(VEErrorMessage);
        return;
    }

    //Make a pushpin for each place we find
    $.each(places, function (i, item) {
        var description = "";
        if (item.Description !== undefined) {
            description = item.Description;
        }
        var LL = new VELatLong(item.LatLong.Latitude,
                        item.LatLong.Longitude);

        NerdDinner.LoadPin(LL, item.Name, description);
    });

    //Make sure all pushpins are visible
    if (NerdDinner._points.length > 1) {
        NerdDinner._map.SetMapView(NerdDinner._points);
    }

    //If we've found exactly one place, that's our address.
    //lat/long precision was getting lost here with toLocaleString, changed to toString
    if (NerdDinner._points.length === 1) {
        $("#Latitude").val(NerdDinner._points[0].Latitude.toString());
        $("#Longitude").val(NerdDinner._points[0].Longitude.toString());
    }
}

NerdDinner.FindDinnersGivenLocation = function (where) {
    NerdDinner._map.Find("", where, null, null, null, null, null, false,
                         null, null, NerdDinner._callbackUpdateMapDinners);
}


NerdDinner.FindMostPopularDinners = function (limit) {
    $.post("/Search/GetMostPopularDinners", { "limit": limit }, NerdDinner._renderDinners, "json");
}

NerdDinner._callbackUpdateMapDinners = function (layer, resultsArray, places, hasMore, VEErrorMessage) {
    var center = NerdDinner._map.GetCenter();

    $.post("/Search/SearchByLocation",
           { latitude: center.Latitude, longitude: center.Longitude },
           NerdDinner._renderDinners,
           "json");
}


NerdDinner._renderDinners = function (dinners) {
    $("#dinnerList").empty();

    NerdDinner.ClearMap();

    $.each(dinners, function (i, dinner) {

        var LL = new VELatLong(dinner.Latitude, dinner.Longitude, 0, null);

        // Add Pin to Map
        NerdDinner.LoadPin(LL, _getDinnerLinkHTML(dinner), _getDinnerDescriptionHTML(dinner));

        //Add a dinner to the <ul> dinnerList on the right
        $('#dinnerList').append($('<li/>')
                        .attr("class", "dinnerItem")
                        .append(_getDinnerLinkHTML(dinner))
                        .append($('<br/>'))
                        .append(_getDinnerDate(dinner, "mmm d"))
                        .append(" with " + _getRSVPMessage(dinner.RSVPCount)));
    });

    // Adjust zoom to display all the pins we just added.
    if (NerdDinner._points.length > 1) {
        NerdDinner._map.SetMapView(NerdDinner._points);
    }

    // Display the event's pin-bubble on hover.
    $(".dinnerItem").each(function (i, dinner) {
        $(dinner).hover(
            function () { NerdDinner._map.ShowInfoBox(NerdDinner._shapes[i]); },
            function () { NerdDinner._map.HideInfoBox(NerdDinner._shapes[i]); }
        );
    });

    function _getDinnerDate(dinner, formatStr) {
        //return '<strong>' + _dateDeserialize(dinner.EventDate).format(formatStr) + '</strong>'; // Codeplex version
        return '<strong>' + _dateDeserialize(dinner.EventDate).toDateString() + '</strong>';
    }

    function _getDinnerLinkHTML(dinner) {
        //return '<a href="' + dinner.Url + '">' + dinner.Title + '</a>'; // Codeplex version
        return '<a href="' + '/Dinners/Details/' + dinner.DinnerID + '">' + dinner.Title + '</a>';
    }

    function _getDinnerDescriptionHTML(dinner) {
        return '<p>' + _getDinnerDate(dinner, "mmmm d, yyyy") + '</p><p>' + dinner.Description + '</p>' + _getRSVPMessage(dinner.RSVPCount);
    }

    function _dateDeserialize(dateStr) {
        return eval('new' + dateStr.replace(/\//g, ' '));
    }


    function _getRSVPMessage(RSVPCount) {
        var rsvpMessage = "" + RSVPCount + " RSVP";

        if (RSVPCount > 1)
            rsvpMessage += "s";

        return rsvpMessage;
    }
}

NerdDinner.dragShape = null;
NerdDinner.dragPixel = null;

NerdDinner.EnableMapMouseClickCallback = function () {
    NerdDinner._map.AttachEvent("onmousedown", NerdDinner.onMouseDown);
    NerdDinner._map.AttachEvent("onmouseup", NerdDinner.onMouseUp);
    NerdDinner._map.AttachEvent("onmousemove", NerdDinner.onMouseMove);
}

NerdDinner.onMouseDown = function (e) {
    if (e.elementID != null) {
        NerdDinner.dragShape = NerdDinner._map.GetShapeByID(e.elementID);
        return true;
    }
}

NerdDinner.onMouseUp = function (e) {
    if (NerdDinner.dragShape != null) {
        var x = e.mapX;
        var y = e.mapY;
        NerdDinner.dragPixel = new VEPixel(x, y);
        var LatLong = NerdDinner._map.PixelToLatLong(NerdDinner.dragPixel);
        $("#Latitude").val(LatLong.Latitude.toString());
        $("#Longitude").val(LatLong.Longitude.toString());
        NerdDinner.dragShape = null;

        NerdDinner._map.FindLocations(LatLong, NerdDinner.getLocationResults);
    }
}

NerdDinner.onMouseMove = function (e) {
    if (NerdDinner.dragShape != null) {
        var x = e.mapX;
        var y = e.mapY;
        NerdDinner.dragPixel = new VEPixel(x, y);
        var LatLong = NerdDinner._map.PixelToLatLong(NerdDinner.dragPixel);
        NerdDinner.dragShape.SetPoints(LatLong);
        return true;
    }
}

NerdDinner.getLocationResults = function (locations) {
    if (locations) {
        var currentAddress = $("#Dinner_Address").val();
        if (locations[0].Name != currentAddress) {
            var answer = confirm("Bing Maps returned the address '" + locations[0].Name + "' for the pin location. Click 'OK' to use this address for the event, or 'Cancel' to use the current address of '" + currentAddress + "'");
            if (answer) {
                $("#Dinner_Address").val(locations[0].Name);
            }
        }
    }


}
  #19 (permalink)  
Old July 19th, 2011, 03:33 AM
Registered User
 
Join Date: Jul 2011
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Exclamation Map is not appearing in the div tag "mapDiv" on partial Dinnar.ascx

Can some one please summarize the method so that I can make the map to appear inside the div tag.

From My side I had tried all the ways mentioned in this thread. Now my webpage loooks like
http://i.imgur.com/J3VjG.png

I am using Map.js provided in one of the posts in this thread and added following to Site.css
#mapDiv
{
float:right;
width:520px;

}
#theMap
{
position: relative;
width: 580px;
border: solid 1px #bbd1ec;
}

Last edited by logiccool; July 19th, 2011 at 03:48 AM.
  #20 (permalink)  
Old July 19th, 2011, 11:43 AM
Friend of Wrox
Points: 539, Level: 8
Points: 539, Level: 8 Points: 539, Level: 8 Points: 539, Level: 8
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Oct 2010
Location: Seattle
Posts: 106
Thanks: 1
Thanked 17 Times in 17 Posts
Default

Check Map.ascx. See if the div tag has matching ID

Code:
<div id="theMap"></div>
 


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
How can I acheive this logic? OnDistantShores XSLT 3 February 26th, 2010 04:16 AM
Heat Map over Google Map ajit Javascript 0 March 7th, 2008 09:01 AM
And/Or Logic??? ninel SQL Server 2000 2 February 9th, 2007 11:33 AM
Mixing Data access logic and business logic polrtex BOOK: Professional Jakarta Struts 0 December 15th, 2003 07:19 PM



All times are GMT -4. The time now is 03:41 PM.


Powered by vBulletin®
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.