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

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
… 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.