Source Code WebAPIEditionSample DrawEditFeatures.zip
DrawEditFeaturesController.cs
using System;
using System.Collections.ObjectModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Http;
using System.Web.SessionState;
using System.Xml.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.WebApiEdition;
namespace DrawingAndEditing.Controllers
{
[RoutePrefix("edit")]
public class DrawingAndEditingController : ApiController
{
private static string jsonArrayTemplate = "[{0}]";
[Route("{z}/{x}/{y}")]
public HttpResponseMessage GetTile(int z, int x, int y)
{
// Create the layerOverlay for displaying the map.
LayerOverlay layerOverlay = new LayerOverlay();
InMemoryFeatureLayer shapesFeatureLyaer = GetLayer();
if (shapesFeatureLyaer != null && shapesFeatureLyaer.InternalFeatures.Count > 0)
{
layerOverlay.Layers.Add(shapesFeatureLyaer);
}
using (Bitmap bitmap = new Bitmap(256, 256))
{
GdiPlusGeoCanvas geoCanvas = new GdiPlusGeoCanvas();
RectangleShape boundingBox = WebApiExtentHelper.GetBoundingBoxForXyz(x, y, z, GeographyUnit.Meter);
geoCanvas.BeginDrawing(bitmap, boundingBox, GeographyUnit.Meter);
layerOverlay.Draw(geoCanvas);
geoCanvas.EndDrawing();
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Png);
HttpResponseMessage responseMessage = new HttpResponseMessage(HttpStatusCode.OK);
responseMessage.Content = new ByteArrayContent(memoryStream.ToArray());
responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
return responseMessage;
}
}
[Route("getshapes")]
public string GetShapes()
{
InMemoryFeatureLayer shapesFeatureLayer = GetLayer();
// Return the shapes in JSON saved on server side to client side.
return string.Format(CultureInfo.InvariantCulture, jsonArrayTemplate, string.Join(",", shapesFeatureLayer.InternalFeatures.Select(f => f.GetGeoJson())));
}
[Route("saveshapes")]
[HttpPost]
public void SaveShapes([FromBody] string modifiedShapesInJson)
{
if (!string.IsNullOrEmpty(modifiedShapesInJson))
{
// Parse the JSON.
// There are 2 groups of shapes, one is for shapes removed on client side,
// and the other is for shapes added on client side.
JObject jObject = JObject.Parse(modifiedShapesInJson);
InMemoryFeatureLayer shapesFeatureLayer = GetLayer();
shapesFeatureLayer.Open();
// Deal with removed shapes.
string[] ids = jObject["removedIds"].ToObject<string[]>();
foreach (var id in ids)
{
if (shapesFeatureLayer.InternalFeatures.Count > 0)
{
shapesFeatureLayer.InternalFeatures.Remove(id);
}
}
// Deal with newly added shapes.
string featureGeoJsons = jObject["newShapes"].ToString();
foreach (Feature feature in CreateFeaturesFromGeoJsons(featureGeoJsons))
{
shapesFeatureLayer.InternalFeatures.Add(feature.Id, feature);
}
shapesFeatureLayer.Close();
}
}
private static Collection<Feature> CreateFeaturesFromGeoJsons(string geoJsons)
{
Collection<Feature> features = new Collection<Feature>();
foreach (JToken item in JArray.Parse(geoJsons))
{
Feature feature = null;
string geoJson = item.ToString();
if (geoJson.Contains("\"type\": \"Circle\""))
{
// Circle is not supported in standard GeoJSON, it's only defined in this sample.
feature = CreateCircleFeatureFromGeoJson(geoJson);
}
else
{
feature = Feature.CreateFeatureFromGeoJson(geoJson);
}
if (feature != null && feature.GetWellKnownBinary() != null)
{
features.Add(feature);
}
}
return features;
}
private static Feature CreateCircleFeatureFromGeoJson(string geoJson)
{
dynamic featureEntity = JsonConvert.DeserializeObject(geoJson);
dynamic geometryEntity = JsonConvert.DeserializeObject(featureEntity.geometry.ToString());
double x = Convert.ToDouble(geometryEntity.coordinates[0].ToString(), CultureInfo.InvariantCulture);
double y = Convert.ToDouble(geometryEntity.coordinates[1].ToString(), CultureInfo.InvariantCulture);
double radius = Convert.ToDouble(geometryEntity.radius.ToString(), CultureInfo.InvariantCulture);
DistanceUnit distanceUnit = (DistanceUnit)Enum.Parse(typeof(DistanceUnit), geometryEntity.radiusUnit.ToString(), true);
EllipseShape circleShape = new EllipseShape(new PointShape(x, y), radius, GeographyUnit.DecimalDegree, distanceUnit);
Feature feature = new Feature(circleShape);
foreach (var item in featureEntity.properties)
{
feature.ColumnValues[item.Name] = item.Value.ToString();
}
return feature;
}
// Get layer from the Session so each session has its own test data.
private static InMemoryFeatureLayer GetLayer()
{
IHttpSessionState session = SessionStateUtility.GetHttpSessionStateFromContext(HttpContext.Current);
if (session["shapesFeatureLayer"] == null)
{
InMemoryFeatureLayer shapesFeatureLayer = new InMemoryFeatureLayer();
shapesFeatureLayer.Open();
shapesFeatureLayer.Columns.Add(new FeatureSourceColumn("Name"));
shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(100, GeoColor.FromHtml("#676e51")), GeoColor.SimpleColors.Black);
shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.FromHtml("#2b7a05"), 14, GeoColor.SimpleColors.Black);
shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyles.CreateSimpleLineStyle(GeoColor.FromHtml("#676e51"), 2, true);
shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("Name", "Arial", 12, DrawingFontStyles.Bold, GeoColor.StandardColors.Gray, GeoColor.StandardColors.White, 2);
shapesFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
string dataFilePath = GetFullPath(@"App_Data\Data.xml");
XElement xElement = XElement.Load(dataFilePath);
foreach (var geometryXElement in xElement.Descendants("Geometry"))
{
Feature feature = new Feature(geometryXElement.Value);
feature.ColumnValues.Add("name", geometryXElement.Attribute("name").Value);
shapesFeatureLayer.InternalFeatures.Add(feature.Id, feature);
}
Proj4Projection proj4 = new Proj4Projection();
proj4.InternalProjectionParametersString = Proj4Projection.GetWgs84ParametersString();
proj4.ExternalProjectionParametersString = Proj4Projection.GetSphericalMercatorParametersString();
shapesFeatureLayer.FeatureSource.Projection = proj4;
proj4.Open();
session["shapesFeatureLayer"] = shapesFeatureLayer;
}
return (InMemoryFeatureLayer)session["shapesFeatureLayer"];
}
private static string GetFullPath(string fileName)
{
Uri uri = new Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
string rootDirectory = Path.GetDirectoryName(Path.GetDirectoryName(uri.LocalPath));
return Path.Combine(rootDirectory, fileName); ;
}
}
}
Default.htm(LeafLet)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Draw edit features</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="author" content="ThinkGeo" />
<link rel="apple-touch-icon" href="desktop.png" />
<meta name="apple-mobile-web-app-title" content="Draw edit features" />
<link href="favicon.ico" rel="shortcut icon" type="Images/x-icon" />
<link href="Content/leaflet.css" rel="stylesheet" />
<link href="Content/leaflet.draw.css" rel="stylesheet" />
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<link href="Content/Site.css" rel="stylesheet" />
</head>
<body>
<div id="map">
</div>
<div id="loadingImage">
<img src="Images/ajax-loader.gif" />
</div>
<div class="centroid">
<div id="dlgName">
<div class="edit-panel-header">
<span>The name of drawn shape</span>
</div>
<div class="edit-content">
<input type="text" id="txtName" />
<span id="spWarning" class="warning">The name is required.</span>
</div>
<div class="edit-foot">
<a id="btnSaveName" href="#" class="btn btn-primary" role="button">OK</a>
</div>
</div>
</div>
<script src="Scripts/jquery-1.11.1.min.js"></script>
<script src="Scripts/leaflet.js"></script>
<script src="Scripts/leaflet.draw.js"></script>
<script src="thinkgeo.leaflet.js"></script>
<script>
var drawingLayer, editServerShapes = false;
var postData = { removeIds: [], geoJsons: [] };
// initialize the map
var map = L.map('map', { center: [33.1451,|-96.8150], zoom: 16 });
// ThinkGeo World Map
L.tileLayer.wms("http://{s}.thinkgeo.com/CachedWMSServer/WmsServer.axd", {
subdomains: ['worldmapkit1',|'worldmapkit2', 'worldmapkit3', 'worldmapkit4', 'worldmapkit5', 'worldmapkit6'],
layers: 'OSMWorldMapKitLayer',
format: 'image/png',
styles: 'WorldMapKitDefaultStyle',
version: '1.1.1',
attribution: '<a href="http://thinkgeo.com/map-suite-developer-gis/world-map-kit-sdk/">ThinkGeo</a> | © <a href="http://osm.org/copyright">OpenStreetMap</a> contributors '
}).addTo(map);
// layer including the drawn shapes which are saved to server side
var shapeLayer = L.dynamicLayer(L.Util.getRootPath() + "/edit/{z}/{x}/{y}");
shapeLayer.on('loading', function () {
$('#loadingImage').show();
})
shapeLayer.on('load', function () {
$('#loadingImage').hide();
})
shapeLayer.addTo(map);
// Initialise the FeatureGroup to save editable layers
var drawnItems = L.featureGroup().addTo(map);
// Initialise the draw control and pass it the FeatureGroup of editable layers
var drawControl = new L.Control.Draw({
edit: {
featureGroup: drawnItems
}
}).addTo(map);
// add image buttons for layers, edit, help etc.
L.imageButtons({
imgs: [ | {
src: 'Images/save.png',
id: 'imgSave',
title: 'Save to server',
callback: function () {
editServerShapes = false;
drawnItems.eachLayer(function (layer) {
var geoJson = layer.toGeoJSON();
if (layer._mRadius) {
geoJson.geometry.radius = layer.getRadius();
geoJson.geometry.type = "Circle";
geoJson.geometry.radiusUnit = "Meter";
}
geoJson.id = layer.id;
geoJson.properties = { 'name': layer.name };
postData.geoJsons.push(geoJson);
}, this);
// save the drawn features to server side in GeoJson format
$.post(L.Util.getRootPath() + '/edit/add', { //: JSON.stringify(postData) }, function (data) {
shapeLayer.redraw();
drawnItems.clearLayers();
});
postData.removeIds.length = 0;
postData.geoJsons.length = 0;
$('#btnStartingEdit').prop("disabled", false);
}
}
]
}).addTo(map);
// event after shapes drawn
map.on('draw:created', function (e) {
drawingLayer = e.layer;
drawingLayer.id = L.Util.guid();
drawnItems.addLayer(drawingLayer);
showDlg();
});
map.on('draw:deleted', function (e) {
var layers = e.layers;
layers.eachLayer(function (layer) {
postData.removeIds.push(layer.id);
});
});
$('.leaflet-draw-edit-edit').click(function (e) {
if (!editServerShapes) {
editServerShapes = true;
$.get(L.Util.getRootPath() + '/edit/getshapes', function (data) {
var geoJsons = JSON.parse(data);
for (var i = 0; i < geoJsons.length; i++) {
var vectorlayer = L.GeoJSON.geometryToLayer(geoJsons[i].geometry);
var coordinates = geoJsons[i].geometry.coordinates;
var geo;
switch (geoJsons[i].geometry.type) {
case 'LineString':
for (var j = 0; j < coordinates.length; j++) {
var tempX = coordinates[j][0];
coordinates[j][0] = coordinates[j][1];
coordinates[j][1] = tempX;
}
geo = new L.Polyline(coordinates);
break;
case 'Polygon':
for (var j = 0; j < coordinates[0].length; j++) {
var tempX = coordinates[0][j][0];
coordinates[0][j][0] = coordinates[0][j][1];
coordinates[0][j][1] = tempX;
}
var geo = new L.Polygon(coordinates[0]);
break;
case 'Point':
var tempX = coordinates[0];
coordinates[0] = coordinates[1];
coordinates[1] = tempX;
geo = new L.Polyline(coordinates);
break;
}
if (geoJsons[i].properties.name) {
geo.name = geoJsons[i].properties.name;
}
geo.setStyle({ color: '#f06eaa' });
geo.id = geoJsons[i].id;
postData.removeIds.push(geoJsons[i].id);
geo.editing.enable();
drawnItems.addLayer(geo);
}
map.removeLayer(shapeLayer);
});
}
});
$('#btnSaveName').click(function () {
if ($('#txtName').val() == //) {
$('#spWarning').show();
return;
} else {
$('#spWarning').hide();
}
// take the input name or description of the drawn shape
if (drawingLayer) {
drawingLayer.name = $('#txtName').val();
$('#txtName').val(//);
}
hideDlg();
});
// show/hide edit dialog in model mode
function showDlg() {
this.bgmask = L.DomUtil.create('div', 'bg-mask');
$('body').append(this.bgmask);
$('#dlgName').slideToggle("fast");
}
function hideDlg() {
$('.bg-mask').remove();
$('#dlgName').slideToggle("fast");
}
</script>
</body>
</html>
Default.htm(OpenLayers)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Draw edit features</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="author" content="ThinkGeo" />
<link rel="apple-touch-icon" href="desktop.png" />
<meta name="apple-mobile-web-app-title" content="Draw edit features" />
<link href="favicon.ico" rel="shortcut icon" type="Images/x-icon" />
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<link href="Content/ol.css" rel="stylesheet" />
<link href="Content/Site.css" rel="stylesheet" />
<link href="Content/thinkgeo.openlayers.css" rel="stylesheet" />
</head>
<body>
<div id="map">
</div>
<div id="bg-mask">
</div>
<div class="centroid">
<div id="dlgName">
<div class="edit-panel-header">
<span>The name of drawn shape</span>
</div>
<div class="edit-content">
<input type="text" id="txtName" />
<span id="spWarning" class="warning">The name is required.</span>
</div>
<div class="edit-foot">
<a id="btnSaveName" href="#" class="btn btn-primary" role="button">OK</a>
</div>
</div>
</div>
<script src="Scripts/jquery-1.11.1.min.js"></script>
<script src="Scripts/ol.js"></script>
<script src="thinkgeo.openlayers.js"></script>
<script>
var draw, editServerShapes = false;
var postData = { removeIds: [], geoJsons: [] };
var attribution = new ol.control.Attribution({
collapsible: false
});
// initialize the map
var map = new ol.Map({
target: 'map',
controls: ol.control.defaults({ attribution: false }).extend([attribution]),
view: new ol.View({
center: [-10777396.5012,|3914579.4368],
zoom: 16
})
});
// add image buttons for layers, edit, help etc.
var imgControls = new app.ImagesControl({
imgs: [{ | src: 'Images/Point.png',
title: 'Draw Point',
callback: function () {
removeModify();
removeDraw();
removeSelect();
addInteraction('Point');
}
}, {
src: 'Images/Line.png',
title: 'Draw Line',
callback: function () {
removeModify();
removeDraw();
removeSelect();
addInteraction('LineString');
}
}, {
src: 'Images/Polygon.png',
title: 'Draw Polygon',
callback: function () {
removeModify();
removeDraw();
removeSelect();
addInteraction('Polygon');
}
},
{
src: 'Images/Edit.png',
title: 'Edit Shape',
callback: function () {
if (!editServerShapes) {
editServerShapes = true;
$.get(getRootPath() + '/edit/getshapes', function (data) {
var geoJsons = JSON.parse(data);
for (var i = 0; i < geoJsons.length; i++) {
tempGeoJSON = geoJsons[i];
transfterGeoJSON(tempGeoJSON, getSphericalMercatorVertex);
var tempFeature = getFeatureFromGeoJson(tempGeoJSON);
featureOverlay.addFeature(tempFeature);
postData.removeIds.push(tempFeature.getId());
}
tileLayer.setVisible(false);
});
removeModify();
removeDraw();
removeSelect();
map.addInteraction(modify);
map.addInteraction(select);
}
}
},
{
src: 'Images/Delete.png',
title: 'Delete Polygon',
callback: function () {
removeModify();
removeDraw();
removeSelect();
var selectionFeatures = select.getFeatures();
selectionFeatures.on('add', deleteFeature);
map.addInteraction(select);
}
},
{
src: 'Images/save.png',
id: 'imgSave',
title: 'Save to server',
callback: function () {
var features = featureOverlay.getFeatures().getArray();
var featureLength = features.length;
for (var i = 0; i < featureLength; i++) {
var tempGeoJSON = getGeoJsonFromFeature(features[i]);
transfterGeoJSON(tempGeoJSON, getWgs84Vertex);
postData.geoJsons.push(tempGeoJSON);
}
// save the drawn features to server side in GeoJson format
$.post(getRootPath() + '/edit/add', { //: JSON.stringify(postData) }, function (data) {
xyzSource.setUrl(getRootPath() + "/edit/{z}/{x}/{y}");
tileLayer.setVisible(true);
});
for (var i = featureLength - 1; i > -1; i--) {
featureOverlay.removeFeature(features[i]);
}
postData.removeIds.length = 0;
postData.geoJsons.length = 0;
removeModify();
removeDraw();
removeSelect();
editServerShapes = false;
}
}
]
});
map.addControl(imgControls);
// ThinkGeo World Map
var worldmapkitlayer = new ol.layer.Tile({
source: new ol.source.TileWMS(({
urls: ['http://worldmapkit1.thinkgeo.com/CachedWMSServer/WmsServer.axd', | 'http://worldmapkit2.thinkgeo.com/CachedWMSServer/WmsServer.axd',
'http://worldmapkit3.thinkgeo.com/CachedWMSServer/WmsServer.axd',
'http://worldmapkit4.thinkgeo.com/CachedWMSServer/WmsServer.axd',
'http://worldmapkit5.thinkgeo.com/CachedWMSServer/WmsServer.axd',
'http://worldmapkit6.thinkgeo.com/CachedWMSServer/WmsServer.axd'],
params:
{
'LAYERS': 'OSMWorldMapKitLayer',
'VERSION': '1.1.1'
},
attributions: [new|ol.Attribution({
html: '<a href="http://thinkgeo.com/map-suite-developer-gis/world-map-kit-sdk/">ThinkGeo</a> | © <a href="http://osm.org/copyright">OpenStreetMap</a> contributors <a href="http://www.openstreetmap.org/copyright">ODbL</a>'
})]
}))
});
map.addLayer(worldmapkitlayer);
// layer including the drawn shapes which are saved to server side
var xyzSource = new ol.source.XYZ({
url: getRootPath() + "/edit/{z}/{x}/{y}",
maxZoom: 19
});
xyzSource.tileLoadFunction = function (imageTile, src) {
imageTile.getImage().src = src + '?t=' + new Date().getTime();;
};
var tileLayer = new ol.layer.Tile({
source: xyzSource
})
map.addLayer(tileLayer);
// Initialise the FeatureGroup to save editable layers
var featureOverlay = new ol.FeatureOverlay({
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(0, 153, 255, 0.4)'
}),
stroke: new ol.style.Stroke({
color: '#0099FF',
width: 3
}),
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#0099FF'
})
})
})
});
featureOverlay.setMap(map);
var select = new ol.interaction.Select({
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(240, 110, 170,0.2)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(240, 110, 170,0.5)',
width: 3
}),
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: 'rgba(240, 110, 170,0.2)'
})
})
})
});
// Initialise the draw control and pass it the FeatureGroup of editable layers
var modify = new ol.interaction.Modify({
features: select.getFeatures(),
// the SHIFT key must be pressed to delete vertices, so
// that new vertices can be drawn at the same position
// of existing vertices
deleteCondition: function (event) {
return ol.events.condition.shiftKeyOnly(event) &&
ol.events.condition.singleClick(event);
}
});
var creatingFeature;
function addInteraction(drawType) {
removeDraw();
draw = new ol.interaction.Draw({
features: featureOverlay.getFeatures(),
type: drawType
});
draw.on('drawend', function (e) {
var id = guid();
e.feature.setId(id);
creatingFeature = e.feature;
showDlg();
});
map.addInteraction(draw);
}
function removeDraw() {
if (draw) {
map.removeInteraction(draw);
}
}
function removeModify() {
if (modify) {
map.removeInteraction(modify);
}
}
function removeSelect() {
if (select) {
map.removeInteraction(select);
var selectionFeatures = select.getFeatures();
selectionFeatures.un('add', deleteFeature);
}
}
function transfterGeoJSON(geoJSON, transfer) {
var coordinates = geoJSON.geometry.coordinates;
switch (geoJSON.geometry.type) {
case 'LineString':
for (var j = 0; j < coordinates.length; j++) {
coordinates[j] = transfer(coordinates[j]);
}
break;
case 'Polygon':
for (var j = 0; j < coordinates[0].length; j++) {
coordinates[0][j] = transfer(coordinates[0][j]);
}
break;
case 'Point':
geoJSON.geometry.coordinates = transfer(coordinates);
break;
}
}
function getGeoJsonFromFeature(feature) {
var geoJSONFomat = new ol.format.GeoJSON();
var geoJSON = geoJSONFomat.writeFeature(feature);
var id = feature.getId();
if (id) {
geoJSON.id = id;
}
else {
geoJSON.id = guid();
}
return geoJSON;
}
function getFeatureFromGeoJson(geoJSON) {
var geoJSONFomat = new ol.format.GeoJSON();
var feature = geoJSONFomat.readFeature(geoJSON);
feature.setId(geoJSON.id);
return feature;
}
function getWgs84Vertex(vertex) {
return ol.proj.transform(vertex, 'EPSG:3857', 'EPSG:4326');
}
function getSphericalMercatorVertex(vertex) {
return ol.proj.transform(vertex, 'EPSG:4326', 'EPSG:3857');
}
var deleteFeature = function (e) {
var features = e.target.getArray();
if (features.length > 0) {
var id = features[0].getId();
featureOverlay.removeFeature(features[0]);
var selectionFeatures = select.getFeatures();
selectionFeatures.remove(features[0]);
postData.removeIds.push(id);
}
}
$('#btnSaveName').click(function () {
if ($('#txtName').val() == //) {
$('#spWarning').show();
return;
} else {
$('#spWarning').hide();
}
// take the input name or description of the drawn shape
if (creatingFeature) {
var shapeName = $('#txtName').val();
creatingFeature.setProperties({ name: shapeName });
$('#txtName').val(//);
creatingFeature = null;
}
hideDlg();
});
// show/hide edit dialog in model mode
function showDlg() {
$('#bg-mask').show();
$('#dlgName').slideToggle("fast");
}
function hideDlg() {
$('#bg-mask').hide();
$('#dlgName').slideToggle("fast");
}
</script>
</body>
</html>