ToolbarDroppable.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * Plugin which allows items to be dropped onto a toolbar and be turned into new Toolbar items.
  3. * To use the plugin, you just need to provide a createItem implementation that takes the drop
  4. * data as an argument and returns an object that can be placed onto the toolbar. Example:
  5. * <pre>
  6. * Ext.create('Ext.ux.ToolbarDroppable', {
  7. * createItem: function(data) {
  8. * return Ext.create('Ext.Button', {text: data.text});
  9. * }
  10. * });
  11. * </pre>
  12. * The afterLayout function can also be overridden, and is called after a new item has been
  13. * created and inserted into the Toolbar. Use this for any logic that needs to be run after
  14. * the item has been created.
  15. */
  16. Ext.define('Ext.ux.ToolbarDroppable', {
  17. /**
  18. * Creates new ToolbarDroppable.
  19. * @param {Object} config Config options.
  20. */
  21. constructor: function(config) {
  22. Ext.apply(this, config);
  23. },
  24. /**
  25. * Initializes the plugin and saves a reference to the toolbar
  26. * @param {Ext.toolbar.Toolbar} toolbar The toolbar instance
  27. */
  28. init: function(toolbar) {
  29. /**
  30. * @property toolbar
  31. * @type Ext.toolbar.Toolbar
  32. * The toolbar instance that this plugin is tied to
  33. */
  34. this.toolbar = toolbar;
  35. this.toolbar.on({
  36. scope : this,
  37. render: this.createDropTarget
  38. });
  39. },
  40. /**
  41. * Creates a drop target on the toolbar
  42. */
  43. createDropTarget: function() {
  44. /**
  45. * @property dropTarget
  46. * @type Ext.dd.DropTarget
  47. * The drop target attached to the toolbar instance
  48. */
  49. this.dropTarget = Ext.create('Ext.dd.DropTarget', this.toolbar.getEl(), {
  50. notifyOver: this.notifyOver.bind(this),
  51. notifyDrop: this.notifyDrop.bind(this)
  52. });
  53. },
  54. /**
  55. * Adds the given DD Group to the drop target
  56. * @param {String} ddGroup The DD Group
  57. */
  58. addDDGroup: function(ddGroup) {
  59. this.dropTarget.addToGroup(ddGroup);
  60. },
  61. /**
  62. * Calculates the location on the toolbar to create the new sorter button based on the XY of the
  63. * drag event
  64. * @param {Ext.event.Event} e The event object
  65. * @return {Number} The index at which to insert the new button
  66. */
  67. calculateEntryIndex: function(e) {
  68. var entryIndex = 0,
  69. toolbar = this.toolbar,
  70. items = toolbar.items.items,
  71. count = items.length,
  72. xHover = e.getXY()[0],
  73. index = 0,
  74. el, xTotal, width, midpoint;
  75. for (; index < count; index++) {
  76. el = items[index].getEl();
  77. xTotal = el.getXY()[0];
  78. width = el.getWidth();
  79. midpoint = xTotal + width / 2;
  80. if (xHover < midpoint) {
  81. entryIndex = index;
  82. break;
  83. } else {
  84. entryIndex = index + 1;
  85. }
  86. }
  87. return entryIndex;
  88. },
  89. /**
  90. * Returns true if the drop is allowed on the drop target. This function can be overridden
  91. * and defaults to simply return true
  92. * @param {Object} data Arbitrary data from the drag source
  93. * @return {Boolean} True if the drop is allowed
  94. */
  95. canDrop: function(data) {
  96. return true;
  97. },
  98. /**
  99. * Custom notifyOver method which will be used in the plugin's internal DropTarget
  100. * @return {String} The CSS class to add
  101. */
  102. notifyOver: function(dragSource, event, data) {
  103. return this.canDrop.apply(this, arguments) ? this.dropTarget.dropAllowed : this.dropTarget.dropNotAllowed;
  104. },
  105. /**
  106. * Called when the drop has been made. Creates the new toolbar item, places it at the correct location
  107. * and calls the afterLayout callback.
  108. */
  109. notifyDrop: function(dragSource, event, data) {
  110. var canAdd = this.canDrop(dragSource, event, data),
  111. tbar = this.toolbar;
  112. if (canAdd) {
  113. var entryIndex = this.calculateEntryIndex(event);
  114. tbar.insert(entryIndex, this.createItem(data));
  115. this.afterLayout();
  116. }
  117. return canAdd;
  118. },
  119. /**
  120. * Creates the new toolbar item based on drop data. This method must be implemented by the plugin instance
  121. * @param {Object} data Arbitrary data from the drop
  122. * @return {Mixed} An item that can be added to a toolbar
  123. */
  124. createItem: function(data) {
  125. //<debug>
  126. Ext.raise("The createItem method must be implemented in the ToolbarDroppable plugin");
  127. //</debug>
  128. },
  129. /**
  130. * @method
  131. * Called after a new button has been created and added to the toolbar. Add any required cleanup logic here
  132. */
  133. afterLayout: Ext.emptyFn
  134. });