Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
emiMobile
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Mac Stephens
emiMobile
Commits
1f94b0a6
Commit
1f94b0a6
authored
Nov 19, 2025
by
Mac Stephens
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update with tooltip completed
parent
de9b7267
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
73 additions
and
42 deletions
+73
-42
emiMobileServer.ini
emiMobileServer/emiMobileServer.ini
+1
-1
View.Map.pas
webEMIMobile/View.Map.pas
+72
-41
No files found.
emiMobileServer/emiMobileServer.ini
View file @
1f94b0a6
[Settings]
LogFileNum
=
51
2
LogFileNum
=
51
3
webClientVersion
=
0.1.0
TwilioUpdateTime
=
0
...
...
webEMIMobile/View.Map.pas
View file @
1f94b0a6
...
...
@@ -150,6 +150,7 @@ var
uname
,
dist
:
string
;
complaintId
,
codeDesc
,
dispatchDist
:
string
;
pngName
,
iconUrl
:
string
;
priority
:
string
;
begin
ShowSpinner
(
'spinner'
);
FUnitsLoaded
:=
False
;
...
...
@@ -201,38 +202,61 @@ begin
begin
item
:=
TJSObject
(
data
[
i
]);
complaintId
:=
string
(
item
[
'ComplaintId'
]);
codeDesc
:=
string
(
item
[
'DispatchCodeDesc'
]);
codeDesc
:=
string
(
item
[
'DispatchCodeDesc'
]);
dispatchDist
:=
string
(
item
[
'DispatchDistrict'
]);
lat
:=
Double
(
item
[
'Lat'
]);
lng
:=
Double
(
item
[
'Lng'
]);
priority
:=
string
(
item
[
'Priority'
]);
lat
:=
Double
(
item
[
'Lat'
]);
lng
:=
Double
(
item
[
'Lng'
]);
if
((
lat
=
0
)
and
(
lng
=
0
))
or
(
Abs
(
lat
)
>
90
)
or
(
Abs
(
lng
)
>
180
)
then
Continue
;
Continue
;
pngName
:=
string
(
item
[
'pngName'
]);
if
Trim
(
pngName
)
<>
''
then
iconUrl
:=
'assets/markers/'
+
pngName
else
iconUrl
:=
'assets/markers/default_5-9.png'
;
m
:=
lfMap
.
Markers
.
Add
;
m
.
Latitude
:=
lat
;
m
.
Latitude
:=
lat
;
m
.
Longitude
:=
lng
;
m
.
Title
:=
Format
(
'%s %s (%s)'
,
[
complaintId
,
codeDesc
,
dispatchDist
]);
m
.
DataString
:=
'complaint|'
+
complaintId
;
m
.
IconURL
:=
iconUrl
;
// Note: This is th HTML tooltip content: info + button
m
.
Title
:=
'<div class="d-flex flex-column gap-1" style="min-width:180px;">'
+
'<div class="fw-semibold small">'
+
'<span class="fw-bold">Complaint ID:</span> '
+
complaintId
+
'</div>'
+
'<div class="small">'
+
'<span class="fw-bold">Type:</span> '
+
codeDesc
+
'</div>'
+
'<div class="small">'
+
'<span class="fw-bold">District:</span> '
+
dispatchDist
+
'</div>'
+
'<div class="small mb-1">'
+
'<span class="fw-bold">Priority:</span> '
+
priority
+
'</div>'
+
'<div class="d-flex justify-content-end mt-1">'
+
'<button type="button" class="btn btn-primary btn-sm px-2 py-1" '
+
'onclick="emiOpenComplaintDetails('''
+
complaintId
+
''')">'
+
'Details'
+
'</button>'
+
'</div>'
+
'</div>'
;
// Note: DataString not used for badges anymore, but keep for future
// Note: m.DataString := 'complaint|' + complaintId;
m
.
IconURL
:=
iconUrl
;
end
;
finally
lfMap
.
EndUpdate
;
end
;
end
;
FComplaintsLoaded
:=
True
;
except
on
E
:
EXDataClientRequestException
do
Console
.
Log
(
'Complaints XData error: '
+
E
.
ErrorResult
.
ErrorMessage
);
end
;
// if FUnitsLoaded and FComplaintsLoaded then
// FitBoundsPolysAndMarkers;
HideSpinner
(
'spinner'
);
end
;
...
...
@@ -242,7 +266,11 @@ procedure TFViewMap.lfMapCustomizeMarker(Sender: TObject; var ACustomizeMarker:
begin
ACustomizeMarker
:=
'var m='
+
MARKERVAR
+
', o=m.options||{};'
+
#
13
#
10
+
'var t = (o && o.title) ? o.title : "";'
+
#
13
#
10
+
// Grab the HTML title and move it off the native "title" attribute
'var rawTitle = (o && o.title) ? o.title : "";'
+
#
13
#
10
+
'o.tooltipHtml = rawTitle;'
+
#
13
#
10
+
// store our HTML here
'o.title = "";'
+
#
13
#
10
+
// prevent browser native tooltip
'var t = o.tooltipHtml || "";'
+
#
13
#
10
+
'var u = (o.icon && o.icon.options && o.icon.options.iconUrl) ? o.icon.options.iconUrl : null;'
+
#
13
#
10
+
'try { m.unbindTooltip(); } catch(e) {}'
+
#
13
#
10
+
...
...
@@ -273,15 +301,20 @@ begin
' }'
+
#
13
#
10
+
'} catch(e) {}'
+
#
13
#
10
+
// build HTML wrapper + optional badge
// map badgeText (priority) to background color
'var badgeColor = "#4b5563"; // default for 5-9'
+
#
13
#
10
+
'if (badgeText === "1") badgeColor = "#bc28d9";'
+
#
13
#
10
+
'else if (badgeText === "2") badgeColor = "#b91c1c";'
+
#
13
#
10
+
'else if (badgeText === "3") badgeColor = "#b45309";'
+
#
13
#
10
+
'else if (badgeText === "4") badgeColor = "#047857";'
+
#
13
#
10
+
'// 59 remain #4b5563'
+
#
13
#
10
+
'var html = ''<div class="emi-marker-wrap"><img src="'' + u + ''" class="emi-marker-img">'';'
+
#
13
#
10
+
'if (badgeText) {'
+
#
13
#
10
+
' html += ''<div class="emi-marker-badge">'' + badgeText + ''</div>'';'
+
#
13
#
10
+
' html += ''<div class="emi-marker-badge"
style="background:'' + badgeColor + '';"
>'' + badgeText + ''</div>'';'
+
#
13
#
10
+
'}'
+
#
13
#
10
+
'html += ''</div>'';'
+
#
13
#
10
+
// use a divIcon for all markers (units + complaints),
// units just won''t get a badgeText because their suffix isn''t numeric
'm.setIcon(L.divIcon({'
+
#
13
#
10
+
' html: html,'
+
#
13
#
10
+
' iconSize: [32,32],'
+
#
13
#
10
+
...
...
@@ -290,44 +323,43 @@ begin
' className: ""'
+
#
13
#
10
+
'}));'
+
#
13
#
10
+
// extra safety: strip native title from the DOM element if present
'try { if (m._icon) m._icon.removeAttribute("title"); } catch(e) {}'
+
#
13
#
10
+
'm.bindTooltip(t, {'
+
#
13
#
10
+
' className: "emi-tip",'
+
#
13
#
10
+
' direction: "top",'
+
#
13
#
10
+
' offset: [0,-28],'
+
#
13
#
10
+
' sticky: true'
+
#
13
#
10
+
' sticky: true,'
+
#
13
#
10
+
' interactive: true'
+
#
13
#
10
+
'});'
;
end
;
procedure
TFViewMap
.
lfMapCustomizeCSS
(
Sender
:
TObject
;
var
ACustomizeCSS
:
string
);
begin
ACustomizeCSS
:=
// Note: Tooltip Container
'.leaflet-tooltip.emi-tip {'
+
#
13
#
10
+
' background: #111;'
+
#
13
#
10
+
' color: #fff;'
+
#
13
#
10
+
' border-radius: 6px;'
+
#
13
#
10
+
' padding: 6px 8px;'
+
#
13
#
10
+
' border: 1px solid rgba(255,255,255,.15);'
+
#
13
#
10
+
' box-shadow: 0 4px 14px rgba(0,0,0,.35);'
+
#
13
#
10
+
' font: 500 12px/1.2 system-ui, Segoe UI, Roboto, sans-serif;'
+
#
13
#
10
+
'}'
+
#
13
#
10
+
'.leaflet-tooltip-top.emi-tip:before { border-top-color: #111; }'
+
#
13
#
10
+
'.leaflet-tooltip-bottom.emi-tip:before { border-bottom-color: #111; }'
+
#
13
#
10
+
'.leaflet-tooltip-left.emi-tip:before { border-left-color: #111; }'
+
#
13
#
10
+
'.leaflet-tooltip-right.emi-tip:before { border-right-color: #111; }'
+
#
13
#
10
+
'.emi-marker-wrap {'
+
#
13
#
10
+
' position: relative;'
+
#
13
#
10
+
' display: inline-block;'
+
#
13
#
10
+
'}'
+
#
13
#
10
+
'.emi-marker-img {'
+
#
13
#
10
+
' display: block;'
+
#
13
#
10
+
' background: rgba(245,245,245,0.99);'
+
#
13
#
10
+
' color: #000;'
+
#
13
#
10
+
' border-radius: 8px;'
+
#
13
#
10
+
' padding: 10px 12px;'
+
#
13
#
10
+
' border: 1px solid rgba(0,0,0,.20);'
+
#
13
#
10
+
' box-shadow: 0 4px 14px rgba(0,0,0,.25);'
+
#
13
#
10
+
' pointer-events: auto;'
+
#
13
#
10
+
'}'
+
#
13
#
10
+
// Note: Tooltip Arrow Colors
'.leaflet-tooltip-top.emi-tip:before { border-top-color: rgba(245,245,245,0.92); }'
+
#
13
#
10
+
'.leaflet-tooltip-bottom.emi-tip:before { border-bottom-color: rgba(245,245,245,0.92); }'
+
#
13
#
10
+
'.leaflet-tooltip-left.emi-tip:before { border-left-color: rgba(245,245,245,0.92); }'
+
#
13
#
10
+
'.leaflet-tooltip-right.emi-tip:before { border-right-color: rgba(245,245,245,0.92); }'
+
#
13
#
10
+
// Note: Marker Badge Wrap
'.emi-marker-wrap { position: relative; display: inline-block; }'
+
#
13
#
10
+
'.emi-marker-img { display: block; }'
+
#
13
#
10
+
'.emi-marker-badge {'
+
#
13
#
10
+
' position: absolute;'
+
#
13
#
10
+
' top: -4px;'
+
#
13
#
10
+
...
...
@@ -345,7 +377,6 @@ begin
end
;
procedure
TFViewMap
.
lfMapPolyElementMouseEnter
(
Sender
:
TObject
;
AElement
:
TTMSFNCMapsPolyElement
);
begin
if
AElement
is
TTMSFNCMapsPolygon
then
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment