$(function() {
var generatedID = 100;
var store = new DevExpress.data.ArrayStore({
key: "ID",
data: employees,
onInserting: function(values) {
values.ID = values.ID || generatedID++;
values.Full_Name = values.Full_Name || "Employee's Name";
values.Title = values.Title || "Employee's Title";
}
});
var diagram = $("#diagram").dxDiagram({
customShapes: [{
type: "employee",
category: "employee",
baseType: "rectangle",
title: "New Employee",
defaultWidth: 1.5,
defaultHeight: 1,
toolboxWidthToHeightRatio: 2,
minWidth: 1.5,
minHeight: 1,
maxWidth: 3,
maxHeight: 2,
allowEditText: false
}],
customShapeTemplate: function(item, $container) {
var employee = item.dataItem;
var svgNS = "http://www.w3.org/2000/svg";
var $content = $(document.createElementNS(svgNS, "svg")).addClass("template");
$(document.createElementNS(svgNS, "text"))
.addClass("template-name")
.attr({ x: "50%", y: "20%" })
.text(employee ? employee.Full_Name : "Employee's Name")
.appendTo($content);
$(document.createElementNS(svgNS, "text"))
.addClass("template-title")
.attr({ x: "50%", y: "45%" })
.text(employee ? employee.Title : "Employee's Title")
.appendTo($content);
$(document.createElementNS(svgNS, "text"))
.addClass("template-button")
.attr({ id: "employee-edit", x: "40%", y: "85%" })
.text("Edit")
.click(function() { editEmployee(employee); })
.appendTo($content);
$(document.createElementNS(svgNS, "text"))
.addClass("template-button")
.attr({ id: "employee-delete", x: "62%", y: "85%" })
.text("Delete")
.click(function() { deleteEmployee(employee); })
.appendTo($content);
$container.append($content);
},
customShapeToolboxTemplate: function(item, $container) {
var employee = item.dataItem;
var $content = $("<svg class='template'>" +
"<text x='50%' y='40%'>New</text>" +
"<text x='50%' y='70%'>Employee</text>" +
"</svg >");
$container.append($content);
},
nodes: {
dataSource: store,
keyExpr: "ID",
typeExpr: function(obj) { return "employee"; },
parentKeyExpr: "Head_ID",
customDataExpr: function(obj, value) {
if(value === undefined) {
return {
"Full_Name": obj.Full_Name,
"Prefix": obj.Prefix,
"Title": obj.Title,
"City": obj.City,
"State": obj.State,
"Email": obj.Email,
"Skype": obj.Skype,
"Mobile_Phone": obj.Mobile_Phone
};
} else {
obj.Full_Name = value.Full_Name;
obj.Prefix = value.Prefix;
obj.Title = value.Title;
obj.City = value.City;
obj.State = value.State;
obj.Email = value.Email;
obj.Skype = value.Skype;
obj.Mobile_Phone = value.Mobile_Phone;
}
},
autoLayout: {
type: "tree"
}
},
onRequestLayoutUpdate: function(e) {
for(var i = 0; i < e.changes.length; i++) {
if(e.changes[i].type === 'remove')
e.allowed = true;
else if(e.changes[i].data.Head_ID !== undefined && e.changes[i].data.Head_ID !== null)
e.allowed = true;
}
},
contextToolbox: {
shapeIconsPerRow: 1,
width: 100
},
toolbox: {
shapeIconsPerRow: 1,
showSearch: false,
groups: [
{ category: "employee", title: "Employee", expanded: true }
]
},
propertiesPanel: {
tabs: [
{
groups: [ { title: "Page Properties", commands: ["pageSize", "pageOrientation", "pageColor"] } ]
}
]
}
}).dxDiagram("instance");
var popupContentTemplate = function($container) {
var $editorsContainer = $("<div class=\"dx-fieldset\" />").appendTo($container);
var $nameField = $("<div class=\"dx-field\"><div class=\"dx-field-label\">Name</div><div class=\"dx-field-value\" data-field=\"Full_Name\" /></div>");
$nameField.find(".dx-field-value").append("<div />").dxTextBox();
var $titleField = $("<div class=\"dx-field\"><div class=\"dx-field-label\">Title</div><div class=\"dx-field-value\" data-field=\"Title\" /></div>");
$titleField.find(".dx-field-value").append("<div /").dxTextBox();
var $cityField = $("<div class=\"dx-field\"><div class=\"dx-field-label\">City</div><div class=\"dx-field-value\" data-field=\"City\" /></div>");
$cityField.find(".dx-field-value").append("<div /").dxTextBox();
var $stateField = $("<div class=\"dx-field\"><div class=\"dx-field-label\">State</div><div class=\"dx-field-value\" data-field=\"State\" /></div>");
$stateField.find(".dx-field-value").append("<div /").dxTextBox();
var $emailField = $("<div class=\"dx-field\"><div class=\"dx-field-label\">Email</div><div class=\"dx-field-value\" data-field=\"Email\" /></div>");
$emailField.find(".dx-field-value").append("<div /").dxTextBox();
var $skypeField = $("<div class=\"dx-field\"><div class=\"dx-field-label\">Skype</div><div class=\"dx-field-value\" data-field=\"Skype\" /></div>");
$skypeField.find(".dx-field-value").append("<div /").dxTextBox();
var $phoneField = $("<div class=\"dx-field\"><div class=\"dx-field-label\">Phone</div><div class=\"dx-field-value\" data-field=\"Mobile_Phone\" /></div>");
$phoneField.find(".dx-field-value").append("<div /").dxTextBox();
$editorsContainer.append($nameField, $titleField, $cityField, $stateField, $emailField, $skypeField, $phoneField);
var $buttonsContainer = $("<div class=\"dx-fieldset buttons\" />").appendTo($container);
$buttonsContainer.append(
$("<button />").dxButton({
text: "Update",
type: "default",
onClick: updateEmployee
}),
$("<button />").dxButton({
text: "Cancel",
onClick: cancelEditEmployee
})
);
};
var popup = $("#popup").dxPopup({
width: 400,
height: 480,
showTitle: true,
title: "Edit Employee",
visible: false,
dragEnabled: false,
contentTemplate: popupContentTemplate.bind(this)
}).dxPopup("instance");
var currentEmployee = {};
var editEmployee = function(employee) {
currentEmployee = Object.assign({}, employee);
popup.show();
popup.content().find(".dx-field-value").each(function() {
var field = $(this).attr("data-field");
var edit = $(this).dxTextBox("instance");
edit.option({
value: currentEmployee[field],
onValueChanged: function(e) { handleChange(field, e.value); }
});
});
};
var deleteEmployee = function(employee) {
store.push([{ type: 'remove', key: employee.ID }]);
};
var updateEmployee = function() {
store.push([{
type: 'update',
key: currentEmployee.ID,
data: {
"Full_Name": currentEmployee.Full_Name,
"Title": currentEmployee.Title,
"City": currentEmployee.City,
"State": currentEmployee.State,
"Email": currentEmployee.Email,
"Skype": currentEmployee.Skype,
"Mobile_Phone": currentEmployee.Mobile_Phone
}
}]);
popup.hide();
};
var cancelEditEmployee = function() {
currentEmployee = {};
popup.hide();
}
var handleChange = function(field, value) {
currentEmployee[field] = value;
}
});
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DevExtreme Demo</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>window.jQuery || document.write(decodeURIComponent('%3Cscript src="js/jquery.min.js"%3E%3C/script%3E'))</script>
<script src="https://cdn3.devexpress.com/jslib/20.2.5/js/dx-diagram.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.5/css/dx.common.css" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.5/css/dx.light.css" />
<link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/20.2.5/css/dx-diagram.css" />
<script src="https://cdn3.devexpress.com/jslib/20.2.5/js/dx.all.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="data.js"></script>
<script src="index.js"></script>
</head>
<body class="dx-viewport">
<div class="demo-container">
<div id="diagram">
</div>
<div id="popup">
</div>
</div>
</body>
</html>
#diagram {
height: 725px;
}
#diagram .template .template-name {
font-weight: bold;
text-decoration: underline;
}
#diagram .template .template-title {
font-style: italic;
}
#diagram .template .template-button {
cursor: pointer;
font-size: 8pt;
fill: navy;
}
#diagram .template .template-button:hover {
text-decoration: underline;
}
.dx-popup-content {
padding: 0;
}
.dx-popup-content .dx-fieldset.buttons {
display: flex;
justify-content: flex-end;
}
.dx-popup-content .dx-fieldset.buttons > * {
margin-left: 8px;
}
var employees = [{
"ID": 1,
"Head_ID": 0,
"Full_Name": "John Heart",
"Prefix": "Mr.",
"Title": "CEO",
"City": "Los Angeles",
"State": "California",
"Email": "jheart@dx-email.com",
"Skype": "jheart_DX_skype",
"Mobile_Phone": "(213) 555-9392",
"Birth_Date": "1964-03-16",
"Hire_Date": "1995-01-15"
}, {
"ID": 2,
"Head_ID": 1,
"Full_Name": "Samantha Bright",
"Prefix": "Dr.",
"Title": "COO",
"City": "Los Angeles",
"State": "California",
"Email": "samanthab@dx-email.com",
"Skype": "samanthab_DX_skype",
"Mobile_Phone": "(213) 555-2858",
"Birth_Date": "1966-05-02",
"Hire_Date": "2004-05-24"
}, {
"ID": 3,
"Head_ID": 1,
"Full_Name": "Arthur Miller",
"Prefix": "Mr.",
"Title": "CTO",
"City": "Denver",
"State": "Colorado",
"Email": "arthurm@dx-email.com",
"Skype": "arthurm_DX_skype",
"Mobile_Phone": "(310) 555-8583",
"Birth_Date": "1972-07-11",
"Hire_Date": "2007-12-18"
}, {
"ID": 4,
"Head_ID": 1,
"Full_Name": "Robert Reagan",
"Prefix": "Mr.",
"Title": "CMO",
"City": "Bentonville",
"State": "Arkansas",
"Email": "robertr@dx-email.com",
"Skype": "robertr_DX_skype",
"Mobile_Phone": "(818) 555-2387",
"Birth_Date": "1974-09-07",
"Hire_Date": "2002-11-08"
}, {
"ID": 5,
"Head_ID": 1,
"Full_Name": "Greta Sims",
"Prefix": "Ms.",
"Title": "HR Manager",
"City": "Atlanta",
"State": "Georgia",
"Email": "gretas@dx-email.com",
"Skype": "gretas_DX_skype",
"Mobile_Phone": "(818) 555-6546",
"Birth_Date": "1977-11-22",
"Hire_Date": "1998-04-23"
}, {
"ID": 6,
"Head_ID": 3,
"Full_Name": "Brett Wade",
"Prefix": "Mr.",
"Title": "IT Manager",
"City": "Reno",
"State": "Nevada",
"Email": "brettw@dx-email.com",
"Skype": "brettw_DX_skype",
"Mobile_Phone": "(626) 555-0358",
"Birth_Date": "1968-12-01",
"Hire_Date": "2009-03-06"
}, {
"ID": 7,
"Head_ID": 5,
"Full_Name": "Sandra Johnson",
"Prefix": "Mrs.",
"Title": "Controller",
"City": "Beaver",
"State": "Utah",
"Email": "sandraj@dx-email.com",
"Skype": "sandraj_DX_skype",
"Mobile_Phone": "(562) 555-2082",
"Birth_Date": "1974-11-15",
"Hire_Date": "2005-05-11"
}, {
"ID": 8,
"Head_ID": 4,
"Full_Name": "Ed Holmes",
"Prefix": "Dr.",
"Title": "Sales Manager",
"City": "Malibu",
"State": "California",
"Email": "edwardh@dx-email.com",
"Skype": "edwardh_DX_skype",
"Mobile_Phone": "(310) 555-1288",
"Birth_Date": "1973-07-14",
"Hire_Date": "2005-06-19"
}, {
"ID": 9,
"Head_ID": 3,
"Full_Name": "Barb Banks",
"Prefix": "Mrs.",
"Title": "Support Manager",
"City": "Phoenix",
"State": "Arizona",
"Email": "barbarab@dx-email.com",
"Skype": "barbarab_DX_skype",
"Mobile_Phone": "(310) 555-3355",
"Birth_Date": "1979-04-14",
"Hire_Date": "2002-08-07"
}, {
"ID": 10,
"Head_ID": 2,
"Full_Name": "Kevin Carter",
"Prefix": "Mr.",
"Title": "Shipping Manager",
"City": "San Diego",
"State": "California",
"Email": "kevinc@dx-email.com",
"Skype": "kevinc_DX_skype",
"Mobile_Phone": "(213) 555-2840",
"Birth_Date": "1978-01-09",
"Hire_Date": "2009-08-11"
}, {
"ID": 11,
"Head_ID": 5,
"Full_Name": "Cindy Stanwick",
"Prefix": "Ms.",
"Title": "HR Assistant",
"City": "Little Rock",
"State": "Arkansas",
"Email": "cindys@dx-email.com",
"Skype": "cindys_DX_skype",
"Mobile_Phone": "(818) 555-6655",
"Birth_Date": "1985-06-05",
"Hire_Date": "2008-03-24"
}, {
"ID": 12,
"Head_ID": 8,
"Full_Name": "Sammy Hill",
"Prefix": "Mr.",
"Title": "Sales Assistant",
"City": "Pasadena",
"State": "California",
"Email": "sammyh@dx-email.com",
"Skype": "sammyh_DX_skype",
"Mobile_Phone": "(626) 555-7292",
"Birth_Date": "1984-02-17",
"Hire_Date": "2012-02-01"
}, {
"ID": 13,
"Head_ID": 10,
"Full_Name": "Davey Jones",
"Prefix": "Mr.",
"Title": "Shipping Assistant",
"City": "Pasadena",
"State": "California",
"Email": "davidj@dx-email.com",
"Skype": "davidj_DX_skype",
"Mobile_Phone": "(626) 555-0281",
"Birth_Date": "1983-03-06",
"Hire_Date": "2011-04-24"
}, {
"ID": 14,
"Head_ID": 10,
"Full_Name": "Victor Norris",
"Prefix": "Mr.",
"Title": "Shipping Assistant",
"City": "Little Rock",
"State": "Arkansas",
"Email": "victorn@dx-email.com",
"Skype": "victorn_DX_skype",
"Mobile_Phone": "(213) 555-9278",
"Birth_Date": "1986-07-23",
"Hire_Date": "2012-07-23"
}, {
"ID": 15,
"Head_ID": 10,
"Full_Name": "Mary Stern",
"Prefix": "Ms.",
"Title": "Shipping Assistant",
"City": "Beaver",
"State": "Utah",
"Email": "marys@dx-email.com",
"Skype": "marys_DX_skype",
"Mobile_Phone": "(818) 555-7857",
"Birth_Date": "1982-04-08",
"Hire_Date": "2012-08-12"
}, {
"ID": 16,
"Head_ID": 10,
"Full_Name": "Robin Cosworth",
"Prefix": "Mrs.",
"Title": "Shipping Assistant",
"City": "Los Angeles",
"State": "California",
"Email": "robinc@dx-email.com",
"Skype": "robinc_DX_skype",
"Mobile_Phone": "(818) 555-0942",
"Birth_Date": "1981-06-12",
"Hire_Date": "2012-09-01"
}, {
"ID": 17,
"Head_ID": 9,
"Full_Name": "Kelly Rodriguez",
"Prefix": "Ms.",
"Title": "Support Assistant",
"City": "Boise",
"State": "Idaho",
"Email": "kellyr@dx-email.com",
"Skype": "kellyr_DX_skype",
"Mobile_Phone": "(818) 555-9248",
"Birth_Date": "1988-05-11",
"Hire_Date": "2012-10-13"
}, {
"ID": 18,
"Head_ID": 9,
"Full_Name": "James Anderson",
"Prefix": "Mr.",
"Title": "Support Assistant",
"City": "Atlanta",
"State": "Georgia",
"Email": "jamesa@dx-email.com",
"Skype": "jamesa_DX_skype",
"Mobile_Phone": "(323) 555-4702",
"Birth_Date": "1987-01-29",
"Hire_Date": "2012-10-18"
}, {
"ID": 19,
"Head_ID": 9,
"Full_Name": "Antony Remmen",
"Prefix": "Mr.",
"Title": "Support Assistant",
"City": "Boise",
"State": "Idaho",
"Email": "anthonyr@dx-email.com",
"Skype": "anthonyr_DX_skype",
"Mobile_Phone": "(310) 555-6625",
"Birth_Date": "1986-02-19",
"Hire_Date": "2013-01-19"
}, {
"ID": 20,
"Head_ID": 8,
"Full_Name": "Olivia Peyton",
"Prefix": "Mrs.",
"Title": "Sales Assistant",
"City": "Atlanta",
"State": "Georgia",
"Email": "oliviap@dx-email.com",
"Skype": "oliviap_DX_skype",
"Mobile_Phone": "(310) 555-2728",
"Birth_Date": "1981-06-03",
"Hire_Date": "2012-05-14"
}, {
"ID": 21,
"Head_ID": 6,
"Full_Name": "Taylor Riley",
"Prefix": "Mr.",
"Title": "Network Admin",
"City": "San Jose",
"State": "California",
"Email": "taylorr@dx-email.com",
"Skype": "taylorr_DX_skype",
"Mobile_Phone": "(310) 555-7276",
"Birth_Date": "1982-08-14",
"Hire_Date": "2012-04-14"
}, {
"ID": 22,
"Head_ID": 6,
"Full_Name": "Amelia Harper",
"Prefix": "Mrs.",
"Title": "Network Admin",
"City": "Los Angeles",
"State": "California",
"Email": "ameliah@dx-email.com",
"Skype": "ameliah_DX_skype",
"Mobile_Phone": "(213) 555-4276",
"Birth_Date": "1983-11-19",
"Hire_Date": "2011-02-10"
}, {
"ID": 23,
"Head_ID": 6,
"Full_Name": "Wally Hobbs",
"Prefix": "Mr.",
"Title": "Programmer",
"City": "Chatsworth",
"State": "California",
"Email": "wallyh@dx-email.com",
"Skype": "wallyh_DX_skype",
"Mobile_Phone": "(818) 555-8872",
"Birth_Date": "1984-12-24",
"Hire_Date": "2011-02-17"
}, {
"ID": 24,
"Head_ID": 6,
"Full_Name": "Brad Jameson",
"Prefix": "Mr.",
"Title": "Programmer",
"City": "San Fernando",
"State": "California",
"Email": "bradleyj@dx-email.com",
"Skype": "bradleyj_DX_skype",
"Mobile_Phone": "(818) 555-4646",
"Birth_Date": "1988-10-12",
"Hire_Date": "2011-03-02"
}, {
"ID": 25,
"Head_ID": 6,
"Full_Name": "Karen Goodson",
"Prefix": "Miss",
"Title": "Programmer",
"City": "South Pasadena",
"State": "California",
"Email": "kareng@dx-email.com",
"Skype": "kareng_DX_skype",
"Mobile_Phone": "(626) 555-0908",
"Birth_Date": "1987-04-26",
"Hire_Date": "2011-03-14"
}, {
"ID": 26,
"Head_ID": 5,
"Full_Name": "Marcus Orbison",
"Prefix": "Mr.",
"Title": "Travel Coordinator",
"City": "Los Angeles",
"State": "California",
"Email": "marcuso@dx-email.com",
"Skype": "marcuso_DX_skype",
"Mobile_Phone": "(213) 555-7098",
"Birth_Date": "1982-03-02",
"Hire_Date": "2005-05-19"
}];