Consolidated ASP Classic MVC framework from best components
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

165 řádky
6.7KB

  1. <div class="container mt-4">
  2. <nav aria-label="breadcrumb">
  3. <ol class="breadcrumb">
  4. <li class="breadcrumb-item"><a href="/territories">Territories</a></li>
  5. <li class="breadcrumb-item"><a href="/territories/<%= TerritoryController.territory.Id %>"><%= Server.HTMLEncode(TerritoryController.territory.Name) %></a></li>
  6. <li class="breadcrumb-item active" aria-current="page">Edit</li>
  7. </ol>
  8. </nav>
  9. <h1>Edit Territory</h1>
  10. <% Flash().ShowErrorsIfPresent %>
  11. <div class="card">
  12. <div class="card-body">
  13. <form method="post" action="/territories/<%= TerritoryController.territory.Id %>">
  14. <div class="row">
  15. <div class="col-md-4">
  16. <div class="mb-3">
  17. <label for="Name" class="form-label">Name <span class="text-danger">*</span></label>
  18. <input type="text" class="form-control" id="Name" name="Name" required maxlength="255" value="<%= Server.HTMLEncode(TerritoryController.territory.Name) %>">
  19. </div>
  20. <div class="mb-3">
  21. <label for="Description" class="form-label">Description</label>
  22. <textarea class="form-control" id="Description" name="Description" rows="2"><%= Server.HTMLEncode(TerritoryController.territory.Description & "") %></textarea>
  23. </div>
  24. <div class="mb-3">
  25. <label for="Coordinates" class="form-label">Coordinates (JSON)</label>
  26. <textarea class="form-control" id="Coordinates" name="Coordinates" rows="4" style="font-family: monospace; font-size: 12px;"><%= Server.HTMLEncode(TerritoryController.territory.Coordinates & "") %></textarea>
  27. <small class="text-muted">Click on the map to add points, or edit JSON directly.</small>
  28. </div>
  29. <div class="d-flex gap-2">
  30. <button type="submit" class="btn btn-primary">Update Territory</button>
  31. <a href="/territories/<%= TerritoryController.territory.Id %>" class="btn btn-secondary">Cancel</a>
  32. </div>
  33. </div>
  34. <div class="col-md-8">
  35. <label class="form-label">Territory Boundary</label>
  36. <div id="map" style="height: 400px; width: 100%; border-radius: 8px;"></div>
  37. <div class="mt-2">
  38. <button type="button" class="btn btn-sm btn-outline-secondary" onclick="clearPolygon()">Clear Polygon</button>
  39. <button type="button" class="btn btn-sm btn-outline-secondary" onclick="undoLastPoint()">Undo Last Point</button>
  40. </div>
  41. </div>
  42. </div>
  43. </form>
  44. </div>
  45. </div>
  46. </div>
  47. <script>
  48. var existingCoordinates = <%= TerritoryController.territory.Coordinates & "" %>;
  49. </script>
  50. <script src="https://maps.googleapis.com/maps/api/js?key=<%= Server.HTMLEncode(GetAppSetting("GoogleMapsApiKey")) %>&callback=initMap" async defer></script>
  51. <script>
  52. var map, polygon, polygonCoords = [];
  53. function initMap() {
  54. var defaultCenter = { lat: -33.8688, lng: 151.2093 }; // Sydney default
  55. // Parse existing coordinates
  56. if (existingCoordinates && Array.isArray(existingCoordinates) && existingCoordinates.length > 0) {
  57. polygonCoords = existingCoordinates.map(function(coord) {
  58. return { lat: coord.lat || coord[0], lng: coord.lng || coord[1] };
  59. });
  60. }
  61. // Calculate center from existing coords or use default
  62. var center = defaultCenter;
  63. if (polygonCoords.length > 0) {
  64. var bounds = new google.maps.LatLngBounds();
  65. polygonCoords.forEach(function(coord) {
  66. bounds.extend(coord);
  67. });
  68. center = bounds.getCenter();
  69. }
  70. map = new google.maps.Map(document.getElementById('map'), {
  71. zoom: 14,
  72. center: center,
  73. mapTypeId: 'roadmap'
  74. });
  75. // Create editable polygon
  76. polygon = new google.maps.Polygon({
  77. paths: polygonCoords,
  78. strokeColor: '#FF0000',
  79. strokeOpacity: 0.8,
  80. strokeWeight: 2,
  81. fillColor: '#FF0000',
  82. fillOpacity: 0.35,
  83. editable: true,
  84. draggable: true
  85. });
  86. polygon.setMap(map);
  87. // Fit bounds if we have coordinates
  88. if (polygonCoords.length > 0) {
  89. var bounds = new google.maps.LatLngBounds();
  90. polygonCoords.forEach(function(coord) {
  91. bounds.extend(coord);
  92. });
  93. map.fitBounds(bounds);
  94. }
  95. // Click to add points
  96. map.addListener('click', function(event) {
  97. var path = polygon.getPath();
  98. path.push(event.latLng);
  99. updateCoordinatesField();
  100. });
  101. // Update field when polygon is edited
  102. google.maps.event.addListener(polygon.getPath(), 'set_at', updateCoordinatesField);
  103. google.maps.event.addListener(polygon.getPath(), 'insert_at', updateCoordinatesField);
  104. google.maps.event.addListener(polygon.getPath(), 'remove_at', updateCoordinatesField);
  105. // Also update when dragged
  106. google.maps.event.addListener(polygon, 'dragend', updateCoordinatesField);
  107. }
  108. function updateCoordinatesField() {
  109. var path = polygon.getPath();
  110. var coords = [];
  111. for (var i = 0; i < path.getLength(); i++) {
  112. var point = path.getAt(i);
  113. coords.push({ lat: point.lat(), lng: point.lng() });
  114. }
  115. document.getElementById('Coordinates').value = JSON.stringify(coords, null, 2);
  116. }
  117. function clearPolygon() {
  118. polygon.getPath().clear();
  119. updateCoordinatesField();
  120. }
  121. function undoLastPoint() {
  122. var path = polygon.getPath();
  123. if (path.getLength() > 0) {
  124. path.pop();
  125. updateCoordinatesField();
  126. }
  127. }
  128. // Allow manual JSON editing
  129. document.getElementById('Coordinates').addEventListener('change', function() {
  130. try {
  131. var coords = JSON.parse(this.value);
  132. if (Array.isArray(coords)) {
  133. var path = polygon.getPath();
  134. path.clear();
  135. coords.forEach(function(coord) {
  136. path.push(new google.maps.LatLng(coord.lat || coord[0], coord.lng || coord[1]));
  137. });
  138. }
  139. } catch (e) {
  140. // Invalid JSON, ignore
  141. }
  142. });
  143. </script>

Powered by TurnKey Linux.