Hey I'm Lee. My blog was put up to house my strange thoughts, ramblings, nuggets of information I can refer back to and document my learning curves on new dev stuff and fitness regimes.

All thoughts and comments on here are my own, and in no way reflect my employer - I also take no responsibility for spelling, grammar, terminology, accuracy of facts etc... So read at your own risk!

Extending The Google Maps Property Editor In Umbraco V5

In the previous blog post we created a fairly simple Google maps property editor, but as we all know when creating property editors/datatypes things are never as clean cut as that and you have the need for things like prevalues to configure you property editor/datatype and maybe even doing some sort of custom logic before Umbraco saves the values from your editor.

So I thought even though the previous Google map property editor is working, and is fully functional as is - We might as well cover some of these scenarios and extend it… And as you will have seen so far, its so easy to do!

Change Values Before Save

There may be occasions where you need to edit or tweak the values of your property editor before Umbraco serializes them, and saves them to the DB.  So to show an example of this I thought I would add a new hidden field, which before the values are saved would concatenate the longitude and latitude into a format like so '51.5454, -41.25668' so we can use it directly in the JavaScript in the front end and not have to worry about getting individual values.

Lets first open up our 'GoogleMapEditorModel.cs' and add a new hidden field.

        [HiddenInput(DisplayValue = false)]
        public string LatLongCombined { get; set; }

That's it, we have somewhere to store this value - Now we just need to override an inbuilt method called 'GetSerializedValue' which will allow us to change and edit values before they are saved. So under our newly added 'LatLongCombined' property in your code add the following:

        public override IDictionary<string, object> GetSerializedValue()
        {
            if (Lat != null && Long != null)
            {
                LatLongCombined = string.Concat(Lat, ", ", Long);
            }
            return base.GetSerializedValue();
        }

As you can see we are just concatenating the other property values into the format we want and saving them to the new property, but you could do anything in here really? Maybe call an external web service or do more complex logic dependant on your needs.

Obviously we can now update our homepage razor code to reflect this by removing the var lat & long we initially added and update the following line of the JavaScript to (Don't forget to actually load the backend first and save and publish the home page or you'll get a key error in the front end)

var myLatlng = new google.maps.LatLng(@Html.Raw(Model.Field<string>("gMap", "LatLongCombined").ToString()));

As the meercat would say.. Simples..

Adding PreValues

For more complex property editors that might require Api keys or lots of configuration settings, prevalues are a must - And again the v5 team have made it super easy to do this using the same principles as the actual editor itself using a Model to scaffold/dictate your UI.  You just create a class as you did for the EditorModel again keeping a naming convention like so 'GoogleMapPreValueModel.cs' appending PreValueModel at the end.  Create this file and add the following code, as you can see its almost exactly the same as the EditorModel apart from we inherit from 'PreValueModel' instaead of 'EditorModel'

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using Umbraco.Cms.Web.Model.BackOffice.PropertyEditors;

namespace Umbraco.Cms.Web.PropertyEditors.GoogleMap
{
    public class GoogleMapPreValueModel : PreValueModel
    {
        [Required(ErrorMessage = @"Zoom level missing")]
        [DisplayName(@"Set the initial zoom level of your map")]
        public int GoogleMapZoomLevel { get; set; }
    }
}

Before this will just work, we do need to tell the PropertyEditor that we have prevalues and to make sure they are available to us from within our property editor.  To do this we just need to expand on what we did in the previous post.

GoogleMapEditorModel

Open up 'GoogleMapEditorModel.cs' and update the main class line to the following (We are just appending the type <GoogleMapPreValueModel> to the EditorModel class we were inheriting from)

public class GoogleMapEditorModel : EditorModel<GoogleMapPreValueModel>

And then add the following constructor just underneath

public GoogleMapEditorModel(GoogleMapPreValueModel preValues) : base(preValues)
{
}

GoogleMapEditor

Finally we just need to do the same thing to the Editor, so update the following line (Again we are adding the PreValueModel type to the PropertyEditor)

public class GoogleMapEditor : PropertyEditor<GoogleMapEditorModel, GoogleMapPreValueModel>

You will know be prompted in Visual Studio to update the implemented interface members, you can either follow the VS prompt or copy and paste the following

        public override GoogleMapEditorModel CreateEditorModel(GoogleMapPreValueModel preValues)
        {
            return new GoogleMapEditorModel(preValues);
        }

        public override GoogleMapPreValueModel CreatePreValueEditorModel()
        {
            return new GoogleMapPreValueModel();
        }

And that be it me ol'friend! If you build and load up the solution you'll see the following on your property editor in the developer section

prevalue-settings

TIP!: You might have to delete your temporary ASP.NET files to get the prevalues to show.

Custom View For PreValues

I'm not going to do this as I think its a bit pointless for this example, but again you can have a custom view for your Pre Values if you wish and again its the exact same concept as the custom view for the property editor (Nifty hey). See the previous post for more details, but in short you just need to create the following view in your 'Views' folder

GoogleMapPreValueEditor.cshtml

At the top of this view add the following

@inherits WebViewPage<Umbraco.Cms.Web.PropertyEditors.GoogleMap.GoogleMapPreValueModel>

And in the 'GoogleMapPreValueModel.cs' class, decorate it with the following to tell Umbraco its using an embedded view (Again exactly the same as we did for the main property editor)

[EmbeddedView("Umbraco.Cms.Web.PropertyEditors.GoogleMap.Views.GoogleMapPreValueEditor.cshtml", "Umbraco.Cms.Web.PropertyEditors")]

See the custom view in the previous post on how to access the properties of the model.

Changing PreValues Before Save

So I haven't actually used this one, but it seems just like on the property editor you can override the same method (Although its a little different)

        public override string GetSerializedValue()
        {
            return base.GetSerializedValue();
        }

I'll have to have a play with this further but at the moment I couldn't think of a reason for using it - so have a play and see if it works for you

Actually Using The PreValue Values

Anyway, so we'll skip the above two items and just use the standard preValue model for showing and saving the settings (Zoom level in our case) - What we want to do now is set the zoom level for the map in our view.  To do this you access prevalue values in your editor like so:

@Model.PreValueModel.PropertyName

So in our case we would get the zoom level like this

@Model.PreValueModel.GoogleMapZoomLevel

Now in our example the Zoom level is in the JavaScript, so for us to be able to use this we need to set another global JS variable in our custom editor view (Just under var latval in the JS script tag)

    var zoomLevel = @Model.PreValueModel.GoogleMapZoomLevel;
    if(zoomLevel <= 0) {
        zoomLevel = 16;
    }

Now open up your 'gMap.js' file and changed the zoom: variable at the top from 'zoom: 16' to:

zoom: zoomLevel,

Save, build and run…

TIP!: You might have to delete your temporary ASP.NET files to get this to show

And that's it Smile … Have a play changing the zoom value settings, and you'll see the zoom level change… As Mr Ramsey would say, Google Map Property Editor... Done!

Hopefully you'll agree this is a great step forward from v4.

Back to top