Consolidated ASP Classic MVC framework from best components
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

165 lignes
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.