Commit 1f94b0a6 by Mac Stephens

Update with tooltip completed

parent de9b7267
[Settings] [Settings]
LogFileNum=512 LogFileNum=513
webClientVersion=0.1.0 webClientVersion=0.1.0
TwilioUpdateTime=0 TwilioUpdateTime=0
......
...@@ -150,6 +150,7 @@ var ...@@ -150,6 +150,7 @@ var
uname, dist: string; uname, dist: string;
complaintId, codeDesc, dispatchDist: string; complaintId, codeDesc, dispatchDist: string;
pngName, iconUrl: string; pngName, iconUrl: string;
priority: string;
begin begin
ShowSpinner('spinner'); ShowSpinner('spinner');
FUnitsLoaded := False; FUnitsLoaded := False;
...@@ -201,38 +202,61 @@ begin ...@@ -201,38 +202,61 @@ begin
begin begin
item := TJSObject(data[i]); item := TJSObject(data[i]);
complaintId := string(item['ComplaintId']); complaintId := string(item['ComplaintId']);
codeDesc := string(item['DispatchCodeDesc']); codeDesc := string(item['DispatchCodeDesc']);
dispatchDist := string(item['DispatchDistrict']); dispatchDist := string(item['DispatchDistrict']);
lat := Double(item['Lat']); priority := string(item['Priority']);
lng := Double(item['Lng']); lat := Double(item['Lat']);
lng := Double(item['Lng']);
if ((lat = 0) and (lng = 0)) or (Abs(lat) > 90) or (Abs(lng) > 180) then if ((lat = 0) and (lng = 0)) or (Abs(lat) > 90) or (Abs(lng) > 180) then
Continue; Continue;
pngName := string(item['pngName']); pngName := string(item['pngName']);
if Trim(pngName) <> '' then if Trim(pngName) <> '' then
iconUrl := 'assets/markers/' + pngName iconUrl := 'assets/markers/' + pngName
else else
iconUrl := 'assets/markers/default_5-9.png'; iconUrl := 'assets/markers/default_5-9.png';
m := lfMap.Markers.Add; m := lfMap.Markers.Add;
m.Latitude := lat; m.Latitude := lat;
m.Longitude := lng; m.Longitude := lng;
m.Title := Format('%s %s (%s)', [complaintId, codeDesc, dispatchDist]);
m.DataString := 'complaint|' + complaintId; // Note: This is th HTML tooltip content: info + button
m.IconURL := iconUrl; 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; end;
finally finally
lfMap.EndUpdate; lfMap.EndUpdate;
end; end;
end; end;
FComplaintsLoaded := True; FComplaintsLoaded := True;
except except
on E: EXDataClientRequestException do on E: EXDataClientRequestException do
Console.Log('Complaints XData error: ' + E.ErrorResult.ErrorMessage); Console.Log('Complaints XData error: ' + E.ErrorResult.ErrorMessage);
end; end;
// if FUnitsLoaded and FComplaintsLoaded then
// FitBoundsPolysAndMarkers;
HideSpinner('spinner'); HideSpinner('spinner');
end; end;
...@@ -242,7 +266,11 @@ procedure TFViewMap.lfMapCustomizeMarker(Sender: TObject; var ACustomizeMarker: ...@@ -242,7 +266,11 @@ procedure TFViewMap.lfMapCustomizeMarker(Sender: TObject; var ACustomizeMarker:
begin begin
ACustomizeMarker := ACustomizeMarker :=
'var m=' + MARKERVAR + ', o=m.options||{};' + #13#10 + '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 + '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 + 'try { m.unbindTooltip(); } catch(e) {}' + #13#10 +
...@@ -273,15 +301,20 @@ begin ...@@ -273,15 +301,20 @@ begin
' }' + #13#10 + ' }' + #13#10 +
'} catch(e) {}' + #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 + 'var html = ''<div class="emi-marker-wrap"><img src="'' + u + ''" class="emi-marker-img">'';' + #13#10 +
'if (badgeText) {' + #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 + '}' + #13#10 +
'html += ''</div>'';' + #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 + 'm.setIcon(L.divIcon({' + #13#10 +
' html: html,' + #13#10 + ' html: html,' + #13#10 +
' iconSize: [32,32],' + #13#10 + ' iconSize: [32,32],' + #13#10 +
...@@ -290,44 +323,43 @@ begin ...@@ -290,44 +323,43 @@ begin
' className: ""' + #13#10 + ' className: ""' + #13#10 +
'}));' + #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 + 'm.bindTooltip(t, {' + #13#10 +
' className: "emi-tip",' + #13#10 + ' className: "emi-tip",' + #13#10 +
' direction: "top",' + #13#10 + ' direction: "top",' + #13#10 +
' offset: [0,-28],' + #13#10 + ' offset: [0,-28],' + #13#10 +
' sticky: true' + #13#10 + ' sticky: true,' + #13#10 +
' interactive: true' + #13#10 +
'});'; '});';
end; end;
procedure TFViewMap.lfMapCustomizeCSS(Sender: TObject; var ACustomizeCSS: string); procedure TFViewMap.lfMapCustomizeCSS(Sender: TObject; var ACustomizeCSS: string);
begin begin
ACustomizeCSS := ACustomizeCSS :=
// Note: Tooltip Container
'.leaflet-tooltip.emi-tip {' + #13#10 + '.leaflet-tooltip.emi-tip {' + #13#10 +
' background: #111;' + #13#10 + ' background: rgba(245,245,245,0.99);' + #13#10 +
' color: #fff;' + #13#10 + ' color: #000;' + #13#10 +
' border-radius: 6px;' + #13#10 + ' border-radius: 8px;' + #13#10 +
' padding: 6px 8px;' + #13#10 + ' padding: 10px 12px;' + #13#10 +
' border: 1px solid rgba(255,255,255,.15);' + #13#10 + ' border: 1px solid rgba(0,0,0,.20);' + #13#10 +
' box-shadow: 0 4px 14px rgba(0,0,0,.35);' + #13#10 + ' box-shadow: 0 4px 14px rgba(0,0,0,.25);' + #13#10 +
' font: 500 12px/1.2 system-ui, Segoe UI, Roboto, sans-serif;' + #13#10 + ' pointer-events: auto;' + #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 +
'}' + #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 + '.emi-marker-badge {' + #13#10 +
' position: absolute;' + #13#10 + ' position: absolute;' + #13#10 +
' top: -4px;' + #13#10 + ' top: -4px;' + #13#10 +
...@@ -345,7 +377,6 @@ begin ...@@ -345,7 +377,6 @@ begin
end; end;
procedure TFViewMap.lfMapPolyElementMouseEnter(Sender: TObject; AElement: TTMSFNCMapsPolyElement); procedure TFViewMap.lfMapPolyElementMouseEnter(Sender: TObject; AElement: TTMSFNCMapsPolyElement);
begin begin
if AElement is TTMSFNCMapsPolygon then if AElement is TTMSFNCMapsPolygon then
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment