Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
tree.phtml
Go to the documentation of this file.
1 <?php
7 // @codingStandardsIgnoreFile
8 
9 ?>
10 <div class="categories-side-col">
11  <div class="sidebar-actions">
12  <?php if ($block->getRoot()): ?>
13  <?= $block->getAddRootButtonHtml() ?><br/>
14  <?= $block->getAddSubButtonHtml() ?>
15  <?php endif; ?>
16  </div>
17  <div class="tree-actions">
18  <?php if ($block->getRoot()): ?>
19  <?php //echo $block->getCollapseButtonHtml() ?>
20  <?php //echo $block->getExpandButtonHtml() ?>
21  <a href="#"
22  onclick="tree.collapseTree(); return false;"><?= /* @escapeNotVerified */ __('Collapse All') ?></a>
23  <span class="separator">|</span> <a href="#"
24  onclick="tree.expandTree(); return false;"><?= /* @escapeNotVerified */ __('Expand All') ?></a>
25  <?php endif; ?>
26  </div>
27  <?php if ($block->getRoot()): ?>
28  <div class="tree-holder">
29  <div id="tree-div" class="tree-wrapper"></div>
30  </div>
31 </div>
32 
33  <div data-id="information-dialog-tree" class="messages" style="display: none;">
34  <div class="message message-notice">
35  <div><?= /* @escapeNotVerified */ __('This operation can take a long time') ?></div>
36  </div>
37  </div>
38  <script>
39  var tree;
40  require([
41  "jquery",
42  'Magento_Ui/js/modal/modal',
43  "jquery/ui",
44  "prototype",
45  "extjs/ext-tree-checkbox",
46  "mage/adminhtml/form",
47  "mage/translate"
48  ], function (jQuery, modal) {
49 
50  var registry = {
51  data: [],
52 
53  set: function (key, value) {
54  this.data[key] = value;
55  },
56 
57  get: function (key) {
58  return this.data[key];
59  }
60  };
61 
62  var treeRoot = '#tree-div';
63 
67  Ext.lib.Event.getTarget = function (e) {
68  var ee = e.browserEvent || e;
69  return ee.target ? Event.element(ee) : null;
70  };
71 
72  Ext.tree.TreePanel.Enhanced = function (el, config) {
73  Ext.tree.TreePanel.Enhanced.superclass.constructor.call(this, el, config);
74  };
75 
76  Ext.extend(Ext.tree.TreePanel.Enhanced, Ext.tree.TreePanel, {
77 
78  loadTree: function (config, firstLoad) {
79  var parameters = config['parameters'];
80  var data = config['data'];
81 
82  this.storeId = parameters['store_id'];
83 
84  if (this.storeId != 0 && $('add_root_category_button')) {
85  $('add_root_category_button').hide();
86  }
87 
88  if ((typeof parameters['root_visible']) != 'undefined') {
89  this.rootVisible = parameters['root_visible'] * 1;
90  }
91 
92  var root = new Ext.tree.TreeNode(parameters);
93 
94  this.nodeHash = {};
95  this.setRootNode(root);
96  this.modal = modal;
97 
98  if (firstLoad) {
99  this.addListener('click', this.categoryClick);
100  this.addListener('beforenodedrop', categoryMove.bind(this));
101  }
102 
103  this.loader.buildCategoryTree(root, data);
104  this.el.dom.innerHTML = '';
105  // render the tree
106  this.render();
107  if (parameters['expanded']) {
108  this.expandAll();
109  } else {
110  root.expand();
111  }
112 
113  var selectedNode = this.getNodeById(parameters['category_id']);
114  if (selectedNode) {
115  this.currentNodeId = parameters['category_id'];
116  } else {
117  if (parameters['parent'] > 0 && parameters['category_id'] === 0) {
118  this.currentNodeId = parameters['parent'];
119  }
120  }
121  this.selectCurrentNode();
122 
123  // Temporary solution will be replaced after refactoring of tree functionality
124  jQuery('body').off('tabsactivate.tree').on('tabsactivate.tree', jQuery.proxy(function (e, ui) {
125  this.activeTab = jQuery(ui.newTab).find('a').prop('id');
126  }, this))
127  },
128 
129  request: function (url, params) {
130  if (!params) {
131  if (this.activeTab) {
132  var params = {active_tab_id: this.activeTab};
133  }
134  else {
135  var params = {};
136  }
137  }
138  if (!params.form_key) {
139  params.form_key = FORM_KEY;
140  }
141  var result = new Ajax.Request(
142  url + (url.match(new RegExp('\\?')) ? '&isAjax=true' : '?isAjax=true' ),
143  {
144  parameters: params,
145  method: 'post'
146  }
147  );
148 
149  return result;
150  },
151 
152  selectCurrentNode: function () {
153  var selectedNode = this.getNodeById(this.currentNodeId);
154 
155  if (selectedNode) {
156  if ((typeof selectedNode.attributes.path) != 'undefined') {
157  var path = selectedNode.attributes.path;
158  if (!this.storeId) {
159  path = '0/' + path;
160  }
161  this.selectPath(path);
162  } else {
163  this.getSelectionModel().select(selectedNode);
164  }
165  }
166  },
167 
168  collapseTree: function () {
169  this.collapseAll();
170 
171  this.selectCurrentNode();
172 
173  if (!this.collapsed) {
174  this.collapsed = true;
175  this.loader.dataUrl = '<?= /* @escapeNotVerified */ $block->getLoadTreeUrl(false) ?>';
176  this.request(this.loader.dataUrl, false);
177  }
178  },
179 
180  expandTree: function () {
181  this.expandAll();
182  if (this.collapsed) {
183  this.collapsed = false;
184  this.loader.dataUrl = '<?= /* @escapeNotVerified */ $block->getLoadTreeUrl(true) ?>';
185  this.request(this.loader.dataUrl, false);
186  }
187  },
188 
189  categoryClick: function (node, e) {
190  var url = this.buildUrl(node.id);
191 
192  this.currentNodeId = node.id;
193  if (!this.useAjax) {
194  setLocation(url);
195  return;
196  }
197  if (this.activeTab) {
198  var params = {active_tab_id: this.activeTab};
199  }
200  updateContent(url, params);
201  },
202 
203  buildUrl: function (id) {
204  var urlExt = (this.storeId ? 'store/' + this.storeId + '/' : '') + 'id/' + id + '/';
205 
206  return parseSidUrl(this.baseUrl, urlExt);
207  },
208 
209  getBaseUrl: function () {
210  return this.baseUrl;
211  }
212  });
213 
214  function reRenderTree(switcherParams) {
215  // re-render tree by store switcher
216  if (tree && switcherParams) {
217  var url;
218  if (switcherParams.useConfirm) {
219  if (!confirm("<?= /* @escapeNotVerified */ __('Please confirm site switching. All data that hasn\'t been saved will be lost.') ?>")) {
220  return false;
221  }
222  }
223 
224  if ($('add_root_category_button')) {
225  if (!switcherParams.scopeId) {
226  $('add_root_category_button').show();
227  }
228  else {
229  $('add_root_category_button').hide();
230  }
231  }
232 
233  if (tree.useAjax) {
234  // retain current selected category id
235  url = tree.switchTreeUrl + switcherParams.scopeParams + 'id/' + tree.currentNodeId + '/';
236  // load from cache
237  // load from ajax
238  // add form key
239  var params = {
240  form_key: FORM_KEY
241  };
242  new Ajax.Request(url + (url.match(new RegExp('\\?')) ? '&isAjax=true' : '?isAjax=true' ), {
243  parameters: params,
244  method: 'post',
245  onComplete: function (transport) {
246  var response;
247 
248  try {
249  response = JSON.parse(transport.responseText);
250  } catch (e) {
251  console.warn('An error occured while parsing response');
252  }
253 
254  if (!response || !response['parameters']) {
255  return false;
256  }
257 
258  _renderNewTree(response, switcherParams.scopeParams);
259  }
260  });
261  } else {
262  var baseUrl = '<?= /* @escapeNotVerified */ $block->getEditUrl() ?>';
263  var urlExt = switcherParams.scopeParams + 'id/' + tree.currentNodeId + '/';
264  url = parseSidUrl(baseUrl, urlExt);
265  setLocation(url);
266  }
267  }
268  // render default tree
269  else {
270  _renderNewTree();
271  }
272  }
273 
274  function _renderNewTree(config, scopeParams) {
275  if (!config) {
276  var config = defaultLoadTreeParams;
277  }
278 
279  if (tree) {
280  tree.purgeListeners();
281  tree.el.dom.innerHTML = '';
282  }
283  tree = new Ext.tree.TreePanel.Enhanced('tree-div', newTreeParams);
284 
285  tree.loadTree(config, true);
286 
287  // try to select current category
288  var selectedNode = tree.getNodeById(config.parameters.category_id);
289  if (selectedNode) {
290  tree.currentNodeId = config.parameters.category_id;
291  }
292  tree.selectCurrentNode();
293 
294  // update content area
295  var url = tree.editUrl;
296  if (scopeParams) {
297  url = url + scopeParams;
298  }
299  <?php if ($block->isClearEdit()): ?>
300  if (selectedNode) {
301  url = url + 'id/' + config.parameters.category_id;
302  }
303  <?php endif;?>
304  //updateContent(url); //commented since ajax requests replaced with http ones to load a category
305  }
306 
307  jQuery(function () {
308  categoryLoader = new Ext.tree.TreeLoader({
309  dataUrl: '<?= /* @escapeNotVerified */ $block->getLoadTreeUrl() ?>'
310  });
311 
312  categoryLoader.processResponse = function (response, parent, callback) {
313  var config = JSON.parse(response.responseText);
314 
315  this.buildCategoryTree(parent, config);
316 
317  if (typeof callback == "function") {
318  callback(this, parent);
319  }
320  };
321 
322  categoryLoader.buildCategoryTree = function (parent, config) {
323  if (!config) return null;
324 
325  if (parent && config && config.length) {
326  for (var i = 0; i < config.length; i++) {
327  var node;
328  var _node = Object.clone(config[i]);
329  if (_node.children && !_node.children.length) {
330  delete(_node.children);
331  node = new Ext.tree.AsyncTreeNode(_node);
332  } else {
333  node = new Ext.tree.TreeNode(config[i]);
334  }
335  parent.appendChild(node);
336  node.loader = node.getOwnerTree().loader;
337  if (_node.children) {
338  this.buildCategoryTree(node, _node.children);
339  }
340  }
341  }
342  };
343 
344  categoryLoader.buildHash = function (node) {
345  var hash = {};
346 
347  hash = this.toArray(node.attributes);
348 
349  if (node.childNodes.length > 0 || (node.loaded == false && node.loading == false)) {
350  hash['children'] = new Array;
351 
352  for (var i = 0, len = node.childNodes.length; i < len; i++) {
353  if (!hash['children']) {
354  hash['children'] = new Array;
355  }
356  hash['children'].push(this.buildHash(node.childNodes[i]));
357  }
358  }
359 
360  return hash;
361  };
362 
363  categoryLoader.toArray = function (attributes) {
364  var data = {form_key: FORM_KEY};
365  for (var key in attributes) {
366  var value = attributes[key];
367  data[key] = value;
368  }
369 
370  return data;
371  };
372 
373  categoryLoader.on("beforeload", function (treeLoader, node) {
374  treeLoader.baseParams.id = node.attributes.id;
375  treeLoader.baseParams.store = node.attributes.store;
376  treeLoader.baseParams.form_key = FORM_KEY;
377  });
378 
379  categoryLoader.on("load", function (treeLoader, node, config) {
380  //varienWindowOnload();
381  });
382 
383  scopeSwitcherHandler = reRenderTree;
384 
385  newTreeParams = {
386  animate: false,
387  loader: categoryLoader,
388  enableDD: true,
389  containerScroll: true,
390  selModel: new Ext.tree.CheckNodeMultiSelectionModel(),
391  rootVisible: '<?= /* @escapeNotVerified */ $block->getRoot()->getIsVisible() ?>',
392  useAjax: <?= /* @escapeNotVerified */ $block->getUseAjax() ?>,
393  switchTreeUrl: '<?= /* @escapeNotVerified */ $block->getSwitchTreeUrl() ?>',
394  editUrl: '<?= /* @escapeNotVerified */ $block->getEditUrl() ?>',
395  currentNodeId: <?= /* @escapeNotVerified */ (int)$block->getCategoryId() ?>,
396  baseUrl: '<?= /* @escapeNotVerified */ $block->getEditUrl() ?>'
397  };
398 
399  defaultLoadTreeParams = {
400  parameters: {
401  text: <?= /* @escapeNotVerified */ json_encode(htmlentities($block->getRoot()->getName())) ?>,
402  draggable: false,
403  allowDrop: <?php if ($block->getRoot()->getIsVisible()): ?>true<?php else : ?>false<?php endif; ?>,
404  id: <?= (int)$block->getRoot()->getId() ?>,
405  expanded: <?= (int)$block->getIsWasExpanded() ?>,
406  store_id: <?= (int)$block->getStore()->getId() ?>,
407  category_id: <?= (int)$block->getCategoryId() ?>,
408  parent: <?= (int)$block->getRequest()->getParam('parent') ?>
409  },
410  data: <?= /* @escapeNotVerified */ $block->getTreeJson() ?>
411  };
412 
413  reRenderTree();
414  });
415 
416  function addNew(url, isRoot) {
417  if (isRoot) {
418  tree.currentNodeId = tree.root.id;
419  }
420 
421  if (/store\/\d+/.test(url)) {
422  url = url.replace(/store\/\d+/, "store/" + tree.storeId);
423  }
424  else {
425  url += "store/" + tree.storeId + "/";
426  }
427 
428  url += 'parent/' + tree.currentNodeId;
429  location.href = url;
430  }
431 
432  function categoryMove(obj) {
433  var data = {id: obj.dropNode.id, form_key: FORM_KEY};
434 
435  data.point = obj.point;
436  switch (obj.point) {
437  case 'above' :
438  data.pid = obj.target.parentNode.id;
439  data.paid = obj.dropNode.parentNode.id;
440  if (obj.target.previousSibling) {
441  data.aid = obj.target.previousSibling.id;
442  } else {
443  data.aid = 0;
444  }
445  break;
446  case 'below' :
447  data.pid = obj.target.parentNode.id;
448  data.aid = obj.target.id;
449  break;
450  case 'append' :
451  data.pid = obj.target.id;
452  data.paid = obj.dropNode.parentNode.id;
453  if (obj.target.lastChild) {
454  data.aid = obj.target.lastChild.id;
455  } else {
456  data.aid = 0;
457  }
458  break;
459  default :
460  obj.cancel = true;
461  return obj;
462  }
463 
464  var pd = [];
465  for (var key in data) {
466  pd.push(encodeURIComponent(key), "=", encodeURIComponent(data[key]), "&");
467  }
468  pd.splice(pd.length - 1, 1);
469 
470  registry.set('pd', pd.join(""));
471 
472  jQuery('[data-id="information-dialog-category"]').modal({
473  modalClass: 'confirm',
474  title: jQuery.mage.__('Warning message'),
475  buttons: [{
476  text: 'Cancel',
477  class: 'action-secondary',
478  click: function () {
479  reRenderTree();
480  this.closeModal();
481  }
482  }, {
483  text: 'Ok',
484  class: 'action-primary',
485  click: function () {
486  (function ($) {
487  $.ajax({
488  url: '<?= /* @escapeNotVerified */ $block->getMoveUrl() ?>',
489  method: 'POST',
490  data: registry.get('pd'),
491  showLoader: true
492  }).done(function (data) {
493  if (data.error) {
494  reRenderTree();
495  } else {
496  $(treeRoot).trigger('categoryMove.tree');
497  }
498  $('.page-main-actions').next('.messages').remove();
499  $('.page-main-actions').next('#messages').remove();
500  $('.page-main-actions').after(data.messages);
501  }).fail(function (jqXHR, textStatus) {
502  if (window.console) {
503  console.log(textStatus);
504  }
505  location.reload();
506  });
507  })(jQuery);
508  this.closeModal();
509  }
510  }]
511 
512  }).trigger('openModal');
513 
514  }
515 
516  window.addNew = addNew;
517 
518  });
519  </script>
520 <?php endif; ?>
$block setTitle( 'CMS Block Title') -> setIdentifier('fixture_block') ->setContent('< h1 >Fixture Block Title</h1 >< a href=" store url</a><p> Config value
Definition: block.php:9
__()
Definition: __.php:13
$block
Definition: block.php:8
if( $block->getRoot())() ?>< br/><? endif
Definition: tree.phtml:12
if($block->getRoot())< div class="message message-notice">< div ><?=__( 'This operation can take a long time') ?></div ></div ></div >< script > var tree
Definition: tree.phtml:27
jQuery('.store-switcher .dropdown-menu li a').each(function()
Definition: switcher.phtml:203
jquery extjs ext tree mage adminhtml mage function(jQuery, modal)
Definition: tree.phtml:48