diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/About.razor b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/About.razor
index fb4f0187..90f45bc5 100644
--- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/About.razor
+++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/About.razor
@@ -31,9 +31,7 @@
Need help creating your own Geospatial Information System, maps, or data applications?
Visit dymaptic.com or email us and let us know how we can help you!
-
-
- Follow @@GeoBlazor
-
+
\ No newline at end of file
diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/About.razor.css b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/About.razor.css
index e677fd26..357f8beb 100644
--- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/About.razor.css
+++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/About.razor.css
@@ -49,6 +49,16 @@
font: normal normal normal 12px/18px 'Helvetica Neue', Arial, sans-serif;
}
+.pro {
+ color: gold;
+ font-style: italic;
+ font-weight: bold;
+ padding: 1rem 0;
+}
+
+.pro a {
+ color: gold!important;
+}
@media (max-width: 799px) {
#feature-inset {
diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ClickToAdd.razor b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ClickToAdd.razor
new file mode 100644
index 00000000..aed1a17c
--- /dev/null
+++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/ClickToAdd.razor
@@ -0,0 +1,64 @@
+@page "/click-to-add"
+Click to Add Points
+Click To Add Points
+
+
+
+ Click anywhere to see a point added to the map. Click on the point again to see a popup. Click on the popup action to add the point to the list below.
+
+
+
+
+
+
+
+
Points Clicked
+ @foreach (Point point in _points)
+ {
+
Long: @point.Longitude!.Value.ToString("N2") Lat: @point.Latitude!.Value.ToString("N2")
+ }
+
+
+@code {
+ private async Task OnClick(ClickEvent arg)
+ {
+ Point point = arg.MapPoint;
+ if (_graphic is null)
+ {
+ _graphic = new Graphic(point);
+ await _graphicsLayer!.Add(_graphic);
+ }
+
+ SimpleMarkerSymbol symbol = new SimpleMarkerSymbol(new Outline(new MapColor("blue")),
+ new MapColor("yellow"), 10);
+
+ ActionButton actionButton = new ActionButton("Click to Add to List",
+ "./_content/dymaptic.GeoBlazor.Core.Sample.Shared/images/dymaptic_logo.png", "test-1", AddPoint);
+ PopupTemplate popupTemplate = new PopupTemplate(
+ $"New Point at Long: {point.Longitude!.Value:N2} Lat: {point.Latitude!.Value:N2}",
+ actions: new[]{ actionButton });
+
+ await _graphic.SetPopupTemplate(popupTemplate);
+ await _graphic.SetSymbol(symbol);
+ await _graphic.SetGeometry(point);
+ }
+
+ private async Task AddPoint()
+ {
+ _points.Add(((Point)_graphic!.Geometry!).Clone());
+ await InvokeAsync(StateHasChanged);
+ }
+
+ private Graphic? _graphic;
+ private GraphicsLayer? _graphicsLayer;
+ private readonly List _points = new();
+}
\ No newline at end of file
diff --git a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor
index 8e28c18a..c3c9dab2 100644
--- a/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor
+++ b/samples/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor
@@ -71,6 +71,7 @@
new("", "Home", "oi-home"),
new("navigation", "Navigation", "oi-compass"),
new("drawing", "Drawing", "oi-pencil"),
+ new("click-to-add", "Click to Add Point", "oi-map-marker"),
new("many-graphics", "Many Graphics", "oi-calculator"),
new("scene", "Scene & Attributes", "oi-globe"),
new("widgets", "Widgets", "oi-location"),
diff --git a/src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs b/src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs
index f726d274..45afd904 100644
--- a/src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs
+++ b/src/dymaptic.GeoBlazor.Core/Components/ActionBase.cs
@@ -108,6 +108,56 @@ internal record ActionBaseSerializationRecord([property: JsonIgnore(Condition =
///
public class ActionButton : ActionBase
{
+ ///
+ /// Parameterless constructor for use as a razor component.
+ ///
+ public ActionButton()
+ {
+ }
+
+ ///
+ /// Constructor for use in code.
+ ///
+ ///
+ /// The title of the action.
+ ///
+ ///
+ /// The URL to an image that will be used to represent the action. This property will be used as a background image
+ ///
+ ///
+ /// The name of the ID assigned to this action.
+ ///
+ ///
+ /// The action function to perform on click.
+ ///
+ ///
+ /// This adds a CSS class to the ActionButton's node.
+ ///
+ ///
+ /// Set this property to true to display a spinner icon.
+ ///
+ ///
+ /// Indicates whether this action is disabled.
+ ///
+ ///
+ /// Indicates if the action is visible.
+ ///
+ public ActionButton(string? title = null, string? image = null, string? id = null,
+ Func? callbackFunction = null, string? className = null, bool? active = null, bool? disabled = null,
+ bool? visible = null)
+ {
+#pragma warning disable BL0005
+ Title = title;
+ Image = image;
+ Id = id;
+ CallbackFunction = callbackFunction;
+ ClassName = className;
+ Active = active;
+ Disabled = disabled;
+ Visible = visible;
+#pragma warning restore BL0005
+ }
+
///
public override string Type => "button";
@@ -141,6 +191,51 @@ internal override ActionBaseSerializationRecord ToSerializationRecord()
///
public class ActionToggle : ActionBase
{
+ ///
+ /// Parameterless constructor for use as a razor component.
+ ///
+ public ActionToggle()
+ {
+ }
+
+ ///
+ /// Constructor for use in code.
+ ///
+ ///
+ /// The title of the action.
+ ///
+ ///
+ /// The name of the ID assigned to this action.
+ ///
+ ///
+ /// The action function to perform on click.
+ ///
+ ///
+ /// Indicates the value of whether the action is toggled on/off.
+ ///
+ ///
+ /// Set this property to true to display a spinner icon.
+ ///
+ ///
+ /// Indicates whether this action is disabled.
+ ///
+ ///
+ /// Indicates if the action is visible.
+ ///
+ public ActionToggle(string? title = null, string? id = null, Func? callbackFunction = null,
+ bool? value = null, bool? active = null, bool? disabled = null, bool? visible = null)
+ {
+#pragma warning disable BL0005
+ Title = title;
+ Id = id;
+ CallbackFunction = callbackFunction;
+ Value = value;
+ Active = active;
+ Disabled = disabled;
+ Visible = visible;
+#pragma warning restore BL0005
+ }
+
///
public override string Type => "toggle";
diff --git a/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupTemplate.cs b/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupTemplate.cs
index eaa15484..cca30964 100644
--- a/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupTemplate.cs
+++ b/src/dymaptic.GeoBlazor.Core/Components/Popups/PopupTemplate.cs
@@ -331,7 +331,7 @@ internal PopupTemplateSerializationRecord ToSerializationRecord()
FieldInfos?.Select(f => f.ToSerializationRecord()),
Content.Select(c => c.ToSerializationRecord()),
ExpressionInfos?.Select(e => e.ToSerializationRecord()), OverwriteActions,
- ReturnGeometry, Actions?.Select(a => a.ToSerializationRecord()));
+ ReturnGeometry, Actions?.Select(a => a.ToSerializationRecord()), Id.ToString());
}
}
@@ -362,5 +362,8 @@ internal record PopupTemplateSerializationRecord([property: JsonIgnore(Condition
bool? ReturnGeometry = null,
[property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[property: ProtoMember(9)]
- IEnumerable? Actions = null)
+ IEnumerable? Actions = null,
+ [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+ [property: ProtoMember(10)]
+ string? id = null)
: MapComponentSerializationRecord;
\ No newline at end of file
diff --git a/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs b/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs
index e0cca48f..b136a9d0 100644
--- a/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs
+++ b/src/dymaptic.GeoBlazor.Core/Components/Views/MapView.razor.cs
@@ -969,6 +969,51 @@ public async Task OnJavascriptLayerViewCreateError(LayerViewCreateErrorEvent err
///
[Parameter]
public int? GraphicSerializationChunkSize { get; set; }
+
+ ///
+ /// For internal use only, this looks up a missing for a
+ /// and returns it to JavaScript.
+ ///
+ [JSInvokable]
+ public DotNetObjectReference? GetDotNetPopupTemplateObjectReference(Guid popupTemplateId)
+ {
+ foreach (Graphic graphic in Graphics)
+ {
+ if (graphic.PopupTemplate?.Id == popupTemplateId)
+ {
+ return graphic.PopupTemplate.DotNetPopupTemplateReference;
+ }
+ }
+
+ foreach (Layer layer in Map!.Layers)
+ {
+ switch (layer)
+ {
+ case FeatureLayer { Source: not null } featureLayer:
+ foreach (Graphic graphic in featureLayer.Source)
+ {
+ if (graphic.PopupTemplate?.Id == popupTemplateId)
+ {
+ return graphic.PopupTemplate.DotNetPopupTemplateReference;
+ }
+ }
+
+ break;
+ case GraphicsLayer graphicsLayer:
+ foreach (Graphic graphic in graphicsLayer.Graphics)
+ {
+ if (graphic.PopupTemplate?.Id == popupTemplateId)
+ {
+ return graphic.PopupTemplate.DotNetPopupTemplateReference;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return null;
+ }
#endregion
diff --git a/src/dymaptic.GeoBlazor.Core/Scripts/definitions.d.ts b/src/dymaptic.GeoBlazor.Core/Scripts/definitions.d.ts
index fdf79120..1e256c6a 100644
--- a/src/dymaptic.GeoBlazor.Core/Scripts/definitions.d.ts
+++ b/src/dymaptic.GeoBlazor.Core/Scripts/definitions.d.ts
@@ -339,6 +339,7 @@ export interface DotNetPopupTemplate {
overwriteActions: boolean;
returnGeometry: boolean;
dotNetPopupTemplateReference: any;
+ id: string;
actions: any[];
}
diff --git a/src/dymaptic.GeoBlazor.Core/Scripts/jsBuilder.ts b/src/dymaptic.GeoBlazor.Core/Scripts/jsBuilder.ts
index d462d005..45874732 100644
--- a/src/dymaptic.GeoBlazor.Core/Scripts/jsBuilder.ts
+++ b/src/dymaptic.GeoBlazor.Core/Scripts/jsBuilder.ts
@@ -2,7 +2,7 @@
import Extent from "@arcgis/core/geometry/Extent";
import Graphic from "@arcgis/core/Graphic";
import PopupTemplate from "@arcgis/core/PopupTemplate";
-import { arcGisObjectRefs, triggerActionHandler } from "./arcGisJsInterop";
+import {arcGisObjectRefs, dotNetRefs, triggerActionHandler} from "./arcGisJsInterop";
import Geometry from "@arcgis/core/geometry/Geometry";
import Point from "@arcgis/core/geometry/Point";
import Polyline from "@arcgis/core/geometry/Polyline";
@@ -227,6 +227,7 @@ export function buildJsPopupTemplate(popupTemplateObject: DotNetPopupTemplate, v
} else {
content = async (featureSelection) => {
try {
+ await lookupDotNetRefForPopupTemplate(popupTemplateObject, viewId as string);
let results: DotNetPopupContent[] | null = await popupTemplateObject.dotNetPopupTemplateReference
.invokeMethodAsync("OnContentFunction", buildDotNetGraphic(featureSelection.graphic));
return results?.map(r => buildJsPopupContent(r));
@@ -272,11 +273,13 @@ export function buildJsPopupTemplate(popupTemplateObject: DotNetPopupTemplate, v
reactiveUtils.once(() => view.popup.on !== undefined)
.then(() => {
templateTriggerActionHandler = view.popup.on("trigger-action", async (event: PopupTriggerActionEvent) => {
+ await lookupDotNetRefForPopupTemplate(popupTemplateObject, viewId as string);
await popupTemplateObject.dotNetPopupTemplateReference.invokeMethodAsync("OnTriggerAction", event.action.id);
});
})
} else {
templateTriggerActionHandler = view.popup.on("trigger-action", async (event: PopupTriggerActionEvent) => {
+ await lookupDotNetRefForPopupTemplate(popupTemplateObject, viewId as string);
await popupTemplateObject.dotNetPopupTemplateReference.invokeMethodAsync("OnTriggerAction", event.action.id);
});
}
@@ -290,6 +293,14 @@ export function buildJsPopupTemplate(popupTemplateObject: DotNetPopupTemplate, v
return template;
}
+async function lookupDotNetRefForPopupTemplate(popupTemplateObject: DotNetPopupTemplate, viewId: string) {
+ if (!hasValue(popupTemplateObject.dotNetPopupTemplateReference)) {
+ let viewRef = dotNetRefs[viewId];
+ popupTemplateObject.dotNetPopupTemplateReference =
+ await viewRef.invokeMethodAsync('GetDotNetPopupTemplateObjectReference', popupTemplateObject.id);
+ }
+}
+
export let templateTriggerActionHandler: IHandle;
export function buildJsPopupContent(popupContentObject: DotNetPopupContent): ContentProperties | null {
diff --git a/src/dymaptic.GeoBlazor.Core/docCopy.ps1 b/src/dymaptic.GeoBlazor.Core/docCopy.ps1
deleted file mode 100644
index e6f39969..00000000
--- a/src/dymaptic.GeoBlazor.Core/docCopy.ps1
+++ /dev/null
@@ -1,19 +0,0 @@
-$FrontMatter = "---`nlayout: default`ntitle: "
-$Parent = "`nparent: "
-$Index = "Index`nnav_order: 1"
-$EndMatter = "`n---`n"
-$SourcePath = ".\Documentation"
-$OutPath = "..\..\docs\pages\classes"
-
-Get-ChildItem -Path $OutPath -Include *.* -Exclude 'classes.md' -File -Recurse | foreach { $_.Delete() }
-Write-Output "Copying Docs Files"
-Get-ChildItem -Path $SourcePath -Filter "*.md" |
- ForEach {
- $NameComponents = ($_.BaseName -split '\.');
- $Title = $NameComponents[-1];
- $Folder = $NameComponents[-2];
- Write-Output "- $_.BaseName"
- "$( $FrontMatter )$( $_.BaseName -eq 'index' ? $Index : $Title )$( $Parent )Classes$( $EndMatter )$( Get-Content $_.FullName -raw )" -replace '.md', '.html' -replace '>[\s]*ArcGIS[\s]*JS[\s]*API[\s]*', '>ArcGIS JS API' |
- Out-File $_.FullName -Encoding utf8NoBOM;
- Copy-Item -Path $_.FullName -Destination "$( $OutPath )" -Force
- }
\ No newline at end of file
diff --git a/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj b/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj
index 92c8f81e..d4a204fe 100644
--- a/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj
+++ b/src/dymaptic.GeoBlazor.Core/dymaptic.GeoBlazor.Core.csproj
@@ -9,8 +9,8 @@
GeoBlazor
MIT
- 2.3.0
- 2.3.0
+ 2.3.2
+ 2.3.2
Tim Purdum, Christopher Moravec, Mara Stoica, Tim Rawson
dymaptic
©2023 by dymaptic
@@ -100,11 +100,6 @@
-
-
-
-
-
diff --git a/src/dymaptic.GeoBlazor.Core/package-lock.json b/src/dymaptic.GeoBlazor.Core/package-lock.json
index 1d5ce717..eb913e1c 100644
--- a/src/dymaptic.GeoBlazor.Core/package-lock.json
+++ b/src/dymaptic.GeoBlazor.Core/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "dymaptic.GeoBlazor.Core",
- "version": "2.3.0",
+ "version": "2.3.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "dymaptic.GeoBlazor.Core",
- "version": "2.3.0",
+ "version": "2.3.2",
"license": "ISC",
"dependencies": {
"@arcgis/core": "^4.27.6",
diff --git a/src/dymaptic.GeoBlazor.Core/package.json b/src/dymaptic.GeoBlazor.Core/package.json
index 2d8925a4..9a766514 100644
--- a/src/dymaptic.GeoBlazor.Core/package.json
+++ b/src/dymaptic.GeoBlazor.Core/package.json
@@ -1,6 +1,6 @@
{
"name": "dymaptic.GeoBlazor.Core",
- "version": "2.3.0",
+ "version": "2.3.2",
"description": "https://www.geoblazor.com",
"main": "arcGisInterop.js",
"scripts": {
diff --git a/src/dymaptic.GeoBlazor.Core/wwwroot/graphic.json b/src/dymaptic.GeoBlazor.Core/wwwroot/graphic.json
index 4f1da72a..14584052 100644
--- a/src/dymaptic.GeoBlazor.Core/wwwroot/graphic.json
+++ b/src/dymaptic.GeoBlazor.Core/wwwroot/graphic.json
@@ -309,6 +309,10 @@
"rule": "repeated",
"type": "Action",
"id": 9
+ },
+ "id": {
+ "type": "string",
+ "id": 10
}
}
},