Your search did not match any results.
Diagram

Templates with Editing

In this demo, the customShapeTemplate option defines a common shape template and adds the Edit and Delete links to a shape. These links allow users to modify and remove employee data from the data source. The Diagram widget reloads modified diagram data whenever the data source changes.

The onRequestLayoutUpdate function specifies whether the widget must reapply its auto layout once the diagram is reloaded.

The customDataExpr option links custom employee information from the data source to diagram nodes. Changes made to data are reflected in the diagram’s history. Undo and redo actions (available within the control’s UI) allow users to rollback/reapply changes.

The CustomShapeToolboxTemplate option specifies the template used for a shape within the toolbox.

Copy to CodePen
Apply
Reset
$(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.4/js/dx-diagram.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.4/css/dx.common.css" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/20.2.4/css/dx.light.css" /> <link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/20.2.4/css/dx-diagram.css" /> <script src="https://cdn3.devexpress.com/jslib/20.2.4/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" }];