edit-chart.html 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Organization Chart Plugin</title>
  6. <link rel="icon" href="img/logo.png">
  7. <link rel="stylesheet" href="css/font-awesome.min.css">
  8. <link rel="stylesheet" href="css/jquery.orgchart.css">
  9. <link rel="stylesheet" href="css/style.css">
  10. <style type="text/css">
  11. #chart-container { background-color: #eee; height: 500px; }
  12. .orgchart { background: #fff; }
  13. .orgchart.edit-state .edge { display: none; }
  14. .orgchart .node { width: 150px; }
  15. .orgchart .node .title { height: 30px; line-height: 30px; }
  16. .orgchart .node .title .symbol { margin-top: 1px; }
  17. #edit-panel {
  18. position: relative;
  19. left: 10px;
  20. width: calc(100% - 40px);
  21. border-radius: 4px;
  22. float: left;
  23. margin-top: 10px;
  24. padding: 10px;
  25. color: #fff;
  26. background-color: #449d44;
  27. }
  28. #edit-panel .btn-inputs { font-size: 24px; }
  29. #edit-panel.edit-state>:not(#chart-state-panel) { display: none; }
  30. #edit-panel label { font-weight: bold; }
  31. #edit-panel.edit-parent-node .selected-node-group { display: none; }
  32. #chart-state-panel, #selected-node, #btn-remove-input { margin-right: 20px; }
  33. #edit-panel button {
  34. color: #333;
  35. background-color: #fff;
  36. display: inline-block;
  37. padding: 6px 12px;
  38. margin-bottom: 0;
  39. line-height: 1.42857143;
  40. text-align: center;
  41. white-space: nowrap;
  42. vertical-align: middle;
  43. -ms-touch-action: manipulation;
  44. touch-action: manipulation;
  45. cursor: pointer;
  46. -webkit-user-select: none;
  47. -moz-user-select: none;
  48. -ms-user-select: none;
  49. user-select: none;
  50. background-image: none;
  51. border: 1px solid #ccc;
  52. border-radius: 4px;
  53. }
  54. #edit-panel.edit-parent-node button:not(#btn-add-nodes) { display: none; }
  55. #edit-panel button:hover,.edit-panel button:focus,.edit-panel button:active {
  56. border-color: #eea236;
  57. box-shadow: 0 0 10px #eea236;
  58. }
  59. #new-nodelist {
  60. display: inline-block;
  61. list-style:none;
  62. margin-top: -2px;
  63. padding: 0;
  64. vertical-align: text-top;
  65. }
  66. #new-nodelist>* { padding-bottom: 4px; }
  67. .btn-inputs { vertical-align: sub; }
  68. #edit-panel.edit-parent-node .btn-inputs { display: none; }
  69. .btn-inputs:hover { text-shadow: 0 0 4px #fff; }
  70. .radio-panel input[type='radio'] { display: inline-block;height: 24px;width: 24px;vertical-align: top; }
  71. #edit-panel.view-state .radio-panel input[type='radio']+label { vertical-align: -webkit-baseline-middle; }
  72. #btn-add-nodes { margin-left: 20px; }
  73. </style>
  74. </head>
  75. <body>
  76. <div id="chart-container"></div>
  77. <div id="edit-panel">
  78. <span id="chart-state-panel" class="radio-panel">
  79. <input type="radio" name="chart-state" id="rd-view" value="view"><label for="rd-view">View</label>
  80. <input type="radio" name="chart-state" id="rd-edit" value="edit" checked="true"><label for="rd-edit">Edit</label>
  81. </span>
  82. <label class="selected-node-group">selected node:</label>
  83. <input type="text" id="selected-node" class="selected-node-group">
  84. <label>new node:</label>
  85. <ul id="new-nodelist">
  86. <li><input type="text" class="new-node"></li>
  87. </ul>
  88. <i class="fa fa-plus-circle btn-inputs" id="btn-add-input"></i>
  89. <i class="fa fa-minus-circle btn-inputs" id="btn-remove-input"></i>
  90. <span id="node-type-panel" class="radio-panel">
  91. <input type="radio" name="node-type" id="rd-parent" value="parent"><label for="rd-parent">Parent(root)</label>
  92. <input type="radio" name="node-type" id="rd-child" value="children"><label for="rd-child">Child</label>
  93. <input type="radio" name="node-type" id="rd-sibling" value="siblings"><label for="rd-sibling">Sibling</label>
  94. </span>
  95. <button type="button" id="btn-add-nodes">Add</button>
  96. <button type="button" id="btn-delete-nodes">Delete</button>
  97. <button type="button" id="btn-reset">Reset</button>
  98. </div>
  99. <script type="text/javascript" src="js/jquery.min.js"></script>
  100. <script type="text/javascript" src="js/html2canvas.min.js"></script>
  101. <script type="text/javascript" src="js/jquery.orgchart.js"></script>
  102. <script type="text/javascript">
  103. $(function() {
  104. var datascource = {
  105. 'name': 'Ball game',
  106. 'children': [
  107. { 'name': 'Football' },
  108. { 'name': 'Basketball' },
  109. { 'name': 'Volleyball' }
  110. ]
  111. };
  112. var getId = function() {
  113. return (new Date().getTime()) * 1000 + Math.floor(Math.random() * 1001);
  114. };
  115. var oc = $('#chart-container').orgchart({
  116. 'data': datascource,
  117. 'zoom':true,
  118. 'pan': true,
  119. //'direction':'l2r',
  120. 'chartClass': 'edit-state',
  121. 'exportButton': true,
  122. 'exportFilename': 'SportsChart',
  123. 'parentNodeSymbol': 'fa-th-large',
  124. 'createNode': function($node, data) {
  125. $node[0].id = getId();
  126. }
  127. });
  128. oc.$chartContainer.on('click', '.node', function() {
  129. var $this = $(this);
  130. $('#selected-node').val($this.find('.title').text()).data('node', $this);
  131. });
  132. oc.$chartContainer.on('click', '.orgchart', function(event) {
  133. if (!$(event.target).closest('.node').length) {
  134. $('#selected-node').val('');
  135. }
  136. });
  137. $('input[name="chart-state"]').on('click', function() {
  138. $('.orgchart').toggleClass('edit-state', this.value !== 'view');
  139. $('#edit-panel').toggleClass('edit-state', this.value === 'view');
  140. if ($(this).val() === 'edit') {
  141. $('.orgchart').find('tr').removeClass('hidden')
  142. .find('td').removeClass('hidden')
  143. .find('.node').removeClass('slide-up slide-down slide-right slide-left');
  144. } else {
  145. $('#btn-reset').trigger('click');
  146. }
  147. });
  148. $('input[name="node-type"]').on('click', function() {
  149. var $this = $(this);
  150. if ($this.val() === 'parent') {
  151. $('#edit-panel').addClass('edit-parent-node');
  152. $('#new-nodelist').children(':gt(0)').remove();
  153. } else {
  154. $('#edit-panel').removeClass('edit-parent-node');
  155. }
  156. });
  157. $('#btn-add-input').on('click', function() {
  158. $('#new-nodelist').append('<li><input type="text" class="new-node"></li>');
  159. });
  160. $('#btn-remove-input').on('click', function() {
  161. var inputs = $('#new-nodelist').children('li');
  162. if (inputs.length > 1) {
  163. inputs.last().remove();
  164. }
  165. });
  166. $('#btn-add-nodes').on('click', function() {
  167. var $chartContainer = $('#chart-container');
  168. var nodeVals = [];
  169. $('#new-nodelist').find('.new-node').each(function(index, item) {
  170. var validVal = item.value.trim();
  171. if (validVal.length) {
  172. nodeVals.push(validVal);
  173. }
  174. });
  175. var $node = $('#selected-node').data('node');
  176. console.log($node);
  177. if (!nodeVals.length) {
  178. alert('Please input value for new node');
  179. return;
  180. }
  181. var nodeType = $('input[name="node-type"]:checked');
  182. if (!nodeType.length) {
  183. alert('Please select a node type');
  184. return;
  185. }
  186. if (nodeType.val() !== 'parent' && !$('.orgchart').length) {
  187. alert('Please creat the root node firstly when you want to build up the orgchart from the scratch');
  188. return;
  189. }
  190. if (nodeType.val() !== 'parent' && !$node) {
  191. alert('Please select one node in orgchart');
  192. return;
  193. }
  194. if (nodeType.val() === 'parent') {
  195. if (!$chartContainer.children('.orgchart').length) {// if the original chart has been deleted
  196. oc = $chartContainer.orgchart({
  197. 'data' : { 'name': nodeVals[0] },
  198. 'exportButton': true,
  199. 'exportFilename': 'SportsChart',
  200. 'parentNodeSymbol': 'fa-th-large',
  201. 'createNode': function($node, data) {
  202. $node[0].id = getId();
  203. }
  204. });
  205. oc.$chart.addClass('view-state');
  206. } else {
  207. oc.addParent($chartContainer.find('.node:first'), { 'name': nodeVals[0], 'id': getId() });
  208. }
  209. } else if (nodeType.val() === 'siblings') {
  210. if ($node[0].id === oc.$chart.find('.node:first')[0].id) {
  211. alert('You are not allowed to directly add sibling nodes to root node');
  212. return;
  213. }
  214. oc.addSiblings($node, nodeVals.map(function (item) {
  215. return { 'name': item, 'relationship': '110', 'id': getId() };
  216. }));
  217. } else {
  218. var hasChild = $node.parent().attr('colspan') > 0 ? true : false;
  219. if (!hasChild) {
  220. var rel = nodeVals.length > 1 ? '110' : '100';
  221. oc.addChildren($node, nodeVals.map(function (item) {
  222. return { 'name': item, 'relationship': rel, 'id': getId() };
  223. }));
  224. } else {
  225. oc.addSiblings($node.closest('tr').siblings('.nodes').find('.node:first'), nodeVals.map(function (item) {
  226. return { 'name': item, 'relationship': '110', 'id': getId() };
  227. }));
  228. }
  229. }
  230. });
  231. $('#btn-delete-nodes').on('click', function() {
  232. var $node = $('#selected-node').data('node');
  233. if (!$node) {
  234. alert('Please select one node in orgchart');
  235. return;
  236. } else if ($node[0] === $('.orgchart').find('.node:first')[0]) {
  237. if (!window.confirm('Are you sure you want to delete the whole chart?')) {
  238. return;
  239. }
  240. }
  241. oc.removeNodes($node);
  242. $('#selected-node').val('').data('node', null);
  243. });
  244. $('#btn-reset').on('click', function() {
  245. $('.orgchart').find('.focused').removeClass('focused');
  246. $('#selected-node').val('');
  247. $('#new-nodelist').find('input:first').val('').parent().siblings().remove();
  248. $('#node-type-panel').find('input').prop('checked', false);
  249. });
  250. });
  251. </script>
  252. </body>
  253. </html>